Servlet中实现文件上传

2008.10.08 / 标签: ,, / 分类: J2EE技术

很久以前写的那个[文件上传] 是在JSP页面中实现的,此次我们来要在Servlet中实现文件的上传处理,两种方法的代码是不一样的,我看到有很多人说在Servlet中要使用commons-fileupload.jar的话还需要commons-io.jar提供支持而在JSP中不需要,经过我的测试,MS在Servlet中也是不需要这个commons-io.jar。
下面我们开始实现Servlet处理文件上传,首先我们需要去下载上面提到的两个jar包,下载地址分别为:
http://commons.apache.org/fileupload
http://commons.apache.org/io/
然后将这两个包导入到你的Web工程下的WEB-INF中的lib目录中去,没有lib的话请自建。另外如果你使用的是JBuilder来做的话,这样放进去是没有用的,使用的时候会提示DOES NOT EXIST。需要按照如下方法导入:
1.选则菜单栏中的“Tools”->“Configure”->“Libraies”。
2.点击“New”,Name这里随便输入(例如:CommonsFileUpload),最好是见其名知其意,Location这里可以不管他。
3.点击“Add”,将那两个包都导入进来,最后一路“OK”。
4.在你的工程命(例如:Neeke.jpx)上右键并选择“Properties”进入“Properties for ‘Neeke.jpx’”对话框,选择“Required Libraries”项,选择“Add”,找到你刚才新建的那个“CommonsFileUpload”然后一路“OK”。
现在就可以正常使用了,且JBuilder会自动将这两个包放在lib下。
新建一个upload.jsp,其代码如下:

<%@ page contentType="text/html; charset=GBK" %>
<html>
<head>
<title>
upload
</title>
</head>
<body>
<form action="../uploadservlet" method="POST" enctype="Multipart/form-data">
<input type="file" name="file" /><input type="submit" value="上传" />
</form>
</body>
</html>

需要注意的是表单form的enctype属性一定要写“Multipart/form-data”,没有什么为什么!
接下来我们新建一个Servlet为UploadServlet(要有DOPOST方法)并导入如下几个包:
org.apache.commons.fileupload.*;
org.apache.commons.io.*;
org.apache.commons.fileupload.servlet.ServletFileUpload;
org.apache.commons.fileupload.disk.DiskFileItemFactory;
由于在JBuilder中doPost()调用了doGet()方法,所以我们可以直接改写doGet()方法,具体代码如下:

public void doGet(HttpServletRequest request, HttpServletResponse response) throws
             ServletException, IOException {
        response.setContentType(CONTENT_TYPE);
        PrintWriter out = response.getWriter();
        DiskFileItemFactory fac = new DiskFileItemFactory();
        //设置缓存文件大小
        fac.setSizeThreshold(1024*1024);
        //缓存文件位置,这里取的是默认的位置
        fac.setRepository(fac.getRepository());
        ServletFileUpload upload = new ServletFileUpload(fac);
        //设置最大允许上传的文件大小,这里是5MB
        upload.setFileSizeMax(1024*1024*5);
        List fileList = null;
        try {
            fileList = upload.parseRequest(request);
        } catch (FileUploadException ex) {
            response.sendRedirect("admin/upload.jsp?result=size");
            ex.printStackTrace();
            return;
        }
        Iterator iter = fileList.iterator();
        while(iter.hasNext()){ i>
            FileItem fileItem = (FileItem)iter.next();
            if(!fileItem.isFormField()){
                String name = fileItem.getName();
                String fileSize = new Long(fileItem.getSize()).toString();
                if(name == null || name.equals("") || fileSize.equals("0"))
                    continue;
                //截取出纯文件名
                name = name.substring(name.lastIndexOf("\\")+1);
                //存储文件
                File saveFile = new File("d:\\upload\\"+name);
                try {
                    fileItem.write(saveFile);
                } catch (Exception ex1) {
                    ex1.printStackTrace();
                    return;
                }
            }
        }
        out.close();
}

这样这个Servlet就能够实现对文件的上传了,这里文件的缓存大小及文件大小限制都可以动态的设置,我想这个问题具体就不需要我写了吧,嘿嘿。

JSP网站RSS的实现

2008.10.05 / 标签: ,, / 分类: J2EE技术

RSS(也叫聚合内容,Really Simple Syndication)现在用的已经很广啦,最初的RSS要追溯到1995年,当Ramanathan V. Guha和其他在苹果电脑公司的高级技术组开发了一个测试的内容框架。更多有关RSS的资料可查看这里,下面我们来为我们的JSP网站生成RSS。

首先我们来看看最基本的RSS结构:

 
  1. <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  2. <rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/"  
  3. xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/"  
  4. xmlns:wfw="http://wellformedweb.org/CommentAPI/"  
  5. xmlns:slash="http://purl.org/rss/1.0/modules/slash/">
  6. </rss>

