分享

Jakarta-Common-FileUpload使用简单入门

 Blex 2011-04-25

common-fileuploadjakarta项目组开发的一个功能很强大的上传文件组件,可以支持多个文件同时上传,同时也可以除了将上传文件保存为文件之外,还可以将上传的文件数据提取保存至数据库中,甚至你可以通过调用其中提供的API,在程序代码中获得上传文件的内容,这样你就可以处理这些数据了,这个当然与具体的应用有关了。

这里只讲common-fileupload的简单使用入门,一并解决上传文件中文件名为中文时,上传之后文件名显示乱码的问题,这个解决方法很简单,在示例程序代码中的注释中有详细的描述,查看程序就可以明白了。同时这里的示例代码中,只提供了一个文件上传框的显示,但是在后台提供了多个文件上传的读取支持的,只要能够基本明白这个上传方法,做成多个文件上传也不成问题。

另外还需说明的是,对于上传文件,通常前台上传文件至后台时,后台是一个Servlet来处理请求,而Servlet处理请求中,通常会有返回页面,所以如果要做到界面显示,而不会让用户感觉有因为上传而产生的刷屏的样子,应该做一个类似于AJAX的表现,来进行局部刷新,不过AJAX本身而言,并不支持formpost方式的文件提交,所以不能用AJAX来进行上传文件的局部刷新。通常比较好的一种做法是在你的网页中内嵌一个iframe,在iframe里面做一个form,以进行文件上传的提交。具体示例代码见下。

本次的上传使用的Common-FileUpload的版本是最新版,即1.2.1版,与网上的其它代码相比,改了很多的使用方式,虽然可以兼容以前的调用方式,不过已经不推荐了,这里的示例代码使用最新的调用方式。它的下载地址是:http://commons./fileupload/,另外你可以通过下载地址中的User Guide链接,找到具体如何使用的方法,当然如果你对英文不感兴趣的话,可以看下面的示例代码,看明白后,再去看那个User Guide,可能收获会更大些。

好了,不说废话了,下面贴出示例代码:

WEB页面:

文件名:uploadtest.html

<html>

    <head>

        <title>文件上传</title>

        <meta http-equiv="Content-Type" content="text/html; charset=utf-8">

    </head>

    <body>

        <p>

            <b>文件上传</b>

        </p>

        <br/>

       <br/>

        <div id="fileSendDiv">

                  <iframe width="100%" height="35" frameborder="0" id="show" name="show" src="uploadfile.jsp" scrolling="no" style="frameborder:0" align="left"></iframe>

       </div>

       <br/>

       <br/>

       <br/>

       <br/>

       <p>

            <b>刷新的是iframe,父页面不会改变</b>

        </p>

    </body>

</html>

该页面注意的是iframe的使用,刷新的会是iframeiframe指向了一个新的文件,文件名叫:uploadfile.jsp,这个才是真正的上传文件的内容表现,你可以将这个文件作为工具类型的文件,只要在上传文件中通过iframe引用这个文件即可(uploadtest.htmluploadfile.jsp处于同一个目录中)。

上传显示文件代码如下:

文件名:uploadfile.jsp

 

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>

    <head>

       <title>上传文件</title>

       <meta http-equiv="Content-Type" content="text/html; charset=utf-8">

       <meta http-equiv="pragma" content="no-cache">

       <meta http-equiv="cache-control" content="no-cache">

       <script language="JavaScript" type="text/javascript">

       function upload()

       {     

           var filename = document.tab.uploadfile.value;

           if (filename=='')

           {

               alert("没有选择要上传的文件,请选择!");

               return;

           }

          

           document.tab.action = "FileUpload";//提交上传为文件时,所指向的servlet配置的Servlet动作

           document.tab.target="show";//指向iframeID,即刷新页面返回时所指的地方。

           document.tab.submit();     

          

       }

    </script>

    </head>

    <body style="margin:0px;">

       <form name="tab" method="post" action="" enctype="multipart/form-data">

           <input type="file" id="uploadfile" name="uploadfile"  style="border:1px solid black;" >

           <input type="button" name="up" value="上传" style="border:1px solid black;height:20px;" onClick="upload()">

       </form>   

    </body>

</html>

需要明确的是该上传文件当调用upload之后,其返回所指向的是IDshow表单,查看uploadtest.html中的iframe发现,指的就是这个iframeID,所以说当后台的Servlet有返回时,刷新的也只是这个iframe,而不会影响整个父页面的显示效果。

 

下面是后台Servlet的源代码:

文件名:UploadFileTest.java

 

package com.uploadtest;

 

import java.io.File;

import java.io.IOException;

import java.io.PrintWriter;

import java.util.Iterator;

import java.util.List;

 

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

 

import org.apache.commons.fileupload.FileItem;

import org.apache.commons.fileupload.disk.DiskFileItemFactory;

