zoukankan      html  css  js  c++  java
  • 文件上传和下载

    一、文件上传需要注意的事情

    1、必须要设置input输入项的name属性,否则浏览器将不会发送上传文件的数据。

    2、必须把form的enctype属值设为multipart/form-data.设置该值后,浏览器在上传文件时,将把文件数据附带在http请求消息体中,并使用MIME协议对上传的文件进行描述,以方便接收方对上传数据进行解析和处理。

     

     

    二、传统的方式获取表单提交的数据

     

     

     1     public void doGet(HttpServletRequest request, HttpServletResponse response)
     2             throws ServletException, IOException {
     3         String name = request.getParameter("username");
     4         
     5 /*        //null  当enctype="multipart/form-data" 不能用传统的方式获取数据
     6         System.out.println(name);
     7         */
     8         
     9         InputStream in = request.getInputStream();
    10         int len = 0;
    11         byte buffer[] = new byte[1024];
    12         while((len=in.read(buffer))>0){
    13             System.out.println(new String(buffer,0,len));
    14         }
    15         
    16         /*------WebKitFormBoundary6hYLK68ivBSHvVww
    17         Content-Disposition: form-data; name="username"
    18 
    19         name
    20         ------WebKitFormBoundary6hYLK68ivBSHvVww
    21         Content-Disposition: form-data; name="file1"; filename="aa.txt"
    22         Content-Type: text/plain
    23 
    24         bbbbbb
    25         ------WebKitFormBoundary6hYLK68ivBSHvVww
    26         Content-Disposition: form-data; name="file2"; filename="bb.txt"
    27         Content-Type: text/plain
    28 
    29         bbbb
    30         ------WebKitFormBoundary6hYLK68ivBSHvVww--*/
    31         
    32         //由此可见, 当enctype="multipart/form-data" 用传统的方式无法解析
    33     }
    34     
    35     public void doPost(HttpServletRequest request, HttpServletResponse response)
    36             throws ServletException, IOException {
    37         doGet(request, response);
    38     }
    39 
    40 }

     

     

     

    三、Commons-fileupload组件实现文件上传

    fileupload工作流程图:

     

    Commons-fileupload依赖的jar包:Commons-fileupload和commons-io

     

     

     1 //处理上传数据
     2 public class UploadServlet1 extends HttpServlet {
     3 
     4     public void doGet(HttpServletRequest request, HttpServletResponse response)
     5             throws ServletException, IOException {
     6         try{
     7             //创建工厂对象
     8             DiskFileItemFactory factory = new DiskFileItemFactory();
     9             ServletFileUpload upload = new ServletFileUpload(factory);
    10             //解析
    11             List<FileItem>list = upload.parseRequest(request);
    12             for(FileItem item : list){
    13                 if(item.isFormField()){//普通输入项
    14                     String inputName = item.getFieldName();
    15                     String inputValue = item.getString();
    16                     System.out.println(inputName+"="+inputValue);
    17                 }else{
    18                     //代表item封装的是上传文件
    19                     String fileName = item.getName().substring(item.getName().lastIndexOf("\")+1);
    20                     InputStream in = item.getInputStream();
    21                     FileOutputStream out = new FileOutputStream("d:\"+fileName);
    22                     int len = 0;
    23                     byte buffer[] = new byte[1024];
    24                     while((len=in.read(buffer))>0){
    25                         out.write(buffer,0, len);
    26                     }
    27                     in.close();
    28                     out.close();
    29                 }
    30             }
    31             
    32         }catch(Exception e){
    33             throw new RuntimeException();
    34         }
    35     }
    36         
    37     
    38     public void doPost(HttpServletRequest request, HttpServletResponse response)
    39             throws ServletException, IOException {
    40         doGet(request, response);
    41     }
    42 
    43 }

     

     

    四、文件上传需要注意的问题

    1、上传文件的中文乱码

    解决上传文件的乱码

    DiskFileItemFactory factory = new DiskFileItemFactory();
    ServletFileUpload upload = new ServletFileUpload(factory);
    upload.setHeaderEncoding("UTF-8");

     

     

    解决普通输入项的乱码(注意,表单类型为multipart/form-data的时候,设置request的编码是无效的

    String inputValue = item.getString("UTF-8");或

    String inputValue = item.getString();
    inputValue = new String(inputValue.getBytes("iso8859-1"), "UTF-8");

     

     

    2、处理表单时先判断表单的类型

     

    1             if(!upload.isMultipartContent(request)){//表单不是multipart/form-data类型按传统方式获取数据
    2                 String username = request.getParameter("username");
    3                 return;
    4             }

     

     

     

     

    3、设置解析器缓冲区的大小,以及临时文件的删除

    //创建工厂对象
    DiskFileItemFactory factory = new DiskFileItemFactory();

    //设置缓冲区大小
    factory.setSizeThreshold(1024*1024);

    //设置临时目录
    factory.setRepository(new File(this.getServletContext().getRealPath("/temp")));

     

    临时文件的删除:在程序中处理完上传文件后,一定要记得调用item.delete()方法,以删除临时文件,而且是在流关闭后再删除

    in.close();
    out.close();

    //删除临时文件目录
    item.delete();

     

     

    4、在做上传系统时,千万要注意上传文件的保存目录,这个上传文件的保存目录绝对不能让外界直接访问到。应该放在WEB-INF目录下

     

     

    5、限制上传文件的类型

    List types = Arrays.asList("jpg","gif","avi","txt");

     

    String ext = filename.substring(filename.lastIndexOf(".")+1);
    if(!types.contains(ext)){
    request.setAttribute("message", "本系统不支持" + ext + "这种类型");
    request.getRequestDispatcher("/message.jsp").forward(request, response);
    return;
    }

     

      

    6、限制上传文件的大小

    upload.setFileSizeMax(1024*1024*5);

    调用解析器的setFileSizeMax(1024*1024*5);就可以限制上传文件的大小,如果上传文件超出限制,则解析器会抛FileUploadBase.FileSizeLimitExceededException异常,程序员通过是否抓到这个异常,进而就可以给用户友好提示。

     

    7、判断空的上传输入项

    String fileName = item.getName().substring(item.getName().lastIndexOf("\")+1);

    if(fileName==null || fileName.trim().equals("")){
    continue;
    }

     

    8、为避免上传文件的覆盖,程序在保存上传文件时,要为每一个文件生成一个唯一的文件名

    public static String generateFileName(String fileName){
    return UUID.randomUUID()+"_"+fileName;
    }

     

    9、为避免在一个文件夹下面保存超过1000个文件,影响文件访问性能,程序应该把上传文件打散后存储。

     1     public String generateSavePath(String path,String filename){
     2         int hashcode = filename.hashCode();  //121221
     3         int dir1 = hashcode&15;
     4         int dir2 = (hashcode>>4)&0xf;
     5         
     6         String savepath = path + File.separator + dir1 + File.separator + dir2;
     7         File file = new File(savepath);
     8         if(!file.exists()){
     9             file.mkdirs();
    10         }
    11         return savepath;
    12     }

     

     

     10、监听上传进度

    1     ServletFileUpload upload = new ServletFileUpload(factory);
    2             upload.setProgressListener(new ProgressListener(){
    3                 public void update(long pBytesRead, long pContentLength, int pItems) {
    4                     System.out.println("当前已解析:" + pBytesRead);
    5                 }
    6             });

     

     

     

      1 import java.io.File;
      2 import java.io.FileOutputStream;
      3 import java.io.IOException;
      4 import java.io.InputStream;
      5 import java.util.Arrays;
      6 import java.util.List;
      7 import java.util.UUID;
      8 
      9 import javax.servlet.ServletException;
     10 import javax.servlet.http.HttpServlet;
     11 import javax.servlet.http.HttpServletRequest;
     12 import javax.servlet.http.HttpServletResponse;
     13 
     14 import org.apache.commons.fileupload.FileItem;
     15 import org.apache.commons.fileupload.FileUploadBase;
     16 import org.apache.commons.fileupload.ProgressListener;
     17 import org.apache.commons.fileupload.disk.DiskFileItemFactory;
     18 import org.apache.commons.fileupload.servlet.ServletFileUpload;
     19 
     20 public class UploadServlet extends HttpServlet {
     21 
     22     public void doGet(HttpServletRequest request, HttpServletResponse response)
     23             throws ServletException, IOException {
     24         
     25         List types = Arrays.asList("jpg","gif","avi","txt");
     26         
     27         try{
     28             DiskFileItemFactory factory = new DiskFileItemFactory();  //10k
     29             factory.setSizeThreshold(1024*1024);
     30             factory.setRepository(new File(this.getServletContext().getRealPath("/temp")));
     31             
     32             ServletFileUpload upload = new ServletFileUpload(factory);
     33             upload.setProgressListener(new ProgressListener(){
     34                 public void update(long pBytesRead, long pContentLength, int pItems) {
     35                     System.out.println("当前已解析:" + pBytesRead);
     36                 }
     37             });
     38             
     39             upload.setFileSizeMax(1024*1024*5);
     40             if(!upload.isMultipartContent(request)){
     41                 //按照传统方式获取表单数据
     42                 request.getParameter("username");
     43                 return;
     44             }
     45             upload.setHeaderEncoding("UTF-8");
     46             List<FileItem> list = upload.parseRequest(request);
     47             
     48             for(FileItem item : list){
     49                 if(item.isFormField()){
     50                     //为普通输入项
     51                     String inputName = item.getFieldName();
     52                     String inputValue = item.getString("UTF-8");
     53                     //inputValue = new String(inputValue.getBytes("iso8859-1"),"UTF-8");
     54                     System.out.println(inputName + "="  + inputValue);
     55                 }else{
     56                     String filename = item.getName().substring(item.getName().lastIndexOf("\")+1);  //""
     57                     if(filename==null || filename.trim().equals("")){
     58                         continue;
     59                     }
     60                     
     61                     /*String ext = filename.substring(filename.lastIndexOf(".")+1);
     62                     if(!types.contains(ext)){
     63                         request.setAttribute("message", "本系统不支持" + ext + "这种类型");
     64                         request.getRequestDispatcher("/message.jsp").forward(request, response);
     65                         return;
     66                     }*/
     67                     InputStream in = item.getInputStream();
     68                     int len = 0;
     69                     byte buffer[] = new byte[1024];
     70                     String saveFileName = generateFileName(filename);
     71                     String savepath = generateSavePath(this.getServletContext().getRealPath("/WEB-INF/upload"),saveFileName);
     72                     FileOutputStream out = new FileOutputStream(savepath + File.separator + saveFileName);
     73                     while((len=in.read(buffer))>0){
     74                         out.write(buffer, 0, len);
     75                     }
     76                     in.close();
     77                     out.close();
     78                     item.delete();  //删除临时文件
     79                 }
     80             }
     81         }catch (FileUploadBase.FileSizeLimitExceededException e) {
     82             request.setAttribute("message", "文件大小不能超过5m");
     83             request.getRequestDispatcher("/message.jsp").forward(request, response);
     84             return;
     85         }catch (Exception e) {
     86             throw new RuntimeException(e);
     87         }
     88         request.setAttribute("message", "上传成功!!");
     89         request.getRequestDispatcher("/message.jsp").forward(request, response);
     90     }
     91     
     92     //
     93     public String generateSavePath(String path,String filename){
     94         int hashcode = filename.hashCode();  //121221
     95         int dir1 = hashcode&15;
     96         int dir2 = (hashcode>>4)&0xf;
     97         
     98         String savepath = path + File.separator + dir1 + File.separator + dir2;
     99         File file = new File(savepath);
    100         if(!file.exists()){
    101             file.mkdirs();
    102         }
    103         return savepath;
    104     }
    105     
    106     public String generateFileName(String filename){
    107         //83434-83u483-934934
    108         return UUID.randomUUID().toString() + "_" + filename;
    109     }
    110 
    111     public void doPost(HttpServletRequest request, HttpServletResponse response)
    112             throws ServletException, IOException {
    113         doGet(request, response);
    114     }
    115 
    116 }

     

     三、在web页面动态添加输入项

     1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
     2 
     3 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
     4 <html>
     5   <head>
     6     <title>My JSP 'upload2.jsp' starting page</title>
     7   </head>
     8   
     9   <script type="text/javascript">
    10           function addfile(){
    11               var files = document.getElementById("files");
    12               
    13               var input = document.createElement("input");
    14               input.type='file';
    15               input.name='file';
    16               
    17               var btn = document.createElement("input");
    18               btn.type = 'button';
    19               btn.value = '删除';
    20               btn.onclick = function del(){
    21                   this.parentNode.parentNode.removeChild(this.parentNode);
    22               }
    23               
    24               var div = document.createElement("div");
    25               div.appendChild(input);
    26               div.appendChild(btn);
    27               
    28               files.appendChild(div);
    29           }
    30       
    31   </script>
    32   
    33   <body>
    34     
    35     <form action="/day18/servlet/UploadServlet3" enctype="multipart/form-data" method="post">
    36     
    37     <table>
    38         <tr>
    39             <td>上传用户</td>
    40             <td>
    41                 <input type="text" name="username">
    42             </td>
    43         </tr>
    44         
    45         <tr>
    46             <td>上传文件</td>
    47             <td>
    48                 <input type="button" value="添加上传文件" onclick="addfile()">
    49             </td>
    50         </tr>
    51         
    52         <tr>
    53             <td></td>
    54             <td>
    55                 <div id="files"></div>
    56             </td>
    57         </tr>
    58         
    59         <tr>
    60             <td></td>
    61             <td>
    62                 <input type="submit" value="上传">
    63             </td>
    64         </tr>
    65     
    66     </table>
    67     </form>
    68     
    69     
    70   </body>
    71 </html>
  • 相关阅读:
    封装异常处理之坑
    30multipart/form-data和application/x-www-form-urlencoded的区别(二)urlencoded之自动deocde
    使用MAT时的Shallow Size和 Retained Size的区别
    当动态代理遇到ioc
    线程池的原理
    synchroned原理与对象头(yet)
    mysql压力测试与qps监控
    一种mysql jvm死锁
    Android Jni变量对照表
    结构体中使用函数指针
  • 原文地址:https://www.cnblogs.com/niuchuangfeng/p/9185289.html
Copyright © 2011-2022 走看看