KevinGong

  BlogJava :: 首页 :: 联系 :: 聚合  :: 管理
  15 Posts :: 1 Stories :: 9 Comments :: 0 Trackbacks

2006年8月6日 #

/*
 * 简单的读/写文本文件的示例
 * 这里包含了三个例子,即
 * 1. 将文件读入到内存(这里是StringBuffer)的例子
 * 2. 将内容中的文本写到文件
 * 3. 将一个文件的内容读出来写入另一个文件中
 *    同时也展示了如果从输入流中读出来内容写入输出流中(仅限文本流)
 * 三个例子可以独立存在,所以根据需要只看其中一个就行了。
 */

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintStream;
import java.io.PrintWriter;

public final class AccessTextFile {

    /**
     * 1. 演示将流中的文本读入一个 StringBuffer 中
     * @throws IOException
     */
    public void readToBuffer(StringBuffer buffer, InputStream is)
        throws IOException {
        String line;        // 用来保存每行读取的内容
        BufferedReader reader = new BufferedReader(new InputStreamReader(is));
        line = reader.readLine();       // 读取第一行
        while (line != null) {          // 如果 line 为空说明读完了
            buffer.append(line);        // 将读到的内容添加到 buffer 中
            buffer.append("\n");        // 添加换行符
            line = reader.readLine();   // 读取下一行
        }
    }

    /**
     * 2. 演示将 StringBuffer 中的内容读出到流中
     */
    public void writeFromBuffer(StringBuffer buffer, OutputStream os) {
        // 用 PrintStream 可以方便的把内容输出到输出流中
        // 其对象的用法和 System.out 一样
        // (System.out 本身就是 PrintStream 对象)
        PrintStream ps = new PrintStream(os);  
        ps.print(buffer.toString());
    }

    /**
     * 3*. 从输入流中拷贝内容到输入流中
     * @throws IOException
     */
    public void copyStream(InputStream is, OutputStream os) throws IOException {
        // 这个读过过程可以参阅 readToBuffer 中的注释
        String line;
        BufferedReader reader = new BufferedReader(new InputStreamReader(is));
        PrintWriter writer = new PrintWriter(new OutputStreamWriter(os));
        line = reader.readLine();
        while (line != null) {
            writer.println(line);
            line = reader.readLine();
        }
        writer.flush();     // 最后确定要把输出流中的东西都写出去了
                            // 这里不关闭 writer 是因为 os 是从外面传进来的
                            // 既然不是从这里打开的,也就不从这里关闭
                            // 如果关闭的 writer,封装在里面的 os 也就被关了
    }

    /**
     * 3. 调用 copyStream(InputStream, OutputStream) 方法拷贝文本文件
     */
    public void copyTextFile(String inFilename, String outFilename)
        throws IOException {
        // 先根据输入/输出文件生成相应的输入/输出流
        InputStream is = new FileInputStream(inFilename);
        OutputStream os = new FileOutputStream(outFilename);
        copyStream(is, os);     // 用 copyStream 拷贝内容
        is.close(); // is 是在这里打开的,所以需要关闭
        os.close(); // os 是在这里打开的,所以需要关闭
    }

    public static void main(String[] args) throws IOException {
        int sw = 1;     // 三种测试的选择开关
        AccessTextFile test = new AccessTextFile();
       
        switch (sw) {
        case 1: // 测试读
        {
            InputStream is = new FileInputStream("E:\\test.txt");
            StringBuffer buffer = new StringBuffer();
            test.readToBuffer(buffer, is);
            System.out.println(buffer);     // 将读到 buffer 中的内容写出来
            is.close();
            break;
        }
        case 2: // 测试写
        {
            StringBuffer buffer = new StringBuffer("Only a test\n");
            test.writeFromBuffer(buffer, System.out);
            break;
        }
        case 3: // 测试拷贝
        {
            test.copyTextFile("E:\\test.txt", "E:\\r.txt");
        }
            break;
        }
    }

}

posted @ 2007-02-03 21:58 KevinGong 阅读(31672) | 评论 (0)编辑 收藏

这一章我主要介绍X系统用的主要配置文件XF86Config-4,我采用了对照的方法介绍,一边贴出我的XF86Config-4文件,一边介绍具体的内容。这篇文章对于大家没有什么立杆见影的帮助,不果可以让你对于X的只是有一个基本的了解。

XF86Config-4文件是X系统的主要配置文件。在Redhat 8以前版本中都叫做XF86Config-4这个名字,Redhat 8已经不再叫做这个名字。

编辑这个文件需要小心谨慎一点,因为一点错误,你的X将不能启动。不果没关系啦,改回来就是了学习Linux最好的办法当然还是求助于男人(man),大家有什么问题尽管看看man的帮助就是了。如果你要删除文件中的内容,最好不要直接的删除,而应该在前面加上#符号把它变成注释。

在Redhat 8以前的版本中,X的配置工具是Xconfigurator,在Debian中X的配种方法是:
dpkg-reconfigure xserver-xfree86
当然你都得用root的身份来运行。

在/usr/share/doc/xfree86-common/FAQ.gz文件中你可以看到具体的技巧。


第一段是Files段,这个部分用来配置X系统说能够使用的字体,每一行都代表一个目录,保存了具体的字体和字体的配置信息。
代码:

Section "Files"
        FontPath        "/usr/X11R6/lib/X11/fonts/xp"
   FontPath        "/usr/X11R6/lib/X11/fonts/XChinese"
   FontPath   "unix/:7100"         # 这是本地字体服务器
   # 如果本地字体服务器出了问题,我们可以使用下面的配置
   FontPath   "/usr/lib/X11/fonts/misc"
   FontPath   "/usr/lib/X11/fonts/cyrillic"
   FontPath   "/usr/lib/X11/fonts/100dpi/:unscaled"
   FontPath   "/usr/lib/X11/fonts/75dpi/:unscaled"
   FontPath   "/usr/lib/X11/fonts/Type1"
   FontPath   "/usr/lib/X11/fonts/Speedo"
   FontPath   "/usr/lib/X11/fonts/100dpi"   #这两个字体是每一个X
   FontPath   "/usr/lib/X11/fonts/75dpi"   #系统都必需安装的英文字体
EndSection

下面的是模块段,用来配置X系统加载的模块。
代码:

Section "Module"
   Load   "xtt"      #gtk1使用的字体引擎,效果好,速度稍慢
   Load   "GLcore"   #如果你是用的是Nvidia的显卡,似乎一定要注消掉这一行
   Load   "bitmap"
   Load   "dbe"
   Load   "ddc"
   Load   "dri"
   Load   "extmod"
#   Load   "freetype"   #如果你使用了xtt模块,那么freetype模块就需要注消掉
   Load   "glx"
   Load   "int10"
   Load   "record"
   Load   "speedo"
   Load   "type1"
   Load   "vbe"
EndSection


下面的段是用来配置你的键盘的,属于“输入设备”
代码:

Section "InputDevice"
   Identifier   "Generic Keyboard"   #这是你的键盘的名字,随便你啦
   Driver      "keyboard"      #键盘的驱动…哇,键盘也有驱动
   Option      "CoreKeyboard"      #如果你有多个键盘,那么你需要在这里指定哪一个键盘是主要的键盘
   Option      "XkbRules"   "xfree86"
   Option      "XkbModel"   "pc104"   #键盘的分布格式,一般来说
   Option      "XkbLayout"   "us"   #美国104键盘是大家通用的。
EndSection


这里配置你的鼠标,当然你可以配置两个鼠标,如果你有的话
代码:

Section "InputDevice"
   Identifier   "Configured Mouse"   #鼠标的名字
   Driver      "mouse"         #鼠标的驱动
   Option      "CorePointer"      
   Option      "Device"      "/dev/input/mice"
   #注意,这里很重要,这是鼠标的设备文件
   #我的鼠标是光电鼠标,用的USB接口,对应的鼠标文件是/dev/input/mice
   #如果你的鼠标是普通的滚轮鼠标,用的是PS2接口,那么你应该使用
   #/dev/mouse或者/dev/psaux或者/dev/ttys0这个设备
   Option      "rotocol"      "ImPS/2"
   #这是鼠标的类型,如果不是是滚轮鼠标,那么使用PS/2
   Option      "Emulate3Buttons"   "true"
   #在Linux系统中,鼠标的第三个键非常有用,
   #如果你的鼠标没有第三个键,那么我们应该允许使用双键同时点击来模拟
   Option      "ZAxisMapping"      "4 5"
EndSection


下面的设备是显卡,这是最头痛的设备了,如果你的显卡太新潮,很有可能不能支持哦。Nvidia的GForce2显卡就必需自己编译显卡的驱动程序才能使用
代码:

Section "Device"
   Identifier   "Generic Video Card"
   Driver      "ati"      #如果你是Nivida的显卡,这里应该是"nvidia"
EndSection



这个设备是显示器。
代码:

Section "Monitor"
   Identifier   "Generic Monitor"   #显示器的名字
   HorizSync   30-60         #显示器的频率,一半来说你的显示器
   VertRefresh   50-75         #应该可以达到我的这个水平
                  #因为我的显示器是15"的老显示器了
                  #大家的电脑都比我的好吧?
   Option      "DPMS"
EndSection


下面是综合以上你的配置的设备的各种显示效果
代码:

Section "Screen"
   Identifier   "Default Screen"   #效果的名字
   Device      "Generic Video Card"   #你可以指定你的显卡的名字
   Monitor      "Generic Monitor"   #指定你的显示器的名字
   DefaultDepth   24         #默认的颜色深度
   SubSection "Display"
      Depth      1
      Modes      "1024x768"
   EndSubSection
   SubSection "Display"
      Depth      4
      Modes      "1024x768"
   EndSubSection
   SubSection "Display"
      Depth      8
      Modes      "1024x768"
   EndSubSection
   SubSection "Display"
      Depth      16
      Modes      "1024x768"   #在这里你可以指定扫描频率例如
                  #"1024x768 @ 85"就是用85mhz的频率
   EndSubSection
   SubSection "Display"
      Depth      24
      Modes      "1024x768"
   EndSubSection