其实就是一个XML文件!在<rss></rss>之间我们可以自由配置自己要发布的RSS的格式。例如此次我们要发布的RSS是这样的:

 
  1. <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  2. <rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" x
  3. mlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" 
  4. xmlns:wfw="http://wellformedweb.org/CommentAPI/" x
  5. mlns:slash="http://purl.org/rss/1.0/modules/slash/">
  6. <channel>
  7. <item>
  8. <title>JSP网站RSS的实现</title>
  9. <author>neeke</author>
  10. <pubDate>2008-10-04</pubDate>
  11. <description>这是来自尼克技术博客博客的RSS</description>
  12. <category>J2EE技术</category>
  13. </item>
  14. </channel>
  15. </rss>

 

了解了它的结构实现起来就容易了。我们创建IO流,并从数据库中获取到我们要发布的RSS资源的集合,然后按照它的格式与结构一行一行的写入到一个RSS.XML文件中即可。

 
  1. public static void publishRss(String rssPath)
  2.     {
  3.       &
    nbsp; 
    //获得要发布的RSS数据集合
  4.         ArrayList rssArticle = ArticleManager.getArticlesAll();
  5.         try {
  6.             //创建输入输出流
  7.             FileWriter fw = new FileWriter(rssPath);
  8.             BufferedWriter bw = new BufferedWriter(fw);
  9.             //开始按照格式写入数据
  10.             bw.write(
  11.                     "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\r\n");
  12.             bw.write("<?xml-stylesheet type=\"text/xsl\" href=\"CSS/rss.xslt\"?>");
  13.             bw.write("<rss version=\"2.0\" xmlns:dc=\"http://purl.org/dc/elements/1.1/\" xmlns:trackback=\"http://madskills.com/public/xml/rss/module/trackback/\" xmlns:wfw=\"http://wellformedweb.org/CommentAPI/\" xmlns:slash=\"http://purl.org/rss/1.0/modules/slash/\">\r\n");
  14.             bw.write("<channel>\r\n");
  15.             for (int i = 0; i < rssArticle.size(); i++) {
  16.                 ArticleBean article = (ArticleBean) rssArticle.get(i);
  17.                 bw.write("<item>\r\n");
  18.                 bw.write("<title>" + article.getTitle() + "</title>\r\n");
  19.                 bw.write("<author>" + article.getAuthorId() + "</author>\r\n");
  20.                 bw.write("<pubDate>" + article.getPostTime() + "</pubDate>\r\n");
  21.                 bw.write("<description>" + article.getIntro() +
  22.                          "</description>\r\n");
  23.                 bw.write("<category>" + article.getCateId() + "</category>\r\n");
  24.                 bw.write("</item>\r\n");
  25.             }
  26.             bw.write("</channel>\r\n");
  27.             bw.write("</rss>");
  28.             //关闭流,RSS发布完毕。
  29.             bw.close();
  30.             fw.close();
  31.         } catch (IOException ex) {
  32.             ex.printStackTrace();
  33.         }
  34.     }

发布完毕,经过我的测试打开后会提示出错,用记事本打开生成的源文件,然而我们的RSS文件是一点问题都没有的哇,怎么可能呢?接着又用JBuilder打开这个XML文件,晕倒~汉字全是乱码,立刻意识到问题出在了哪里了。在哪呢?其实就是文件的编码问题!将原先
bw.write("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\r\n");该行代码中的UTF-8改为GBK,重新跑一次程序,一切OK!

J2EE MVC模式中首页初始化

2008.10.04 / 标签: ,,,,,,, / 分类: J2EE技术

虽然也学了这么久的J2EE了(基础型),但是我一直都搞不明白:MVC模式是要分三层的,显示层、控制层(业务逻辑层)及数据层,业务逻辑层才能访问数据层,而显示层不能够直接访问数据层。既然如此,那么网站的首页所需要的数据都是来自数据库的,是要动态读取的,这就要在jsp中直接访问数据层,岂不是相互矛盾了吗?
去了几个技术论坛看了看,有人说那只是一个高效的框架模型,不一定非要遵守,可以直接在首页jsp中调用数据层的方法,活人岂能被尿憋死?话虽说有那么点道理,不过我还是不想这么试。
我是这么想的:
方法1.能不能打开网站地址时候访问的第一个文件是一个Servlet,在Servlet中获得首页用于显示所需要的所有数据,然后将它放在request中,接着在使用
request.getRequestDispatcher("index.jsp").forward(request, response);
跳转到真实的首页,如此即可在index.jsp中从request中获得所要的数据了。那么,如何才能打开网址就直接访问Servlet呢?在网站的根目录下WEB-INF中的web.xml中有这么一对标签:
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
类似于配置IIS中的默认首页 ,我们把这里的index.jsp改为对应的Servlet即可。

