文件上传与下载----上传

实现web开发中的文件上传功能,需完成如下二步操作:

    1、在web页面中添加上传输入项。
   2、在servlet中读取上传文件的数据,并保存到本地硬盘中。
      在web页面中添加上传输入项:
              <input type=“file”>标签用于在web页面中添加文件上传输入项(就会有一个浏览按钮),设置文件上传输入项时须注意:
            1、 必须要设置input输入项的name属性,否则浏览器将不会发送上传文件的数据。
            2、必须把form的enctype属值设为multipart/form-data.设置该值后,浏览器在上传文件时,将把文件数据附带在http请求消息
                    体中,并使用MIME协议对上传的文件进行描述,以方便接收方对上传数据进行解析和处理。
            FORM的enctype属值multipart/form-data与application/x-www-form-urlencoded的区别 :

                        FORM元素的enctype属性指定了表单数据向服务器提交时所采用的编码类型,默认的缺省值是“application/x-www-form-

                    urlencoded”。 然而,在向服务器发送大量的文本、包含非ASCII字符的文本或二进制数据时这种编码方式效率很低。

                    件上载时,所使用的编码类型应当是“multipart/form-data”,它既可以发送文本数据,也支持二进制数据上载。Browser

                    端<form>表单的ENCTYPE属性值为multipart/form-data,它告诉我们传输的数据要用到多媒体传输协议,由于多媒体传

                    输的都是大量的数据,所以规定上传文件必须是post方法,<input>的type属性必须是file。

        在Servlet中读取文件上传数据,并保存到本地硬盘中:            
             使用Commons-fileupload组件实现文件上传,需要导入该组件相应的支撑jar包:Commons-fileupload和commons-io。
             commons-io 不属于文件上传组件的开发jar文件,但Commons-fileupload 组件从1.1 版本开始,它工作时需要commons-io包
             的支持。
        为什么不用getInputStream方法的原因:
             Request对象提供了一个getInputStream方法,通过这个方法可以读取到客户端提交过来的数据。但由于用户可能会同时上传
             多个文件,在servlet端编程直接读取上传数据,并分别解析出相应的文件数据是一项非常麻烦的工作。为方便用户处理文件
             上传数据,Apache 开源组织提供了一个用来处理表单文件上传的一个开源组件( Commons-fileupload ),该组件性能优
             异,并且其API使用极其简单,可以让开发人员轻松实现web文件上传功能,因此在web开发中实现文件上传功能,通常使用
             Commons-fileupload组件实现。
核心API—ServletFileUpload
       DiskFileItemFactory 是创建 FileItem 对象的工厂,这个工厂类常用方法:
             public void setSizeThreshold(int sizeThreshold)
             设置内存缓冲区的大小,默认值为10K。当上传文件大于缓冲区大小时, fileupload组件将使用临时文件缓存上传文件。
             public void setRepository(java.io.File repository)
             指定临时文件目录,默认值为System.getProperty("java.io.tmpdir").
             public DiskFileItemFactory(int sizeThreshold, java.io.File repository)
             构造函数       
       ServletFileUpload 负责处理上传的文件数据,并将表单中每个输入项封装成一个 FileItem 对象中。常用方法有:
             boolean isMultipartContent(HttpServletRequest request)
             判断上传表单是否为multipart/form-data类型
             List parseRequest(HttpServletRequest request)
             解析request对象,并把表单中的每一个输入项包装成一个fileItem 对象,并返回一个保存了所有FileItem的list集合。
             setFileSizeMax(long fileSizeMax)
             设置上传文件的最大值
             setSizeMax(long sizeMax)
             设置上传文件总量的最大值
             setHeaderEncoding(java.lang.String encoding)
             设置编码格式
             setProgressListener(ProgressListener pListener)
             获取进度监视器ProgressListener 对象