EndSection



最终你必需定义下面的段用来告诉X服务器你使用的配置
代码:

Section "ServerLayout"
   Identifier   "Default Layout"   #刚才我们给我们的配置取的名字
   Screen      "Default Screen"   #给我们的效果取的名字
   InputDevice   "Generic Keyboard"   #我们的键盘的名字
   InputDevice   "Configured Mouse"   #我们的鼠标的名字
               #这些名字一定要在前面的配置中已经定义
EndSection

Section "DRI"
   Mode   0666
EndSection



一般来说我们X启动时候会遇到的问题是:
1:no screen found
这有可能是你没有正确的定义所需要的效果,也有可能是你的其他部分定义出错倒置你的效果不能实现
2:xtt和freetype的冲突,注消一个就可以了
3:驱动没有找到,如果你的显卡非常的新潮,那么多半是这个错误了,编译你的驱动吧…

posted @ 2006-10-29 14:26 KevinGong 阅读(256) | 评论 (0)编辑 收藏

现在请输入你的用户名和密码,当然,我们输入root,这样获得一切管理权限!

你一定非常希望立刻看到那些非常漂亮的图形界面,但是也许我要让你失望了。我建议在没有使用图形界面以前,首先熟练的掌握基本的Linux命令,这样才是一个真正的Linuxer。从哪里开始呢?

1. ls 列出文件和目录的命令

你一定很想知道你的电脑里面有哪些东西,现在执行命令ls,啊,怎么什么都没有?当然啦,这是你第一次登录到这个系统,你的默认位置是你的个人目录,而不是系统根目录。你还没有在这个目录里面存放任何的个人文件,当然什么都没有啦。如果你是用root用户登录的话,你的个人目录就是/root目录;如果你是用普通用户登录,比如叫做kris,那么kris的个人目录是/kris。前面的/是什么意思呢?就是“根”的意思,就是最前面的那个目录,在根目录下面建立有很多的子目录,我们在第一章已经讨论过了。

ls命令有很多的选项,常用的是:

-A 选项用来列出所有的文件,包括那些隐藏的文件。为什么我们要隐藏文件呢?道理和你为什么要把情书藏起来不让爸妈发现是一样的。就是为了保密啊。现在执行ls -A看看?是不是有一个隐藏文件“.bashrc”被显示出来啦?聪明的你一定奇怪的发现这个文件名前面有一个点,对!记住,只要文件名前面第一个字符是一个“.”,这个文件就是隐藏文件。一个目录名前面的第一个字符如果是“.”这个目录就是隐藏目录。
-l 这个选项用来显示一个列表,包含了这个目录下面所有的文件的绝大部分属性的列表。你可以每个文件的大小,所有者,你的权限还有修改日期等等。
-R R的意思就是recursive递归,明显这个选项让系统显示出这个目录下面的所有文件以外,还要显示出所有子目录下面的文件。也就是把我们那一大堆水果全部抖出来。
--color 这个选项特别有用,我估计大家的显示器都是彩显吧,什么?你的显示器还是黑白的?天哪!既然是彩显,那么我们可以让ls命令用不同的眼色代表不同的文件类型。比如可执行文件用绿色,普通文件是白色,目录是蓝色。也许你会问,目录也是文件吗?对的,在Linux里面一切都是文件,所有的硬件设备都用一个文件来代替,比如你的软驱,就是用/dev/fd0来代替的。目录也是一个文件。
--help 这个选项几乎是每一个Linux命令都有的,用来显示出该命令的帮助信息。

2. cd 和 mkdir 以及 rm 改变当然所在目录,建立新目录以及删除目录命令

趁热打铁的,刚才说了目录,我们每一次登录都有一个默认目录就是我们的个人用户目录。我们怎么才能到其他的目录去呢?cd就是用来改变当前所在的目录的。前面我们说过,“/”代表根目录,那么执行cd /就可以进入根目录。不试一下吗?
让我们看看根目录下面有哪些文件和子目录吧,执行ls,我们发现,根目录下面有一个目录名子特别变态,叫做usr,进去看看,cd usr,看看这里面有什么?你会发现一个更psycho(变态)的目录叫做src,进入src目录看看?没什么好玩的。那么我们现在回到刚才的usr目录,怎么做?是不是cd usr?执行试一下,好像不行,系统报告出错 cd: usr: No such file or directory。这是怎么搞的?问题在于我们现在所在的目录是/usr/src下,我们执行cd usr的意思是进入/usr/src/usr目录而不是/usr目录。正确的方法是cd /usr。
就好比你在中华美食的箩筐里面看到一个四川的箩筐,里面有一个成都的小箩筐,现在你进入以后发现成都的小箩筐里面有一种叫做“麻辣烫”的很辣的食品。你大饱口福以后想要吃一些甜点,于是准备去福州。你能站在成都的箩筐里面去福州吗?当然不行,福州并不在成都的箩筐里面啊,你应该进入“/中华美食/福州”而不是“/中华美食/四川/成都/福州”对不对?
好的,一个问题出现了,难道我每一次进入一个目录,都要用/usr/src...这么复杂的方式来表示吗?不一定。我们用“..”的方式来表示上一层目录。如果你现在在/usr/src目录下,进入/usr目录有两种办法:cd /usr和cd ..他们是一样的。

怎样才能知道我现在在哪个目录?用命令pwd,这个命令没有什么好说的,执行一次就知道了。

现在我想在我自己的个人目录里面建立一个目录叫做LoveLetter。我应该首先回到我自己的目录,这里有一个简单的方法,就是直接运行cd不带任何参数,这样就可以回到自己的目录,当然也可以cd /root或者cd /home/kris,看你是用什么用户登录的。
进入我自己的目录以后,建立新目录的命令是
mkdir 新目录名
我执行 mkdir LoveLetter 就可以建立一个新的叫做LoveLetter的目录。进入这个目录看看?什么都没有。不着急,慢慢来。我都不着急你急什么?
突然我想起这台电脑我的爸妈也要使用,他们看到我的情书目录怎么办?你忘了刚才我说的可以用加一个点“.”在前面的方法来隐藏目录和文件的?我们可以改变这个目录的名字,但是这个命令我准备等会儿讲,现在我们用一个很无聊的办法来完成这个要求。这个办法就是删掉刚才建立的oveLetter目录在新建一个.LoveLetter目录,之所以说这个办法很无聊,是因为我们现在是在做实验,如果来真的,你原意删掉你的情书吗?是不是另有新欢啦?哈哈。

删除目录的命令其实也可以删除文件,就是rm。
rm 待删除的文件名/目录名
我记得Redhat会提示你是不是真的要删除。按y就是确定,按n就是取消。如果Redhat没有提示你,那么等会请根据我说的方法修改一下系统让它提示咱们。免得以后心痛。删除一个文件很简单。麻烦的是删除一个目录,如果一个目录里面已经有文件,rm是不让直接删除的,你必需先把目录里面的所有文件删除,再删除目录。但是有一个参数可以改变一下,就是 -rf ,这个参数有一定的危险性,因为即使系统本来要提醒一下是不是真的删除目录,加上这个参数也不会有提示了。执行rm 目录 -rf会在一眨眼的时间里面让你的资料下课!
那么我现在就删除LoveLetter目录了:rm LoveLetter -rf
建立一个新的目录mkdir .LoveLetter
现在ls看看,是不是看不到LoveLetter目录了?但是ls -A还是能看到的。所以这种隐藏方式只能偏偏自己,真正让你的文件安全的方式还是以后再讲吧。

3. mv 改变文件名和目录名的命令
cp 复制文件和目录命令
man 命令使用方法参考工具

mv 老文件名 新文件名
mv 老目录名 新目录名
就可以改变文件或者目录的名字。
我现在想要把刚才的这个目录.LoveLetter改名回去,因为这种无聊的隐藏方式很变态,我们有更高级的方法来做这样一件事情:就是不要告诉爸妈你的密码!!!
mv .LoveLetter LoveLetter

cp命令用来把一个文件复制成为一个新的文件,

cp 老文件名 新文件名

这个老文件明和新文件名如果在同一个目录下面,那么当然需要名字不一样,很简单的道理,如果文件名一样何必建立两个文件?如果新老文件在不同的目录,我们就可以让它们有相同的名子。下面的例子说明了这一点:

cp LoveLetter LoveLetter_yesterday 新的文件LoveLetter_yesterday和旧的LoveLetter在同一个目录,所以名子不一样。
cp LoveLetter /home/LoveLetter 新的文件在/home目录下面,但是旧的文件LoveLetter在某一个用户的个人目录下面,当然两者名子可以相同。

cp命令也可以复制整个目录,但是现在我们暂时不讲这么复杂。其实cp还有rm以及ls这些命令不仅是整个Linux的基本命令,更包含了非常多的功能。如果大家有兴趣,可以使用man

man 命令名字

比如man ls,这样就可以看到所有ls命令和参数的详悉解释,尤其是一部分常用的命令的man帮助已经由志愿者翻译了,大家看起来更容易。

一点幽默

好了,说了好多东西了,我想休息一下,给大家说一个有趣的事情,我们说了好多命令和目录的名子,你们是不是觉得有点奇怪。说实在话,我第一次看到usr这个目录时也不知道是什么意思,后来才发现以下对应关系:
usr ->; user
ls ->; list
mkdir ->; make dir
rm ->; remove
src ->; source
mv ->; move
cp ->; copy