方法2.创建一个过滤器,专门用来过滤首页文件,当请求首页文件时就在过滤器中取数据。过滤器本身其实也是Servlet。
我就晕了,无论用这里面哪一个方法,那这里面的Servlet到底属于哪一层啊?是不是我太钻牛角尖了?

读写HTML代码类型配置信息的思考

2008.10.03 / 标签: ,,, / 分类: J2EE技术

昨天写了那个 [自定义配置文件] ,今天就又碰到问题了。如果我们定义的这个配置信息要能够支持HTML代码呢?比如要能够直接支持保存超级链接,统计代码啦诸如此类,那可就会爆出问题来。
例如,我们现在要保存一段51啦的统计代码:
<scrip tlanguage="javascript" type="text/javascript" src="http://js.users.51.la/1642363.js"></script>
<noscript>
<a href="http://www.51.la/?1642363" target="_blank"><img alt="&#x6211;&#x8981;&#x5566;&#x514D;&#x8D39;&#x7EDF;&#x8BA1;" src="http://img.users.51.la/1642363.asp" style="border:none" /></a>
</noscript>
将它保存的时候是不会出错的,保存到配置文件中会是这样的:

Const ZC_BLOG_COPYRIGHT="<scrip tlanguage="javascript"
type="text/javascript"src="http://js.users.51.la/1642363.js"></script><noscript><a href="http://www.51.la/?1642363" target="_blank"><img alt="&#x6211;&#x8981;&#x5566;&#x514D;&#x8D39;&#x7EDF;&#x8BA1;" src="http://img.users.51.la/1642363.asp" style="border:none" /></a></noscript>";

当我们第二次读取它的时候,按照我们上次的方法(截取“=”号和“;”之间部分)就出错啦。来看看它给我们截出来的是什么吧,先找到“=”紧接着找第一个“;”,然后把它们之间的截取出来,那就是:

<scrip tlanguage="javascript" type="text/javascript" src="http://js.users.51.la/1642363.js"></script>
<noscript><a href="http://www.51.la/?1642363" target="_blank"><img alt="&#x621

这不就完全错了吗,根本就不是我们想要得到的那段代码。怎么办?
首先,从“=”开始截取我们不用修改,我们要让它截取到该行的最后一个“;”,这样以来截取出来的就是我们想要的了,代码只需将int end = line.indexOf(";");修改为:int end = line.lastIndexOf(";");这样就OK了。
接下来还有一个问题,我们的配置文件的格式这这样的Const ZC_BLOG_COPYRIGHT="HTML代码";如果直接将“HTML代码”替换成上面的统计代码,虽然在我们修改读取的时候不会有问题,但是如果在网页的脚本中需要用的话那就出错了,为什么呢?因为统计代码中有“"”。
这个又要如何修改呢?也很简单,我们在写入代码到配置文件中之前先使用
copyRight = copyRight.replace(‘\"’,'\”);
将其中所有的双引号都替换为单引号,而取值修改的时候我们再反过来
copyRight = copyRight.replace(‘\”,’\"’);
把读取出来的代码中的所有单引号替换为双引号,这样用户在修改的时候看到的就和原来的一样了,而实际上的配置文件中却不是这样的,有点障眼法的意思,呵呵。

组建的功能区分

2008.07.31 / 标签: ,, / 分类: J2EE技术
Sofa

每一个组件和技术都有各自的功能和特点,在编写程序时,我们应该是以他们的功能来设计他们的作用,就好像在餐厅吃饭,服务员把菜谱提供给顾客,顾客根据菜谱点菜,然后把菜单交给服务员,而服务员根据菜单中冷、热菜的不同,交给不同的厨师,厨师做好后,把菜再交给服务员,由服务员吧菜给顾客端来。
在这个过程中,服务员是这个过程的组织者和控制器(Controller),他负责接待顾客,并把菜谱显示给顾客,把顾客的点菜内容交给厨师加工菜肴(类似于进行访问数据库和处理业务的Java类),最后服务员把菜肴端给顾客(类似于一个响应的JSP)。
对于顾客先看到的是菜谱,之后是整桌的菜肴。在程序中,用户能够看到的就是HTML、JSP页面,这部分称作视图(View)。当服务员把顾客的点菜内容交给厨师后,厨师根据不同的菜,采用不同的原料和配料来加工菜肴。这类似于在程序中,根据用户提交不同的请求数据,访问数据库或是进行业务逻辑处理,这部分称为模型(Model)。
在程序设计中,把采用模型(Model)、视图(View)、控制器(Controller)的设计方式称为MVC设计模式。

无觅相关文章插件,快速提升流量