import org.apache.commons.fileupload.servlet.ServletFileUpload;

 

public class UploadFileTest extends HttpServlet {

    private static final long   serialVersionUID = 1L;

 

    private static final String CONTENT_TYPE     = "text/html; charset=utf-8";

 

    //Process the HTTP Post request

    public void doPost(HttpServletRequest request, HttpServletResponse response)

            throws ServletException, IOException {

        String path = request.getContextPath();

        //WEB形式的表现地址,示例:http://127.0.0.1:8080/uploadtest/

        String basePath = request.getScheme() + "://" + request.getServerName()

                + ":" + request.getServerPort() + path + "/";

        //获得本地地址,示例如:c://tomcat/webapp/

        String temp = getServletContext().getRealPath("/") + "upload/temp"; //临时目录

        String loadpath = getServletContext().getRealPath("/") + "upload"; //上传文件存放目录

        response.setContentType(CONTENT_TYPE);

        PrintWriter out = response.getWriter();

        try {

            //Create a factory for disk-based file items

            DiskFileItemFactory factory = new DiskFileItemFactory();

            //Set factory constraints设置最多只允许在内存中存储的数据,单位:字节

            factory.setSizeThreshold(4096);

            //设置一旦文件大小超过getSizeThreshold()的值时数据存放在硬盘的目录(缓存)

            factory.setRepository(new File(temp));

            //Create a new file upload handler

            ServletFileUpload upload = new ServletFileUpload(factory);

            // Set overall request size constraint设置允许用户上传文件大小,单位:字节,这里设为5m

            upload.setSizeMax(5 * 1024 * 1024);

            //Parse the request

            List /* FileItem */fileItems = upload.parseRequest(request);

            //开始读取上传信息

            // 依次处理每个上传的文件

            Iterator iter = fileItems.iterator();

            while (iter.hasNext()) {

                FileItem item = (FileItem) iter.next();

                //忽略其他不是文件域的所有表单信息

                if (!item.isFormField()) {

                    String name = item.getName();

                    long size = item.getSize();

                    if ((name == null || name.equals("")) && size == 0)

                        continue;

                    name = name.substring(name.lastIndexOf("\\") + 1);//从全路径中提取文件名

                    //处理中文编码问题,前台是UTF8,所以这里需要对应上,如果前台是gb2312的话,这里也应该是gb2312

                    name = new String(name.getBytes(), "utf-8");

                    try {

                        //保存上传的文件到指定的目录

                        //在下文中上传文件至数据库时,将对这里改写

                        File fNew = new File(loadpath, name);

                        item.write(fNew);

                        //out.print(name + "  " + size + "");

                        response.sendRedirect(basePath + "uploadfile.jsp");//返回刷新页面,即返回iframe

                    }

                    catch (Exception e) {

                        e.printStackTrace();

                        out.println(e);

                    }

                }

            }

        }

        catch (Exception e) {

            e.printStackTrace();

        }

    }

}

具体的调用说明,见源文件中的注释

最后就剩下web.xml的配置了,下面是示例:

<?xml version="1.0" encoding="UTF-8"?>

<web-app version="2.4" xmlns="http://java./xml/ns/j2ee"

    xmlns:xsi="http://www./2001/XMLSchema-instance"

    xsi:schemaLocation="http://java./xml/ns/j2ee

    http://java./xml/ns/j2ee/web-app_2_4.xsd">   

    <display-name>UploadFile</display-name>

    <servlet>

       <description></description>

       <display-name>FileUpload</display-name>

       <servlet-name>FileUpload</servlet-name>

       <servlet-class>

           com.uploadtest.UploadFileTest

       </servlet-class>

    </servlet>

    <servlet-mapping>

       <servlet-name>FileUpload</servlet-name>

       <url-pattern>/FileUpload</url-pattern>

    </servlet-mapping>

</web-app>

好了,一个完整的使用Common-FileUpload的例子就结束了。

最后要提一点,就是这个上传组件中,在解析上传文件时,会读取上传文件的内容的,有时在应用中,比如WEB呼叫中心方面,WEB端上传的文件会被远端的人员接收,但是有时的情况下,远端服务人员并不一定希望接收WEB端发过来的文件,所以即便是远端服务人员拒绝了接收文件,但是这个上传组件却是已经读取了文件的内容至缓存中了,也就是说多做了一步。并且即便是远端服务人员愿意接收文件,它也是有延迟的,过程是先从WEB中接收文件至缓存中,再从缓存中提取数据传至远端的服务人员。估计可以通过改变这个上传组件的源代码,来回避上面所说的问题,不过需要对源代码有一定的研究。

至于用到该上传组件的一些高级功能(如要做一个上传进度条的显示),可以看它提供的User Guide,进行自身功能的定义了,本文只做入门级介绍。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多