是不是很有趣,在UNIX世界,包括Linux世界,人们的想象力就是这么无敌!简写居然能简写成这样子。大家一般的想法是取一个单词的前三个或者前四个字母作为简写,可是UNIX的牛人就是喜欢把move简写成为mv,真不知道他们怎么想的。大家一起捉摸吧

4. nano 和 vi编辑文件的命令 和 cat 以及 more显示文本文件

nano是一个小巧自由,并且友好的编辑器,我认为nano更适合初学Linux的朋友使用。我们现在只学习怎样编辑一个文件以及怎样保存。

nano 文件名

如果你写的文件名已经存在,那么就打开并且编辑,否则就建立一个新的文件。编辑的方法还用说吗?呵呵,当你想要退出的时候,按ctrl+x,nano会问你是不是保存编辑的文件。按Y就是保存,按N就不保存。

nano最大好处在于用户可以不用记忆太多的操作键,大部分常用的功能的操作方法都在屏幕下放列出了。新手需要注意的是“^X”就是按住ctrl键不放再按X的意思。

下面简单的介绍vi。vi是一个非常强大的编辑软件。它太庞大了,足够写一本书专门来讲解。我们这里从使用的角度出发,讲一下vi的用法。
vi有两种模式,一种是命令模式,一种是编辑模式。进入vi以后,默认处于命令模式。

现在我们执行vi LoveLetter。进入以后,按一下键盘上的Insert功能键或者i键可以进入编辑状态,可以插入字符,再按一下Insert变成复盖模式,这两种模式的区别很容易体现,大家尝试一下就可以了。上下左右四个方向键可以移动光标。基本的编辑命令和Windows里面没有区别。是不是很容易呢?当你把需要的内容输入完成以后,我们要保存,这时候按一下ESC键从编辑模式回到命令模式,首先输入一个冒号“:”,也就是按住SHIFT键不放再按分号“;”这样首先输入一个“:”,然后,输入w,回车,就可以保存我们编辑的内容到LoveLetter文件。现在我们按一下Insert就可以继续编辑。再按ESC,输入“:”,再按w又可以保存。可是现在我们不需要保存,我们想要不保存就退出,怎么做呢?当我们输入w的时候是write的意思,保存,那么我们输入q就是quit退出的意思。好,输入q,回车,vi提示我们刚才进行的修改还没有保存,所以记住!一旦需要放弃我们的修改,不能直接用q命令退出,而需要用“q!”命令。输入q!,好了,退出了。
我们想看看我们刚才编辑的LoveLetter是不是真的保存好了,再vi LoveLetter,ok,看到了吧?现在我们想要直接退出,就可以只输入“:q”就可以了,不用输入那个“!”因为我们没有修改文件内容。如果我们修改一下这篇文章,我们在退出的时候可以输入“ESC : wq”就可以了。不需要把w和q分成两次输入。

vi的最最基本用法说到这里差不多了,要是你还想多了解一些vi的知识,在进入vi以后直接按F1就可以了,有详悉的帮助和教学。

其实刚才我们想要看一下编辑的LoveLetter是不是保存好了,不用再vi进去的,只需要用命令

cat LoveLetter

就可以了。cat就是用来显示文本文件内容的命令。如果我们的文本文件很长,一个屏幕显示不完,cat是不会自动分页的。我们可以换用命令

more LoveLetter

more命令显示文本文件时,如果内容过多,会自动的在每一页结束时暂停下来,等到用户按一下空格键再继续。

5. 最重要的命令:halt reboot 关机和重新启动命令

在Linux里面,不能够直接用电源按钮关机,也不能直接用reset按钮重新启动,这对系统,尤其是硬盘有比较大的影响。关机命令是halt,重启动命令是reboot。其实还有shutdown命令完成类似功能,需要的话,请用今天学会的man命令学习使用。
posted @ 2006-10-29 14:17 KevinGong 阅读(408) | 评论 (1)编辑 收藏

http://www.m-heaven.com/dreamweaver/
posted @ 2006-09-22 14:23 KevinGong 阅读(482) | 评论 (2)编辑 收藏

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
<title>无标题文档</title>
</head>

<body>
<p>
  <object id="player" style="display:none" height="400" width="400" classid="CLSID:6BF52A52-394A-11d3-B153-00C04F79FAA6">
    <param name="invokeURLs" value="-1">
    <param NAME="AutoStart" VALUE="-1">
    <param name="currentPosition" value="0">
    <param name='uiMode' value='mini'>
    <param NAME="url" VALUE="test.mpg">
  </object>
</p>
<input name="submit" type="submit" onclick="getInfo()">
<p>
 
<script language="javascript">
 var time;
  function getInfo(){
  var pl=document.getElementById("player");
   time=pl.currentMedia.durationString;
   alert(parseInt(pl.currentMedia.durationString.substring(0,2)*60));
   //alert(parseInt(pl.currentMedia.durationString.substring(3,5)));
  alert(parseInt(pl.currentMedia.durationString.substring(0,2)*60)+parseInt(pl.currentMedia.durationString.substring(3,5)));
 }
</script>
</p>
</body>
</html>

posted @ 2006-09-14 14:49 KevinGong 阅读(4642) | 评论 (1)编辑 收藏

    首先,我们必须明确,为什么要使用J2EE?J2EE优点是什么?使用J2EE的主要原因是多层结构,传统的两层C/S结构难于维护,稳定性极差,界面代码和数据库代码混淆在一起,牵一动百,多层结构使得界面和数据库完全分离,并且诞生了中间件这样的技术,如下图:

Web+EJB能组成真正的多层结构

  为什么使用EJB我原先认为这不是一个讨论的话题,因为EJB是J2EE重要的组成部分,可以说没有EJB的J2EE只是一种Web系统,这样的系统非常容易丧失了多层结构的大部分优点(仔细想想那些混合多种层次功能JavaBeans和传统两层结构有什么区别?)。

  当然,可以人为地在Javabeans之间进行层次划分,例如Hibernate算数据持久层,某些JavaBeans是业务核心层,但是因为都是普通JavaBeans,这种划分没有一种强制性和明显标志性,这样的系统更换了主创人员或设计师,可能就会被新的程序员修改得非常混乱。

  我们先看看一个包含EJB的J2EE系统是如何清晰地表达层次。如下图:

  Web完全只是一个MVC模式的实现,关键业务核心是在EJB的服务层实现,这样做的优点是,Web只负责界面相关部分,因为,如果是一个智能客户端,如Swing或J2ME,在不需要修改任何业务核心的情况下能够方便地更换。同样,提供Web Services功能,也只是在 Web层修改,不会涉及EJB方面的修改,同样保证了系统的稳定性,保证了系统升级和未来的扩展性。

  如果不使用EJB,在EJB服务层实现的业务核心将由普通JavaBeans实现,使用何种架构或设计能够保证负责MVC的JavaBeans和负责业务核心的JavaBeans清晰地分开,又如何保证在新的程序员不会破坏和打乱你精心布局的JavaBeans架构?

EJB提供性能优化支持

  最主要的是性能问题,由于以前国内中文Java网站有些人弯曲EJB,认为EJB性能低,其实这是一种非常肤浅错误的认识,我们首先看看在一般Java环境中是如何提高性能。

  假定一个JavaBeans为A,那么一般使用这个JavaBeans命令如下:

  A a = new A();

  但是,在高访问量的环境中,new A()其实是很费时消耗系统性能的,因此,能不能在软件系统启动时候就预先建立一些对象,这样,系统运行时,从这些已经生成的对象池中借用一个,这样,就无需在使用时进行New,节约了开销,提高了性能,因此,真正成熟性能解决方案都是需要对象池等支持。

  在一个纯Web结构的系统(也就是只能运行在Tomat环境中),例如Struts + Hibernate等这样的系统,除非自己动手做,一般是没有对象池技术支持的,因此他们的性能只能算是Demo演示版本的性能,根本无法承受大容量并发访问,也无法称为一个成熟的系统,所以,我们研究成熟的开源Web系统,如Jive、OFBize,LifeRay等,他们都在Web层拥有自己的对象池和缓存池。

  对象池和缓存机制是J2EE必须的吗?当然,是所有成熟系统必须的,Windows系统如果去掉缓存将会变得怎样?

  自己动手开发对象池和缓存机制并不是一件简单的事情,需要对多线程以及同步锁等底层原理有深层次的把握,这其实也是一门非常深入的Java研究分支,所以,你可以抛开你的客户焦急的催促,精心研究开发自己的对象池和缓存池。

  但是,EJB容器(如JBoss)已经提供了对象池和缓存机制,所以,没有事务机制的无状态Session Bean的性能肯定要强于普通JavaBeans。EJB容器不但在单机中提供了对象池和缓存,而且可以跨服务器实现动态负载平衡,这些都无需开发者自己开发任何软件代码,结构如下:

EJB组件能提供真正的可重用框架

  每一个jar包代表一个EJB组件,一个系统可以由多个可重用的EJB组件构成,例如:树形结构EJB组件;自增序号EJB组件;用户资料EJB组件等,这样的EJB组件可以象积木一样搭配在大部分应用系统中,提高了系统的开发效率,保证了开发质量。

  下图是某个新的具体系统时应用到的EJB组件图,在这个新的应用中,由于使用了以前大量可重用的EJB组件,新的开发工作基本集中在界面设计和流程安排上:

EJB提供了事务机制

  事务机制对于一些关键事务是很重要的,例如ATM机提款,提款有多个动作:修改数据库以及数钱等,如果这其中有任何一个环节出错,那么其它已经实现的操作必须还原,否则,就会出现,提款人没有拿到钱,但是卡上已经扣款等不可思议的事情发生。

  EJB提供的事务机制非常周全,但事务机制带来的缺点是性能的降低,因此,有些人认为EJB很重,因为在实际应用中,有的用户系统可能不需要事务机制,只是需要EJB提供的性能优化机制,这样,如果使用EJB,就象叫一个人来背东西,他除了背着我要的东西外,还背着我不要的东西。

  除非你是一个完美主义,在一般企业应用或数据库系统应用中,EJB不会对你构成很重的包袱。