上传文件中应当注意的细节:

         1上传中文文件的乱码问题:
             文件名中文乱码问题,可调用ServletUpLoader的setHeaderEncoding方法,或者设置request的setCharacterEncoding属性
             l临时文件的删除问题
             由于文件大小超出DiskFileItemFactory.setSizeThreshold方法设置的内存缓冲区的大小时,Commons-fileupload组件将使用临
             时文件保存上传数据,因此在程序结束时,务必调用FileItem.delete方法删除临时文件。
             Delete方法的调用必须位于流关闭之后,否则会出现文件占用,而导致删除失败的情况。
       2上传的普通输入项的乱码问题:

                手工转码,用户名的乱码问题:

                paramValue= new String(paramValue.getBytes("iso8859-1"),"utf-8");

                利用FileItem类的getString(String encoding)

                 String getString(String encoding)  throws   UnsupportedEncodingException

       3、 文件存放位置问题:
             为保证服务器安全,上传文件应保存在应用程序的WEB-INF目录下,或者不受WEB服务器管理的目录。
             为防止多用户上传相同文件名的文件,而导致文件覆盖的情况发生,文件上传程序应保证上传文件具有唯一文件名。
             为防止单个目录下文件过多,影响文件读写速度,处理上传文件的程序应根据可能的文件上传总量,选择合适的目录
             结构生成算法,将上传文件分散存储。

             如表示url资源时应该用斜杠 “/”

             如表示硬盘路径时用斜杠“\\”

       4、 临时文件的删除问题
             代码必须放在流关闭语句的最后面,因为正在使用的文件是不能删除的
             DiskFileItemFactory  factory = new DiskFileItemFactory();

             factory.setRepository(new File(this.getServletContext().getRealPath("/temp")));

                       ……

             FileItem item;

                       ……

             item.delete();

      5、 限制文件上传的最大值问题:

             调用解析器的:upload.setFileSizeMax(1024*1024);  //上传文件不能超过1M。如果超出大小,需要给用户友好提示:

                try{

                        ……

                    }catch (FileUploadBase.FileSizeLimitExceededException e) {

                             request.setAttribute("message", "上传文件不能超过1M!!");

                    }

       6、 ProgressListener 显示上传进度问题:    

                    ProgressListener progressListener = new ProgressListener() {

                               public void update(long pBytesRead, long pContentLength, int pItems) {

                                       System.out.println("到现在为止,  " + pBytesRead + " 字节已上传,总大小为 "  + pContentLength);

                               }

                     };

                     upload.setProgressListener(progressListener);
 
实现代码:
       upload.jsp  

                <form action="${pageContext.request.contextPath}/servlet/UploadServlet2" enctype="multipart/form-data" method="post">

                             用户名:<input type="text" name="username" /><br/>

                             文件1<input type="file" name="file1" /><br/>

                             文件2<input type="file" name="file2" /><br/>

                            <input type="submit" value="上传" /><br/>

                </form>

       UploadServlet.java

            package cn.class3g.web.servlet;

            import java.io.File;
            import java.io.FileOutputStream;
            import java.io.IOException;
            import java.io.InputStream;
            import java.io.PrintWriter;
            import java.util.List;
            import java.util.UUID;

            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.FileUploadBase.FileSizeLimitExceededException;
            import org.apache.commons.fileupload.FileUploadException;
            import org.apache.commons.fileupload.disk.DiskFileItemFactory;
            import org.apache.commons.fileupload.servlet.ServletFileUpload;

            public class UploadServlet2 extends HttpServlet {

                    public void doGet(HttpServletRequest request, HttpServletResponse response)  throws ServletException, IOException {
                             doPost(request,response);
                     }
                   public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  
                           // request.setCharacterEncoding("UTF-8");

                         try {
                              // 1、建立工厂对象
                                  DiskFileItemFactory factory = new DiskFileItemFactory();
                              //factory.setRepository(new File("F:\\"));
   
                              // 2、得到上传文件解析器
                                  ServletFileUpload upload = new ServletFileUpload(factory);
                                  upload.setHeaderEncoding("utf-8");//处理上传文件
 
                              // 3、设定上传文件尺寸
                                   upload.setFileSizeMax(1024*1024);
           
                              // 4、进行解析,得到fileItem对象
                                 List<FileItem> list = upload.parseRequest(request);

                             // 5、对list进行迭代处理
                                 for (FileItem item : list) {
                                     if (item.isFormField()) {// 表单普通输入项

                                           String paramName = item.getFieldName();
                                        //String paramValue = item.getString();

                                       //paramValue = new String(paramValue.getBytes("ISO8859-1"),"UTF-8");
                                         String paramValue=item.getString("utf-8");
                                         System.out.println("普通输入项" + paramName + "==" + paramValue);

                                     } else {// 上传文件处理
                                       //获取上传文件名
                                         String fileName = item.getName();
                                       // 如果文件xxx中有目录,则去掉目录部分只保留文件名
                                         fileName = fileName.substring(fileName.lastIndexOf("\\") + 1);
                                               System.out.println("name =" + fileName);
     
                                       if (!fileName.equals(" ")) {
      
                                               fileName =refactorFileName(fileName) ;
                                               System.out.println("filename = " + fileName);

                                               InputStream in = item.getInputStream();
                                               File file = new File("F:\\" + fileName);
                                               FileOutputStream fos = new FileOutputStream(file);

                                               byte[] buffer = new byte[1024];
                                               int len = 0;
                                        while ((len - in.read(buffer)) > 0) {
                                                    fos.write(buffer, 0, len);
                                         }

                                        fos.flush();
                                        fos.close();
                                        in.close();
                                        item.delete();
  
                                               request.setAttribute("message", "文件上传成功");

                                        }
                                      }
                                   }

                                 }catch(FileSizeLimitExceededException e1){
                                                e1.printStackTrace();
                                    request.setAttribute("message", "上传文件尺寸太大!!!");
                                 }catch (FileUploadException e) {
                                               e.printStackTrace();
                                    request.setAttribute("message", "文件上传失败!!!");
                                 }
                                     request.getRequestDispatcher("/message.jsp").forward(request, response);  
                                 }
 
              public String refactorFileName(String fileName){
                      return UUID.randomUUID().toString() + "_" + fileName;  
              }

        }

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值