CMP独特的优点

  开源以及一些数据库持久层技术崇拜者,一直抨击CMP,认为CMP慢无用,实际最大的问题是他们的设计和使用问题。

  由于EJB容器(如JBoss)对CMP实现有事务机制的缓存优化,因此,CMP特别适合多个用户同时更新同一个数据源的情况,CMP这种严格的事务完整性保证多个用户同时操作一个数据记录时,能够保证性能优化和数据的完整性,如果这个数据记录是是软件系统的状态标志,它的状态会影响系统中很多的环节,那么状态更改的重要性不言而喻。

  如果没有事务完整性支持,你的软件系统在用户访问量变大,就会变得发生各种不可能发生的逻辑错误,查看程序逻辑是正确的,那么问题出在哪里?出在数据完整性上。

  由于每个CMP在内存中都有一个缓存,在实际应用中,如果使用CMP批量读数据库数据,几万条查询完毕,内存中充满了几万条CMP缓存,如果这时你的EJB容器设置不当(如使用JBoss缺省配置),那么JVM的垃圾回收机制就会频繁启动,导致你的系统变慢甚至死机,这也是一些人抨击CMP慢的原因所在,其实他们使用方法不当,或者没有正确配置EJB容器CMP缓存。

  对于这种情况,根据J2EE核心模式,推荐使用DAO+JDBC方式。

小结

  除非你对设计模式非常精深,能够将自己系统中的JavaBeans使用模式或某种框架进行固定分层,同时,你孜孜不倦研发出对象池,又熟练于JTA等事务机制,你可以选择没有EJB的纯Web结构,就象Jive、OFBiz那样。当然还有一个前提,老板不懂或者非常有挑战性(做与IBM SUN 微软齐名的公司和技术)。

  不要再被TSS那些狂热的开源先生误导,他们有时间有保障可以做他们喜欢的事情,作为专业的J2EE程序员,按照J2EE标准去学习去行动,也不要认为,只要使用了J2EE其中某个技术如Jsp或JavaBeans就心安理得认为自己的系统是J2EE了。

  当然,我并不是说纯Web系统不能实现多层结构,但是至少在很多方面没有Web+EJB结构完善和清晰,所以,EJB不是J2EE可以忽视的部分,而是主要的重要的部分,重要业务功能核心都封装在EJB中,相反Web层是一种次要的、和界面相关的层次。

  补充:什么情况下不需要EJB,在SUN的SECA架构师试卷中回答:小型系统和不需要事务。另外过去那种认为“EJB有性能问题”根本是一种缪误,具体可参考下面有关问题。

posted @ 2006-09-11 14:56 KevinGong 阅读(276) | 评论 (0)编辑 收藏

java文件上传,介绍几种常用的方法,也是经过本人亲手调试过的
1.jspsmartupload
这个组件用起来是挺方便的,不过就是只适合小文件上传,如果大文件上传的话就不行,查看了一下他的代码,m_totalBytes = m_request.getContentLength(); m_binArray = new byte[m_totalBytes];居然把整个上传文件都读到内存去了,那如果是上传几十M的文件,同时几个用户上传,服务器稳挂,不过如果只是上传5M以内的小文件,这个组件还是挺实用的

下面是源代码:
File类
/*
 * 创建日期 2006-7-29
 *
 * 更改所生成文件模板为
 * 窗口 > 首选项 > Java > 代码生成 > 代码和注释
 */
package com.kinstar.issuing.file;

/**
 * @author gongyifeng
 *
 * 更改所生成类型注释的模板为
 * 窗口 > 首选项 > Java > 代码生成 > 代码和注释
 */
import java.io.ByteArrayInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.math.BigInteger;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.servlet.ServletException;

// Referenced classes of package com.jspsmart.upload:
// SmartUploadException, SmartUpload

public class File{
 private SmartUpload m_parent;
 private int m_startData;
 private int m_endData;
 private int m_size;
 private String m_fieldname;
 private String m_filename;
 private String m_fileExt;
 private String m_filePathName;
 private String m_contentType;
 private String m_contentDisp;
 private String m_typeMime;
 private String m_subTypeMime;
 private String m_contentString;
 private boolean m_isMissing;
 public static final int SAVEAS_AUTO = 0;
 public static final int SAVEAS_VIRTUAL = 1;
 public static final int SAVEAS_PHYSICAL = 2;

 File(){
  m_startData = 0;
  m_endData = 0;
  m_size = 0;
  m_fieldname = new String();
  m_filename = new String();
  m_fileExt = new String();
  m_filePathName = new String();
  m_contentType = new String();
  m_contentDisp = new String();
  m_typeMime = new String();
  m_subTypeMime = new String();
  m_contentString = new String();
  m_isMissing = true;
 }

 public void saveAs(String s) throws IOException, SmartUploadException{
  saveAs(s, 0);
 }

 public void saveAs(String s, int i) throws IOException, SmartUploadException{
  String s1 = new String();
  s1 = m_parent.getPhysicalPath(s, i);
  if(s1 == null)
   throw new IllegalArgumentException("There is no specified destination file (1140).");
  try
  {
   java.io.File file = new java.io.File(s1);
   FileOutputStream fileoutputstream = new FileOutputStream(file);
   fileoutputstream.write(m_parent.m_binArray, m_startData, m_size);
   fileoutputstream.close();
  }
  catch(IOException ioexception)
  {
   throw new SmartUploadException("File can't be saved (1120).");
  }
 }

 public void fileToField(ResultSet resultset, String s) throws ServletException, IOException, SmartUploadException, SQLException{
  long l = 0L;
  int i = 0x10000;
  int j = 0;
  int k = m_startData;
  if(resultset == null)
   throw new IllegalArgumentException("The RecordSet cannot be null (1145).");
  if(s == null)
   throw new IllegalArgumentException("The columnName cannot be null (1150).");
  if(s.length() == 0)
   throw new IllegalArgumentException("The columnName cannot be empty (1155).");
  l = BigInteger.valueOf(m_size).divide(BigInteger.valueOf(i)).longValue();
  j = BigInteger.valueOf(m_size).mod(BigInteger.valueOf(i)).intValue();
  try
  {
   for(int i1 = 1; (long)i1 < l; i1++)
   {
    resultset.updateBinaryStream(s, new ByteArrayInputStream(m_parent.m_binArray, k, i), i);
    k = k != 0 ? k : 1;
    k = i1 * i + m_startData;
   }
   
   if(j > 0)
    resultset.updateBinaryStream(s, new ByteArrayInputStream(m_parent.m_binArray, k, j), j);
  }catch(SQLException sqlexception){
   byte abyte0[] = new byte[m_size];
   System.arraycopy(m_parent.m_binArray, m_startData, abyte0, 0, m_size);
   resultset.updateBytes(s, abyte0);
  }catch(Exception exception)
  {
   throw new SmartUploadException("Unable to save file in the DataBase (1130).");
  }
 }

 public boolean isMissing(){
  return m_isMissing;
 }
 
 public String getFieldName(){
  return m_fieldname;
 }
 
 public String getFileName(){
  DateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");
  String date = df.format(new Date());
  
  return date+m_filename;
 }
 
 public String getFilePathName(){
  return m_filePathName;
 }
 
 public String getFileExt(){
  return m_fileExt;
 }
 
 public String getContentType(){
  return m_contentType;
 }
 
 public String getContentDisp(){
  return m_contentDisp;
 }
 
 public String getContentString(){
  String s = new String(m_parent.m_binArray, m_startData, m_size);
  return s;
 }
 
 public String getTypeMIME() throws IOException{
  return m_typeMime;
 }
 
 public String getSubTypeMIME(){
  return m_subTypeMime;
 }
 
 public int getSize(){
  return m_size;
 }
 
 protected int getStartData(){
  return m_startData;
 }
 
 protected int getEndData(){
  return m_endData;
 }
 
 protected void setParent(SmartUpload smartupload){
  m_parent = smartupload;
 }
 
 protected void setStartData(int i){
  m_startData = i;
 }
 
 protected void setEndData(int i){
  m_endData = i;
 }
 
 protected void setSize(int i){
  m_size = i;
 }
 
 protected void setIsMissing(boolean flag){
  m_isMissing = flag;
 }
 
 protected void setFieldName(String s){
  m_fieldname = s;
 }
 
 protected void setFileName(String s){
  m_filename = s;
 }
 
 protected void setFilePathName(String s){
  m_filePathName = s;
 }
 
 protected void setFileExt(String s){
  m_fileExt = s;
 }
 
 protected void setContentType(String s){
  m_contentType = s;
 }
 
 protected void setContentDisp(String s){
  m_contentDisp = s;
 }
 
 protected void setTypeMIME(String s){
  m_typeMime = s;
 }
 
 protected void setSubTypeMIME(String s){
  m_subTypeMime = s;
 }
 
 public byte getBinaryData(int i){
  if(m_startData + i > m_endData)
   throw new ArrayIndexOutOfBoundsException("Index Out of range (1115).");
  if(m_startData + i <= m_endData)
   return m_parent.m_binArray[m_startData + i];
  else
   return 0;
 } 
}

Files类
/*
 * 创建日期 2006-7-29
 *
 * 更改所生成文件模板为
 * 窗口 > 首选项 > Java > 代码生成 > 代码和注释
 */
package com.kinstar.issuing.file;

/**
 * @author gongyifeng
 *
 * 更改所生成类型注释的模板为
 * 窗口 > 首选项 > Java > 代码生成 > 代码和注释
 */
import java.io.IOException;
import java.util.*;

// Referenced classes of package com.jspsmart.upload:
// File, SmartUpload

public class Files{

 private SmartUpload m_parent;
 private Hashtable m_files;
 private int m_counter;
 
 Files(){
  m_files = new Hashtable();
  m_counter = 0;
 }
 
 protected void addFile(File file){
  if(file == null)
  {
   throw new IllegalArgumentException("newFile cannot be null.");
  } else {
   m_files.put(new Integer(m_counter), file);
   m_counter++;
   return;
  }
 }
 
 public File getFile(int i)
 {
 if(i < 0)
  throw new IllegalArgumentException("File's index cannot be a negative value (1210).");
 File file = (File)m_files.get(new Integer(i));
 if(file == null)
  throw new IllegalArgumentException("Files' name is invalid or does not exist (1205).");
 else
  return file;
 }
 
 public int getCount()
 {
  return m_counter;
 }
 
 public long getSize() throws IOException
 {
  long l = 0L;
  for(int i = 0; i < m_counter; i++)
  l += getFile(i).getSize();
  
  return l;
 }
 
 public Collection getCollection()
 {
  return m_files.values();
 }
 
 public Enumeration getEnumeration()
 {
  return m_files.elements();
 }
}

Request类
/*
 * 创建日期 2006-7-29
 *
 * 更改所生成文件模板为
 * 窗口 > 首选项 > Java > 代码生成 > 代码和注释
 */
package com.kinstar.issuing.file;

/**
 * @author gongyifeng
 *
 * 更改所生成类型注释的模板为
 * 窗口 > 首选项 > Java > 代码生成 > 代码和注释
 */
import java.util.Enumeration;
import java.util.Hashtable;

public class Request
{

 private Hashtable m_parameters;
 private int m_counter;
 
 Request(){
  m_parameters = new Hashtable();
  m_counter = 0;
 }
 
 protected void putParameter(String s, String s1) {
  if(s == null)
   throw new IllegalArgumentException("The name of an element cannot be null.");
  if(m_parameters.containsKey(s))
  {
   Hashtable hashtable = (Hashtable)m_parameters.get(s);
   hashtable.put(new Integer(hashtable.size()), s1);
  } else{
   Hashtable hashtable1 = new Hashtable();
   hashtable1.put(new Integer(0), s1);
   m_parameters.put(s, hashtable1);
   m_counter++;
  }
 }
 
 public String getParameter(String s){
 if(s == null)
  throw new IllegalArgumentException("Form's name is invalid or does not exist (1305).");
 Hashtable hashtable = (Hashtable)m_parameters.get(s);
 if(hashtable == null)
  return null;
 else
  return (String)hashtable.get(new Integer(0));
 }
 
 public Enumeration getParameterNames()
 {
  return m_parameters.keys();
 }
 
 public String[] getParameterValues(String s)
 {
  if(s == null)
   throw new IllegalArgumentException("Form's name is invalid or does not exist (1305).");
  Hashtable hashtable = (Hashtable)m_parameters.get(s);
  if(hashtable == null)
   return null;
  String as[] = new String[hashtable.size()];
  for(int i = 0; i < hashtable.size(); i++)
   as[i] = (String)hashtable.get(new Integer(i));
  
  return as;
 }
}

SmartUpload类
/*
 * 创建日期 2006-7-29
 *
 * 更改所生成文件模板为
 * 窗口 > 首选项 > Java > 代码生成 > 代码和注释
 */
package com.kinstar.issuing.file;

/**
 * @author gongyifeng
 *
 * 更改所生成类型注释的模板为
 * 窗口 > 首选项 > Java > 代码生成 > 代码和注释
 */
import java.io.*;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Vector;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.PageContext;

// Referenced classes of package com.jspsmart.upload:
// Files, Request, SmartUploadException, File

public class SmartUpload
{

 protected byte m_binArray[];
 protected HttpServletRequest m_request;
 protected HttpServletResponse m_response;
 protected ServletContext m_application;
 private int m_totalBytes;
 private int m_currentIndex;
 private int m_startData;
 private int m_endData;
 private String m_boundary;
 private long m_totalMaxFileSize;
 private long m_maxFileSize;
 private Vector m_deniedFilesList;
 private Vector m_allowedFilesList;
 private boolean m_denyPhysicalPath;
 private boolean m_forcePhysicalPath;
 private String m_contentDisposition;
 public static final int SAVE_AUTO = 0;
 public static final int SAVE_VIRTUAL = 1;
 public static final int SAVE_PHYSICAL = 2;
 private Files m_files;
 private Request m_formRequest;
 
 public SmartUpload()
 {
  m_totalBytes = 0;
  m_currentIndex = 0;
  m_startData = 0;
  m_endData = 0;
  m_boundary = new String();
  m_totalMaxFileSize = 0L;
  m_maxFileSize = 0L;
  m_deniedFilesList = new Vector();
  m_allowedFilesList = new Vector();
  m_denyPhysicalPath = false;
  m_forcePhysicalPath = false;
  m_contentDisposition = new String();
  m_files = new Files();
  m_formRequest = new Request();
 }
 
 public final void init(ServletConfig servletconfig) throws ServletException
 {
  m_application = servletconfig.getServletContext();
 }
 
 public void service(HttpServletRequest httpservletrequest, HttpServletResponse httpservletresponse)throws ServletException, IOException
 {
  m_request = httpservletrequest;
  m_response = httpservletresponse;
 }
 
 public final void initialize(ServletConfig servletconfig, HttpServletRequest httpservletrequest, HttpServletResponse httpservletresponse)throws ServletException
 {
  m_application = servletconfig.getServletContext();
  m_request = httpservletrequest;
  m_response = httpservletresponse;
 }
 
 public final void initialize(PageContext pagecontext)throws ServletException
 {
  m_application = pagecontext.getServletContext();
  m_request = (HttpServletRequest)pagecontext.getRequest();
  m_response = (HttpServletResponse)pagecontext.getResponse();
 }
 
 public final void initialize(ServletContext servletcontext, HttpSession httpsession, HttpServletRequest httpservletrequest, HttpServletResponse httpservletresponse, JspWriter jspwriter) throws ServletException
 {
  m_application = servletcontext;
  m_request = httpservletrequest;
  m_response = httpservletresponse;
 }
 
 public void upload()throws ServletException, IOException, SmartUploadException
 {
  int i = 0;
  boolean flag = false;
  long l = 0L;
  boolean flag1 = false;
  String s = new String();
  String s2 = new String();
  String s4 = new String();
  String s5 = new String();
  String s6 = new String();
  String s7 = new String();
  String s8 = new String();
  String s9 = new String();
  String s10 = new String();
  boolean flag2 = false;
  m_totalBytes = m_request.getContentLength();
  m_binArray = new byte[m_totalBytes];
  int j;
  for(; i < m_totalBytes; i += j)
  try
  {
   m_request.getInputStream();
   j = m_request.getInputStream().read(m_binArray, i, m_totalBytes - i);
  }
  catch(Exception exception)
  {
   throw new SmartUploadException("Unable to upload.");
  }
  
  for(; !flag1 && m_currentIndex < m_totalBytes; m_currentIndex++)
  if(m_binArray[m_currentIndex] == 13)
   flag1 = true;
  else
   m_boundary = m_boundary + (char)m_binArray[m_currentIndex];
  
  if(m_currentIndex == 1)
   return;
  for(m_currentIndex++; m_currentIndex < m_totalBytes; m_currentIndex = m_currentIndex + 2)
  {
   String s1 = getDataHeader();
   m_currentIndex = m_currentIndex + 2;
   boolean flag3 = s1.indexOf("filename") > 0;
   String s3 = getDataFieldValue(s1, "name");
   if(flag3)
   {
    s6 = getDataFieldValue(s1, "filename");
    s4 = getFileName(s6);
    s5 = getFileExt(s4);
    s7 = getContentType(s1);
    s8 = getContentDisp(s1);
    s9 = getTypeMIME(s7);
    s10 = getSubTypeMIME(s7);
   }
   getDataSection();
   if(flag3 && s4.length() > 0)
   {
    if(m_deniedFilesList.contains(s5))
     throw new SecurityException("The extension of the file is denied to be uploaded (1015).");
    if(!m_allowedFilesList.isEmpty() && !m_allowedFilesList.contains(s5))
     throw new SecurityException("The extension of the file is not allowed to be uploaded (1010).");
    if(m_maxFileSize > 0L && (long)((m_endData - m_startData) + 1) > m_maxFileSize)
     throw new SecurityException("Size exceeded for this file : " + s4 + " (1105).");
    l += (m_endData - m_startData) + 1;
    if(m_totalMaxFileSize > 0L && l > m_totalMaxFileSize)
     throw new SecurityException("Total File Size exceeded (1110).");
   }
   if(flag3)
   {
    com.kinstar.issuing.file.File file = new com.kinstar.issuing.file.File();
    file.setParent(this);
    file.setFieldName(s3);
    file.setFileName(s4);
    file.setFileExt(s5);
    file.setFilePathName(s6);
    file.setIsMissing(s6.length() == 0);
    file.setContentType(s7);
    file.setContentDisp(s8);
    file.setTypeMIME(s9);
    file.setSubTypeMIME(s10);
    if(s7.indexOf("application/x-macbinary") > 0)
     m_startData = m_startData + 128;
     file.setSize((m_endData - m_startData) + 1);
     file.setStartData(m_startData);
     file.setEndData(m_endData);
     m_files.addFile(file);
    } else
    {
     String s11 = new String(m_binArray, m_startData, (m_endData - m_startData) + 1);
     m_formRequest.putParameter(s3, s11);
    }
    if((char)m_binArray[m_currentIndex + 1] == '-')
     break;
    }
 
   }
 
 public int save(String s)throws ServletException, IOException, SmartUploadException
 {
  return save(s, 0);
 }
 
 public int save(String s, int i)throws ServletException, IOException, SmartUploadException
 {
  int j = 0;
  if(s == null)
   s = m_application.getRealPath("/");
  if(s.indexOf("/") != -1)
  {
   if(s.charAt(s.length() - 1) != '/')
    s = s + "/";
   } else
   if(s.charAt(s.length() - 1) != '\\')
    s = s + "\\";
   for(int k = 0; k < m_files.getCount(); k++)
   if(!m_files.getFile(k).isMissing())
   {
   m_files.getFile(k).saveAs(s + m_files.getFile(k).getFileName(), i);
   j++;
  }
 
  return j;
 }
 
 public int getSize()
 {
  return m_totalBytes;
 }
 
 public byte getBinaryData(int i)
 {
  byte byte0;
  try
  {
   byte0 = m_binArray[i];
  }
  catch(Exception exception)
  {
   throw new ArrayIndexOutOfBoundsException("Index out of range (1005).");
  }
  return byte0;
 }
 
 public Files getFiles()
 {
  return m_files;
 }
 
 public Request getRequest()
 {
  return m_formRequest;
 }
 
 public void downloadFile(String s) throws ServletException, IOException, SmartUploadException
 {
  downloadFile(s, null, null);
 }
 
 public void downloadFile(String s, String s1) throws ServletException, IOException, SmartUploadException, SmartUploadException
 {
  downloadFile(s, s1, null);
 }
 
 public void downloadFile(String s, String s1, String s2)throws ServletException, IOException, SmartUploadException
 {
  downloadFile(s, s1, s2, 65000);
 }
 
 public void downloadFile(String s, String s1, String s2, int i)throws ServletException, IOException, SmartUploadException
 {
  if(s == null)
   throw new IllegalArgumentException("File '" + s + "' not found (1040).");
  if(s.equals(""))
   throw new IllegalArgumentException("File '" + s + "' not found (1040).");
  if(!isVirtual(s) && m_denyPhysicalPath)
   throw new SecurityException("Physical path is denied (1035).");
  if(isVirtual(s))
   s = m_application.getRealPath(s);
  java.io.File file = new java.io.File(s);
  FileInputStream fileinputstream = new FileInputStream(file);
  long l = file.length();
  boolean flag = false;
  int k = 0;
  byte abyte0[] = new byte[i];
  if(s1 == null)
   m_response.setContentType("application/x-msdownload");
  else
  if(s1.length() == 0)
   m_response.setContentType("application/x-msdownload");
  else
   m_response.setContentType(s1);
  m_response.setContentLength((int)l);
  m_contentDisposition = m_contentDisposition != null ? m_contentDisposition : "attachment;";
  if(s2 == null)
   m_response.setHeader("Content-Disposition", m_contentDisposition + " filename=" + getFileName(s));
  else
  if(s2.length() == 0)
   m_response.setHeader("Content-Disposition", m_contentDisposition);
  else
   m_response.setHeader("Content-Disposition", m_contentDisposition + " filename=" + s2);
  while((long)k < l)
  {
   int j = fileinputstream.read(abyte0, 0, i);
   k += j;
   m_response.getOutputStream().write(abyte0, 0, j);
  }
  fileinputstream.close();
 }
 
 public void downloadField(ResultSet resultset, String s, String s1, String s2) throws ServletException, IOException, SQLException
 {
 if(resultset == null)
  throw new IllegalArgumentException("The RecordSet cannot be null (1045).");
 if(s == null)
  throw new IllegalArgumentException("The columnName cannot be null (1050).");
 if(s.length() == 0)
  throw new IllegalArgumentException("The columnName cannot be empty (1055).");
 byte abyte0[] = resultset.getBytes(s);
 if(s1 == null)
  m_response.setContentType("application/x-msdownload");
 else
 if(s1.length() == 0)
  m_response.setContentType("application/x-msdownload");
 else
  m_response.setContentType(s1);
 m_response.setContentLength(abyte0.length);
 if(s2 == null)
  m_response.setHeader("Content-Disposition", "attachment;");
 else
 if(s2.length() == 0)
  m_response.setHeader("Content-Disposition", "attachment;");
 else
  m_response.setHeader("Content-Disposition", "attachment; filename=" + s2);
 m_response.getOutputStream().write(abyte0, 0, abyte0.length);
 }
 
 public void fieldToFile(ResultSet resultset, String s, String s1)throws ServletException, IOException, SmartUploadException, SQLException
 {
  try
  {
   if(m_application.getRealPath(s1) != null)
   s1 = m_application.getRealPath(s1);
   InputStream inputstream = resultset.getBinaryStream(s);
   FileOutputStream fileoutputstream = new FileOutputStream(s1);
   int i;
   while((i = inputstream.read()) != -1)
    fileoutputstream.write(i);
   fileoutputstream.close();
  }
  catch(Exception exception)
  {
   throw new SmartUploadException("Unable to save file from the DataBase (1020).");
  }
 }
 
 private String getDataFieldValue(String s, String s1)
 {
  String s2 = new String();
  String s3 = new String();
  int i = 0;
  boolean flag = false;
  boolean flag1 = false;
  boolean flag2 = false;
  s2 = s1 + "=" + '"';
  i = s.indexOf(s2);
  if(i > 0)
  {
   int j = i + s2.length();
   int k = j;
   s2 = "\"";
   int l = s.indexOf(s2, j);
   if(k > 0 && l > 0)
   s3 = s.substring(k, l);
  }
  return s3;
 }
 
 private String getFileExt(String s)
 {
  String s1 = new String();
  int i = 0;
  int j = 0;
  if(s == null)
   return null;
  i = s.lastIndexOf(46) + 1;
  j = s.length();
  s1 = s.substring(i, j);
  if(s.lastIndexOf(46) > 0)
   return s1;
  else
  return "";
 }
 
 private String getContentType(String s)
 {
  String s1 = new String();
  String s2 = new String();
  int i = 0;
  boolean flag = false;
  s1 = "Content-Type:";
  i = s.indexOf(s1) + s1.length();
  if(i != -1)
  {
   int j = s.length();
   s2 = s.substring(i, j);
  }
  return s2;
 }
 
 private String getTypeMIME(String s)
 {
  String s1 = new String();
  int i = 0;
  i = s.indexOf("/");
  if(i != -1)
   return s.substring(1, i);
  else
  return s;
 }
 
 private String getSubTypeMIME(String s)
 {
  String s1 = new String();
  int i = 0;
  boolean flag = false;
  i = s.indexOf("/") + 1;
  if(i != -1)
  {
   int j = s.length();
   return s.substring(i, j);
  } else
  {
   return s;
  }
 }
 
 private String getContentDisp(String s)
 {
  String s1 = new String();
  int i = 0;
  int j = 0;
  i = s.indexOf(":") + 1;
  j = s.indexOf(";");
  s1 = s.substring(i, j);
  return s1;
 }
 
 private void getDataSection()
 {
  boolean flag = false;
  String s = new String();
  int i = m_currentIndex;
  int j = 0;
  int k = m_boundary.length();
  m_startData = m_currentIndex;
  m_endData = 0;
  while(i < m_totalBytes)
  if(m_binArray[i] == (byte)m_boundary.charAt(j))
  {
   if(j == k - 1)
   {
    m_endData = ((i - k) + 1) - 3;
    break;
   }
   i++;
   j++;
  } else
  {
   i++;
   j = 0;
  }
  m_currentIndex = m_endData + k + 3;
 }
 
 private String getDataHeader()
 {
  int i = m_currentIndex;
  int j = 0;
  boolean flag = false;
  for(boolean flag1 = false; !flag1;)
  if(m_binArray[m_currentIndex] == 13 && m_binArray[m_currentIndex + 2] == 13)
  {
   flag1 = true;
   j = m_currentIndex - 1;
   m_currentIndex = m_currentIndex + 2;
  } else
  {
   m_currentIndex++;
  }
  
  String s = new String(m_binArray, i, (j - i) + 1);
  return s;
 }
 
 private String getFileName(String s)
 {
  String s1 = new String();
  String s2 = new String();
  int i = 0;
  boolean flag = false;
  boolean flag1 = false;
  boolean flag2 = false;
  i = s.lastIndexOf(47);
  if(i != -1)
   return s.substring(i + 1, s.length());
  i = s.lastIndexOf(92);
  if(i != -1)
   return s.substring(i + 1, s.length());
  else
  return s;
 }
 
 public void setDeniedFilesList(String s) throws ServletException, IOException, SQLException
 {
  String s1 = "";
  if(s != null)
  {
  String s2 = "";
  for(int i = 0; i < s.length(); i++)
  if(s.charAt(i) == ',')
  {
   if(!m_deniedFilesList.contains(s2))
   m_deniedFilesList.addElement(s2);
   s2 = "";
  } else
  {
   s2 = s2 + s.charAt(i);
  }
  
  if(s2 != "")
   m_deniedFilesList.addElement(s2);
  } else
  {
   m_deniedFilesList = null;
  }
 }
 
 public void setAllowedFilesList(String s)
 {
  String s1 = "";
  if(s != null)
  {
   String s2 = "";
   for(int i = 0; i < s.length(); i++)
   if(s.charAt(i) == ',')
   {
    if(!m_allowedFilesList.contains(s2))
    m_allowedFilesList.addElement(s2);
    s2 = "";
   } else
   {
    s2 = s2 + s.charAt(i);
   }
   
   if(s2 != "")
    m_allowedFilesList.addElement(s2);
  } else
  {
   m_allowedFilesList = null;
  }
 }
 
 public void setDenyPhysicalPath(boolean flag)
 {
  m_denyPhysicalPath = flag;
 }
 
 public void setForcePhysicalPath(boolean flag)
 {
  m_forcePhysicalPath = flag;
 }
 
 public void setContentDisposition(String s)
 {
  m_contentDisposition = s;
 }
 
 public void setTotalMaxFileSize(long l)
 {
  m_totalMaxFileSize = l;
 }
 
 public void setMaxFileSize(long l)
 {
  m_maxFileSize = l;
 }
 
 protected String getPhysicalPath(String s, int i)throws IOException
 {
  String s1 = new String();
  String s2 = new String();
  String s3 = new String();
  boolean flag = false;
  s3 = System.getProperty("file.separator");
  if(s == null)
   throw new IllegalArgumentException("There is no specified destination file (1140).");
  if(s.equals(""))
   throw new IllegalArgumentException("There is no specified destination file (1140).");
  if(s.lastIndexOf("\\") >= 0)
  {
   s1 = s.substring(0, s.lastIndexOf("\\"));
   s2 = s.substring(s.lastIndexOf("\\") + 1);
  }
  if(s.lastIndexOf("/") >= 0)
  {
   s1 = s.substring(0, s.lastIndexOf("/"));
   s2 = s.substring(s.lastIndexOf("/") + 1);
  }
  s1 = s1.length() != 0 ? s1 : "/";
  java.io.File file = new java.io.File(s1);
  if(file.exists())
   flag = true;
  if(i == 0)
  {
   if(isVirtual(s1))
   {
    s1 = m_application.getRealPath(s1);
    if(s1.endsWith(s3))
     s1 = s1 + s2;
    else
    s1 = s1 + s3 + s2;
     return s1;
   }
   if(flag)
   {
    if(m_denyPhysicalPath)
     throw new IllegalArgumentException("Physical path is denied (1125).");
    else
     return s;
   } else
   {
    throw new IllegalArgumentException("This path does not exist (1135).");
   }
  }
  if(i == 1)
  {
   if(isVirtual(s1))
   {
    s1 = m_application.getRealPath(s1);
   if(s1.endsWith(s3))
    s1 = s1 + s2;
   else
    s1 = s1 + s3 + s2;
   return s1;
  }
  if(flag)
   throw new IllegalArgumentException("The path is not a virtual path.");
  else
   throw new IllegalArgumentException("This path does not exist (1135).");
  }
  if(i == 2)
  {
   if(flag)
   if(m_denyPhysicalPath)
    throw new IllegalArgumentException("Physical path is denied (1125).");
   else
    return s;
   if(isVirtual(s1))
    throw new IllegalArgumentException("The path is not a physical path.");
   else
   throw new IllegalArgumentException("This path does not exist (1135).");
  } else
  {
   return null;
  }
 }
 
 public void uploadInFile(String s)throws IOException, SmartUploadException
 {
  int i = 0;
  int j = 0;
  boolean flag = false;
  if(s == null)
   throw new IllegalArgumentException("There is no specified destination file (1025).");
  if(s.length() == 0)
   throw new IllegalArgumentException("There is no specified destination file (1025).");
  if(!isVirtual(s) && m_denyPhysicalPath)
   throw new SecurityException("Physical path is denied (1035).");
  i = m_request.getContentLength();
  m_binArray = new byte[i];
  int k;
  for(; j < i; j += k)
  try
  {
   k = m_request.getInputStream().read(m_binArray, j, i - j);
  }
  catch(Exception exception)
  {
   throw new SmartUploadException("Unable to upload.");
  }
  
  if(isVirtual(s))
   s = m_application.getRealPath(s);
  try
  {
   java.io.File file = new java.io.File(s);
   FileOutputStream fileoutputstream = new FileOutputStream(file);
   fileoutputstream.write(m_binArray);
   fileoutputstream.close();
  }
  catch(Exception exception1)
  {
   throw new SmartUploadException("The Form cannot be saved in the specified file (1030).");
  }
 }
 
 private boolean isVirtual(String s)
 {
  if(m_application.getRealPath(s) != null)
  {
   java.io.File file = new java.io.File(m_application.getRealPath(s));
   return file.exists();
  } else
  {
   return false;
  }
 }
}

SmartUploadException 类
/*
 * 创建日期 2006-7-29
 *
 * 更改所生成文件模板为
 * 窗口 > 首选项 > Java > 代码生成 > 代码和注释
 */
package com.kinstar.issuing.file;

/**
 * @author gongyifeng
 *
 * 更改所生成类型注释的模板为
 * 窗口 > 首选项 > Java > 代码生成 > 代码和注释
 */
public class SmartUploadException extends Exception
{

 SmartUploadException(String s)
 {
  super(s);
 }
}

上传的Servlet
package com.kinstar.issuing.action;

import java.io.IOException;
import javax.servlet.Servlet;
import javax.servlet.ServletException;
import java.io.*;
import java.sql.SQLException;
import java.util.*;
import java.text.*;
import javax.servlet.*;
import javax.servlet.http.*;


import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.kinstar.issuing.file.File;
import com.kinstar.issuing.file.SmartUpload;
import com.kinstar.issuing.objects.t_user;
import com.kinstar.issuing.operation.UserOperation;
import com.kinstar.issuing.program.programService;
import com.kinstar.issuing.session.SessionGloble;
import com.kinstar.issuing.util.StringUtil;

/**
 * @version  1.0
 * @author gyf
 */


public class upload2ProgramAction extends HttpServlet{
  private ServletConfig config;
  /**
  * 初始化Servlet
  */
  final public void init(ServletConfig config) throws ServletException {
  this.config = config;
  }
  /**
  * 处理GET请求
  */
  public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
   doPost(request,response);
  }
 
  /**
  * 响应POST请求
  */
  public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {  
   int count=0;
   SmartUpload mySmartUpload = new SmartUpload();
   try {
     // 初始化
     mySmartUpload.initialize(config,request,response);
 
     // 上载
     mySmartUpload.upload();
     com.kinstar.issuing.file.File f1 = mySmartUpload.getFiles().getFile(0);
   //  com.kinstar.issuing.file.File f2 = mySmartUpload.getFiles().getFile(1);
     String backPic = f1.getFileName();
   //String name2 = f2.getFileName();
   
     long size=0;
     
    // 保存上载文件到指定目录
   count=mySmartUpload.save("ads");  
   response.sendRedirect("program.jsp?dopass=ture");
  
    }     

     
    catch (Exception e){
     response.sendRedirect("fail.jsp");
   } 
}

2.common-fileupload组件
挺好用的,也能够上传大文件,我试过,300M以上的文件上传本地传非常快,异地测试也能够上传成功.
首先要下载org.apache.commons.fileupload包和org.apache.commons.io包

下面是我的servlet
package com.kinstar.issuing.action;

import java.io.IOException;
import javax.servlet.Servlet;
import javax.servlet.ServletException;
import java.io.*;
import java.sql.SQLException;
import java.util.*;
import java.text.*;
import javax.servlet.*;
import javax.servlet.http.*;
import java.util.regex.*;


import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.fileupload.DiskFileUpload;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;

import com.kinstar.issuing.objects.t_user;
import com.kinstar.issuing.operation.UserOperation;
import com.kinstar.issuing.program.programService;
import com.kinstar.issuing.session.SessionGloble;
import com.kinstar.issuing.util.StringUtil;

/**
 * @version  1.0
 * @author gyf
 */


public class uploadProgramAction extends HttpServlet{
  private static final String CONTENT_TYPE = "text/html; charset=GB2312";
 
  /**
  * 处理GET请求
  */
  public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    doPost(request,response);
  }
 
  /**
  * 响应POST请求
  */
  public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
   // 变量定义
    response.setContentType(CONTENT_TYPE);
    HttpSession modifysession=request.getSession();
    SessionGloble logonUser;
    logonUser=(SessionGloble)modifysession.getAttribute("UserInfo");
       if(logonUser==null){
       response.sendRedirect("mainindex.jsp");
    }
    t_user userinfo=new t_user();
    UserOperation user=null;
    try {
     user = new UserOperation();
    } catch (Exception e1) {
    // TODO 自动生成 catch 块
    e1.printStackTrace();
    }
    try {
     userinfo=user.getUser(logonUser.getUserId());
    } catch (Exception e2) {
    // TODO 自动生成 catch 块
    e2.printStackTrace();
    }
     //System.out.println("figure="+userinfo.getUserFigure());
     PrintWriter out=response.getWriter();
     DateFormat updf = new SimpleDateFormat("yyyyMMddHHmm");
     String updateTime = updf.format(new Date());
     int isNeed = 0;
     String IsCheck="0";
  
    //省农行用户上传的节目必需显示,且审批已经合格
     if(userinfo.getUserFigure().equals("1")){
     isNeed = 1;
     IsCheck = "1";
     }
     else{
     isNeed = 0;
     IsCheck = "0";
     }
    int type=0;
    String avaTime="";
    String screen="";
    int fileTime=0;
    int fileTimeReal=0;
    int circle=0;
    String picSwitch="";
    String deleState="1";
    String backPic="";
   
    String fieldName="";
    String finalName="";
    String fileNameReal="";
    long size=0;
    String name="";
     try {
    DiskFileUpload fu = new DiskFileUpload();
    // 设置允许用户上传文件大小,单位:字节,这里设为2m
    fu.setSizeMax(5*1024*1024*1024);
    // 设置最多只允许在内存中存储的数据,单位:字节
    fu.setSizeThreshold(10*1024*1024);
    // 设置一旦文件大小超过getSizeThreshold()的值时数据存放在硬盘的目录
    fu.setRepositoryPath("C:\\WINDOWS\\Temp\\");
    //开始读取上传信息
    List fileItems = fu.parseRequest(request);
    //依次处理每个上传的文件
    Iterator iter = fileItems.iterator();
 
  
       //正则匹配,过滤路径取文件名
    String regExp=".+\\\\(.+)$";
 
    //过滤掉的文件类型
    String[] errorType={".exe",".com",".cgi",".asp"};
     
    Pattern p = Pattern.compile(regExp);
    StringUtil su = new StringUtil();
      
    while (iter.hasNext()) {
      FileItem item = (FileItem)iter.next();
    
       if(item.isFormField()) {
       // 获得表单域的名字
        fieldName = item.getFieldName();
        // 如果表单域的名字是name…
        if(fieldName.equals("type"))
            type = Integer.parseInt(item.getString());
      
       }
      if (!item.isFormField()) {
       name = item.getName();
       size = item.getSize();
       if((name==null||name.equals("")) && size==0)
        continue;
        Matcher m = p.matcher(name);
        boolean result = m.find();
        if (result){
        for (int temp=0;temp<errorType.length;temp++){
        if (m.group(1).endsWith(errorType[temp])){
        throw new IOException(name+": wrong type");
        }
        }
      
       DateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");
                String date = df.format(new Date());
       fileNameReal=date+m.group(1);
       finalName=date+Math.round(Math.random()*10000)+fileNameReal.substring(fileNameReal.indexOf("."));
        //保存上传的文件到指定的目录  
        //在下文中上传文件至数据库时,将对这里改写
        item.write(new File(getServletContext().getRealPath(".//ads//")+finalName));
        //out.print(finalName+size);
        }
       else
       {
      throw new IOException("fail to upload");
      
       } 
      }
      if(item.isFormField()) {
     // 获得表单域的名字
     fieldName = item.getFieldName();
     if(fieldName.equals("avaTime"))
      avaTime=item.getString();
     if(fieldName.equals("screen"))
      screen=item.getString();
     if(fieldName.equals("fileTime"))
      fileTime = Integer.parseInt(item.getString());
     if(fieldName.equals("fileTimeReal"))
      fileTimeReal = Integer.parseInt(item.getString());
     if(fieldName.equals("circle"))
      circle = Integer.parseInt(item.getString()); 
     if(fieldName.equals("switchPic"))
        picSwitch = item.getString(); 
      
      }   
       }
     }catch (IOException e){
       out.println(e);
     }catch (FileUploadException e){
       out.println(e);
     } catch (Exception e) {
    // TODO 自动生成 catch 块
     e.printStackTrace();
     }
     if(finalName.equals("")){
       response.sendRedirect("fail.jsp");
     }
     else{
   try {
    programService ps = new programService();
    ps.insertProgram(userinfo.getUserId(),updateTime,type,finalName,size,isNeed,avaTime,deleState,IsCheck,userinfo.getCity(),backPic,screen,fileTime,fileTimeReal,picSwitch,circle,userinfo.getUserFigure(),new String(fileNameReal.getBytes("GB2312"),"ISO8859-1"));
    response.sendRedirect("program.jsp?dopass=true"); 
   } catch (Exception e3) {
   // TODO 自动生成 catch 块
    e3.printStackTrace();
   }
     }
   }
}
 

posted @ 2006-08-18 16:29 KevinGong 阅读(1064) | 评论 (1)编辑 收藏

最近做一个cts,其中有一个定时报警的需求,网上找了点资料参考!

如何在Web工程中实现任务计划调度

     好多朋友用过Windows的任务计划,也有不少程序迷自己曾写过时钟报警、系统自动关机等趣味程序,可却很少有朋友在Web工程中实现过类似功能。今天有空把笔者先前曾在Tomcat上实现的类似功能,搬出来与大家共享。
     早在几年前,我公司跟某市财政局合作项目开发,为加强财政局对所属单位财务状况的有效监管,开发、实施了财政局数据中心项目。此项目采用B/S加C/S混合结构模式。财政局Web服务器上架设数据同步接收装置,由市属单位每天下班前把财务信息通过HTTP协议上传至财政局中心服务器,与Web服务器上的接收装置对接。财政局内部各部门需要查阅大量财务信息,获取完备的市属单位当前财务状况信息,各部门按职能划分,需要准确的获取各部门各自所关注的汇总信息,以财政报表的形式提供。
    因财政数据量大,实时计算财政报表速度较慢,当初就考虑用报表缓存来减轻服务器的负担,但用缓存需要一个合理的缓存更新机制。考虑到各市属单位每天下班前才把财务数据上传,财政局每天所查看到的财务信息其实并不包括当天(除非有某位领导等到所属单位全部上传完之后才来查看信息,应该已经下班了),所以要是能实现任务计划调度,在每晚深夜把当天及历史财务信息汇总,更新缓存,速度瓶颈不就解决了吗。
    当时由于系统核心是基于Web部署的,报表计算引擎也相应的部署在Tomcat容器上,因此如果想要借用Windows的任务计划来实现定时计算,就需要额外编写普通桌面应用程序接口,稍显复杂。于是就琢磨着想在Web上实现,经过查阅较多相关资料,发现Java定时器(java.util.Timer)有定时触发计划任务的功能,通过配置定时器的间隔时间,在某一间隔时间段之后会自动有规律的调用预先所安排的计划任务(java.util.TimerTask)。另外,由于我们希望当Web工程启动时,定时器能自动开始计时,在整个Web工程的生命期里,定时器能在每晚深夜触发一次报表计算引擎。因此定时器的存放位置也值得考查,不能简单的存在于单个Servlet或JavaBean中,必须能让定时器宿主的存活期为整个Web工程生命期,在工程启动时能自动加载运行。结合这两点,跟Servlet上下文有关的侦听器就最合适不过了,通过在工程的配置文件中加以合理配置,会在工程启动时自动运行,并在整个工程生命期中处于监听状态。
    下面就Servlet侦听器结合Java定时器来讲述整个实现过程。要运用Servlet侦听器需要实现javax.servlet.ServletContextListener接口,同时实现它的contextInitialized(ServletContextEvent event)和contextDestroyed(ServletContextEvent event)两个接口函数。考虑定时器有个建立和销毁的过程,看了前面两个接口函数,就不容置疑的把建立的过程置入contextInitialized,把销毁的过程置入contextDestroyed了。
    我把ServletContextListener的实现类取名为ContextListener,在其内添加一个定时器,示例代码如下所示(为考虑篇幅,仅提供部分代码供读者参考):


    private java.util.Timer timer = null;
    public void contextInitialized(ServletContextEvent event) {
        timer = new java.util.Timer(true);
        event.getServletContext().log("定时器已启动");        
         timer.schedule(new MyTask(event.getServletContext()), 0, 60*60*1000);
        event.getServletContext().log("已经添加任务调度表");
    }
    public void contextDestroyed(ServletContextEvent event) {
        timer.cancel();
        event.getServletContext().log("定时器销毁");
    }

    以上代码中, timer.schedule(new MyTask(event.getServletContext()), 0, 60*60*1000)这一行为定时器调度语句,其中MyTask是自定义需要被调度的执行任务(在我的财政数据中心项目中就是报表计算引擎入口),从java.util.TimerTask继承,下面会重点讲述,第三个参数表示每小时(即60*60*1000毫秒)被触发一次,中间参数0表示无延迟。其它代码相当简单,不再详细说明。
   下面介绍MyTask的实现,上面的代码中看到了在构造MyTask时,传入了javax.servlet.ServletContext类型参数,是为记录Servlet日志方便而传入,因此需要重载MyTask的构造函数(其父类java.util.TimerTask原构造函数是没有参数的)。在timer.schedule()的调度中,设置了每小时调度一次,因此如果想实现调度任务每24小时被执行一次,还需要判断一下时钟点,以常量C_SCHEDULE_HOUR表示(晚上12点,也即0点)。同时为防止24小时执行下来,任务还未执行完(当然,一般任务是没有这么长的),避免第二次又被调度以引起执行冲突,设置了当前是否正在执行的状态标志isRunning。示例代码如下所示:


    private static final int C_SCHEDULE_HOUR   = 0;
    private static boolean isRunning = false;
         private ServletContext context = null;
    public MyTask(ServletContext context) {
        this.context = context;
    }
    public void run() {
        Calendar cal = Calendar.getInstance();        
        if (!isRunning)  {           
            if (C_SCHEDULE_HOUR == cal.get(Calendar.HOUR_OF_DAY)) {            
                    isRunning = true;                
                context.log("开始执行指定任务");
                
                //TODO 添加自定义的详细任务,以下只是示例
                int i = 0;
                while (i++ < 10) {
                    context.log("已完成任务的" + i + "/" + 10);
                }

                isRunning = false;
                context.log("指定任务执行结束");               
            }            
        } else {
            context.log("上一次任务执行还未结束");
        }
    }

    上面代码中“//TODO……”之下四行是真正被调度执行的演示代码(在我的财政数据中心项目中就是报表计算过程),您可以换成自己希望执行的语句。
到这儿,ServletContextListener和MyTask的代码都已完整了。最后一步就是把ServletContextListener部署到您的Web工程中去,在您工程的web.xml配置文件中加入如下三行:
   
        com.test.ContextListener
    
    当然,上面的com.test得换成您自己的包名了。保存web.xml文件后,把工程打包部署到Tomcat中即可。任务会在每晚12点至凌晨1点之间被执行,上面的代码会在Tomcat的日志文件中记录如下:
2003-12-05 0:21:39 开始执行指定任务
2003-12-05 0:21:39 已完成任务的1/10
    ……
2003-12-05 0:21:39 已完成任务的10/10
2003-12-05 0:21:39 指定任务执行结束

posted @ 2006-08-06 21:48 KevinGong 阅读(261) | 评论 (0)编辑 收藏