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

    文件上传和下载在web应用中非常普遍,要在jsp环境中实现文件上传功能是非常容易的,因为网上有许多用java开发的文件上传组件,本文以commons-fileupload组件为例,为jsp应用添加文件上传功能。common-fileupload组件是apache的一个开源项目之一,可以从http://jakarta.apache.org/commons/fileupload/下载。用该组件可实现一次上传一个或多个文件,并可限制文件大小。

    开发环境

      创建一个javaweb项目,加入common-fileupload组件(commons-fileupload-1.3.1.jar,commons-io-2.4.jar)

      

    文件上传

    文件上传界面,upload.jsp

    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>文件上传</title>
    </head>
    <body>
        <form action="${pageContext.request.contextPath }/upload" 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="提交">
        </form>
    </body>
    </html>

    消息提示界面,message.jsp

    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>消息提示</title>
    </head>
    <body>
        ${message }
    </body>
    </html>

    接受文件上传servlet,UploadServlet.java

      1 package com.servlet;
      2 
      3 import java.io.File;
      4 import java.io.FileOutputStream;
      5 import java.io.IOException;
      6 import java.io.InputStream;
      7 import java.util.HashMap;
      8 import java.util.Iterator;
      9 import java.util.List;
     10 import java.util.UUID;
     11 
     12 import javax.servlet.ServletException;
     13 import javax.servlet.http.HttpServlet;
     14 import javax.servlet.http.HttpServletRequest;
     15 import javax.servlet.http.HttpServletResponse;
     16 
     17 import org.apache.commons.fileupload.FileItem;
     18 import org.apache.commons.fileupload.FileUploadBase.FileSizeLimitExceededException;
     19 import org.apache.commons.fileupload.ProgressListener;
     20 import org.apache.commons.fileupload.disk.DiskFileItemFactory;
     21 import org.apache.commons.fileupload.servlet.ServletFileUpload;
     22 
     23 
     24 public class UploadServlet extends HttpServlet {
     25     private static final long serialVersionUID = 1L;
     26 
     27     
     28     // 定义允许上传的文件扩展名
     29     private String Ext_Name = "gif,jpg,jpeg,png,bmp,swf,flv,mp3,wav,wma,wmv,mid,avi,mpg,asf,rm,rmvb,doc,docx,xls,xlsx,ppt,htm,html,txt,zip,rar,gz,bz2";
     30 
     31     /**
     32      * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
     33      *      response)
     34      */
     35     protected void doGet(HttpServletRequest request, HttpServletResponse response)
     36             throws ServletException, IOException {
     37 
     38 
     39         // 得到上传文件的保存目录,将上传文件存放在WEB-INF目录下,不允许外界直接访问,保证上传文件的安全
     40         String savePath = this.getServletContext().getRealPath("WEB-INF/upload");
     41         File saveFileDir = new File(savePath);
     42         if (!saveFileDir.exists()) {
     43             // 创建临时目录
     44             saveFileDir.mkdirs();
     45         }
     46         
     47         // 上传时生成临时文件保存目录
     48         String tmpPath = this.getServletContext().getRealPath("WEB-INF/tem");
     49         File tmpFile = new File(tmpPath);
     50         if (!tmpFile.exists()) {
     51             // 创建临时目录
     52             tmpFile.mkdirs();
     53         }
     54 
     55         // 消息提示
     56         String message = "";
     57         try {
     58             // 使用Apache文件上传组件处理文件上传步骤:
     59             // 1.创建一个DiskFileItemFactory工厂
     60             DiskFileItemFactory factory = new DiskFileItemFactory();
     61             // 设置工厂的缓冲区的大小,当上传的文件大小超过缓冲区的大小时,就会生成一个临时文件存放到指定的临时目录当中
     62             factory.setSizeThreshold(1024 * 10);// 设置缓冲区的大小为100KB,如果不指定,那么默认缓冲区的大小是10KB
     63             // 设置上传时生成的临时文件的保存目录
     64             factory.setRepository(tmpFile);
     65             // 2.创建一个文件上传解析器
     66             ServletFileUpload upload = new ServletFileUpload(factory);
     67             // 监听文件上传进度
     68             upload.setProgressListener(new ProgressListener() {
     69 
     70                 @Override
     71                 public void update(long readedBytes, long totalBytes, int currentItem) {
     72                     // TODO Auto-generated method stub
     73                     System.out.println("当前已处理:" + readedBytes + "-----------文件大小为:" + totalBytes + "--" + currentItem);
     74                 }
     75             });
     76             // 解决上传文件名的中文乱码问题
     77             upload.setHeaderEncoding("UTF-8");
     78             // 3.判断提交上来的数据是否是上传表单的数据
     79             if (!ServletFileUpload.isMultipartContent(request)) {
     80                 // 按照传统方式获取数据
     81                 return;
     82             }
     83 
     84             // 设置上传单个文件的最大值
     85             upload.setFileSizeMax(1024 * 1024 * 1);// 1M
     86             // 设置上传文件总量的最大值,就是本次上传的所有文件的总和的最大值
     87             upload.setSizeMax(1024 * 1024 * 10);// 10M
     88 
     89             List items = upload.parseRequest(request);
     90             Iterator itr = items.iterator();
     91             while (itr.hasNext()) {
     92                 FileItem item = (FileItem) itr.next();
     93                 // 如果fileitem中封装的是普通的输入想数据
     94                 if (item.isFormField()) {
     95                     String name = item.getFieldName();
     96                     // 解决普通输入项数据中文乱码问题
     97                     String value = item.getString("UTF-8");
     98                     // value = new String(value.getBytes("iso8859-1"),"UTF-8");
     99                     System.out.println(name + "=" + value);
    100                 } else// 如果fileitem中封装的是上传文件
    101                 {
    102                     // 得到上传文件的文件名
    103                     String fileName = item.getName();
    104                     System.out.println("文件名:" + fileName);
    105                     if (fileName == null && fileName.trim().length() == 0) {
    106                         continue;
    107                     }
    108                     // 注意:不同的浏览器提交的文件名是不一样的,有些浏览器提交上来的文件名是带有路径的
    109                     // 如: C:UsersH__DDesktop1.txt 而有些则是 : 1.txt
    110                     // 处理获取到的上传文件的文件名的路径部分,只保留文件名部分
    111                     fileName = fileName.substring(fileName.lastIndexOf("\") + 1);
    112                     
    113                     // 得到上传文件的扩展名
    114                     String fileExt = fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase();
    115                     // 检查扩展名
    116                     // 如果需要限制上传的文件类型,那么可以通过文件的扩展名来判断上传的文件类型是否合法
    117                     System.out.println("上传的文件的扩展名是:" + fileExt);
    118                     if(!Ext_Name.contains(fileExt)){
    119                         System.out.println("上传文件扩展名是不允许的扩展名:" + fileExt);
    120                         message = message + "文件:" + fileName + ",上传文件扩展名是不允许的扩展名:" + fileExt + "<br/>";
    121                         break;
    122                     }
    123 
    124                     // 检查文件大小
    125                     if(item.getSize() == 0) continue;
    126                     if(item.getSize() > 1024 * 1024 * 1){
    127                         System.out.println("上传文件大小:" + item.getSize());
    128                         message = message + "文件:" + fileName + ",上传文件大小超过限制大小:" + upload.getFileSizeMax() + "<br/>";
    129                         break;
    130                     }
    131                     
    132                     
    133                     // 得到存文件的文件名
    134                     String saveFileName = makeFileName(fileName);
    135                     
    136                     //保存文件方法一// 获取item中的上传文件的输入流
    137                     InputStream is = item.getInputStream();
    138                     //创建一个文件输出流
    139                     FileOutputStream out = new FileOutputStream(savePath + "\" + saveFileName);
    140                     //创建一个缓冲区
    141                     byte buffer[] = new byte[1024];
    142                     //判断输入流中的数据是否已经读完的标致
    143                     int len = 0;
    144                     while((len = is.read(buffer)) > 0){
    145                         out.write(buffer, 0, len);
    146                     }
    147                     //关闭输出流
    148                     out.close();
    149                     //关闭输入流
    150                     is.close();
    151                     //删除临时文件
    152                     item.delete();
    153                     
    154                     message = message + "文件:" + fileName + ",上传成功<br/>";
    155                     
    156                     
    157                     //保存文件方法二
    158 //                    File uploadedFile = new File(savePath, saveFileName);
    159 //                    item.write(uploadedFile);
    160                     
    161                 }
    162 
    163             }
    164             
    165         } catch (FileSizeLimitExceededException e) {
    166             message = message + "上传文件大小超过限制<br/>";
    167             e.printStackTrace();
    168         } catch (Exception e) {
    169             // TODO Auto-generated catch block
    170             e.printStackTrace();
    171         } finally {
    172             request.setAttribute("message", message);
    173             request.getRequestDispatcher("/message.jsp").forward(request, response);
    174         }
    175     }
    176 
    177     /**
    178      * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
    179      *      response)
    180      */
    181     protected void doPost(HttpServletRequest request, HttpServletResponse response)
    182             throws ServletException, IOException {
    183         // TODO Auto-generated method stub
    184         doGet(request, response);
    185     }
    186 
    187     private String makeFileName(String fileName) {
    188         // 为防止文件覆盖的现象发生,要为上传文件产生一个唯一的文件名
    189         return UUID.randomUUID().toString().replaceAll("-", "") + "_" + fileName;
    190 
    191     }
    192 
    193 
    194 }

    web.xml配置servlet。web.xml

    <servlet>
            <servlet-name>UploadServlet</servlet-name>
            <servlet-class>com.servlet.UploadServlet</servlet-class>
        </servlet>
    
        <servlet-mapping>
            <servlet-name>UploadServlet</servlet-name>
            <url-pattern>/upload</url-pattern>
        </servlet-mapping>

    文件下载

    浏览文件界面。listFile.jsp

    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>下载文件显示页面</title>
    </head>
    <body>
        <!-- 遍历Map集合 -->
        <c:forEach var="me" items="${fileNameMap}">
            <c:url value="/download" var="downurl">
                <c:param name="filename" value="${me.key}"></c:param>
            </c:url>
             ${me.value}<a href="${downurl}">下载</a>
            <br />
        </c:forEach>
    </body>
    </html>

    查询文件servlet。ListFileServlet.java

     1 package com.servlet;
     2 
     3 import java.io.File;
     4 import java.io.IOException;
     5 import java.util.HashMap;
     6 import java.util.Map;
     7 
     8 import javax.servlet.ServletException;
     9 import javax.servlet.http.HttpServlet;
    10 import javax.servlet.http.HttpServletRequest;
    11 import javax.servlet.http.HttpServletResponse;
    12 
    13 
    14 public class ListFileServlet extends HttpServlet {
    15     private static final long serialVersionUID = 1L;
    16 
    17     /**
    18      * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
    19      *      response)
    20      */
    21     protected void doGet(HttpServletRequest request, HttpServletResponse response)
    22             throws ServletException, IOException {
    23 
    24         // 获取上传文件的目录
    25         String uploadFilePath = this.getServletContext().getRealPath("/WEB-INF/upload");
    26         // 存储要下载的文件名
    27         Map<String, String> fileNameMap = new HashMap<String, String>();
    28         // 递归遍历filepath目录下的所有文件和目录,将文件的文件名存储到map集合中
    29         listFile(new File(uploadFilePath), fileNameMap);// File既可以代表一个文件也可以代表一个目录
    30         // 将Map集合发送到listfile.jsp页面进行显示
    31         request.setAttribute("fileNameMap", fileNameMap);
    32         request.getRequestDispatcher("/listFile.jsp").forward(request, response);
    33 
    34     }
    35 
    36     /**
    37      * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
    38      *      response)
    39      */
    40     protected void doPost(HttpServletRequest request, HttpServletResponse response)
    41             throws ServletException, IOException {
    42         // TODO Auto-generated method stub
    43         doGet(request, response);
    44     }
    45 
    46     /**
    47      * 递归遍历指定目录下的所有文件
    48      * @param file
    49      * @param map
    50      */
    51     public void listFile(File file, Map<String, String> map) {
    52         
    53         if(file == null) return;
    54         
    55         // 如果file代表的不是一个文件,而是一个目录
    56         if (!file.isFile()) {
    57             // 列出该目录下的所有文件和目录
    58             File files[] = file.listFiles();
    59             if(files == null) return;
    60             // 遍历files[]数组
    61             for (File f : files) {
    62                 // 递归
    63                 listFile(f, map);
    64             }
    65         } else {
    66             String realName = file.getName().substring(file.getName().indexOf("_") + 1);
    67             // file.getName()得到的是文件的原始名称,这个名称是唯一的,因此可以作为key,realName是处理过后的名称,有可能会重复
    68             map.put(file.getName(), realName);
    69         }
    70     }
    71 
    72 }

    查询servlet的web.xml配置,web.xml

    <servlet>
    <servlet-name>ListFileServlet</servlet-name>
    <servlet-class>com.servlet.ListFileServlet</servlet-class>
    </servlet>
    
    <servlet-mapping>
    <servlet-name>ListFileServlet</servlet-name>
    <url-pattern>/listFile</url-pattern>
    </servlet-mapping>

    下载servlet,DownloadServlet.java

     1 package com.servlet;
     2 
     3 import java.io.File;
     4 import java.io.FileInputStream;
     5 import java.io.IOException;
     6 import java.io.OutputStream;
     7 import java.net.URLEncoder;
     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 public class DownloadServlet extends HttpServlet {
    15     private static final long serialVersionUID = 1L;
    16 
    17     /**
    18      * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
    19      *      response)
    20      */
    21     protected void doGet(HttpServletRequest request, HttpServletResponse response)
    22             throws ServletException, IOException {
    23 
    24         // 得到要下载的文件名
    25         String fileName = request.getParameter("filename"); // 2323928392489-美人鱼.avi
    26         fileName = new String(fileName.getBytes("iso8859-1"), "UTF-8");
    27         // 上传的文件都是保存在/WEB-INF/upload目录下的子目录当中
    28         String fileSaveRootPath = this.getServletContext().getRealPath("/WEB-INF/upload");
    29         // 得到要下载的文件
    30         File file = new File(fileSaveRootPath + "\" + fileName);
    31         // 如果文件不存在
    32         if (!file.exists()) {
    33             request.setAttribute("message", "您要下载的资源已被删除!!");
    34             request.getRequestDispatcher("/message.jsp").forward(request, response);
    35             return;
    36         }
    37         // 处理文件名
    38         String realname = fileName.substring(fileName.indexOf("_") + 1);
    39         // 设置响应头,控制浏览器下载该文件
    40         response.setHeader("content-disposition", "attachment;filename=" + URLEncoder.encode(realname, "UTF-8"));
    41         // 读取要下载的文件,保存到文件输入流
    42         FileInputStream in = new FileInputStream(fileSaveRootPath + "\" + fileName);
    43         // 创建输出流
    44         OutputStream out = response.getOutputStream();
    45         // 创建缓冲区
    46         byte buffer[] = new byte[1024];
    47         int len = 0;
    48         // 循环将输入流中的内容读取到缓冲区当中
    49         while ((len = in.read(buffer)) > 0) {
    50             // 输出缓冲区的内容到浏览器,实现文件下载
    51             out.write(buffer, 0, len);
    52         }
    53         // 关闭文件输入流
    54         in.close();
    55         // 关闭输出流
    56         out.close();
    57 
    58     }
    59 
    60     /**
    61      * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
    62      *      response)
    63      */
    64     protected void doPost(HttpServletRequest request, HttpServletResponse response)
    65             throws ServletException, IOException {
    66         // TODO Auto-generated method stub
    67         doGet(request, response);
    68     }
    69 
    70     
    71 
    72 }

    下载servlet的web.xml配置,web.xml

    <servlet>
            <servlet-name>DownloadServlet</servlet-name>
            <servlet-class>com.servlet.DownloadServlet</servlet-class>
        </servlet>
    
        <servlet-mapping>
            <servlet-name>DownloadServlet</servlet-name>
            <url-pattern>/download</url-pattern>
        </servlet-mapping>
  • 相关阅读:
    86. Partition List
    328. Odd Even Linked List
    19. Remove Nth Node From End of List(移除倒数第N的结点, 快慢指针)
    24. Swap Nodes in Pairs
    2. Add Two Numbers(2个链表相加)
    92. Reverse Linked List II(链表部分反转)
    109. Convert Sorted List to Binary Search Tree
    138. Copy List with Random Pointer
    为Unity的新版ugui的Prefab生成预览图
    ArcEngine生成矩形缓冲区
  • 原文地址:https://www.cnblogs.com/wdpnodecodes/p/7413015.html
Copyright © 2011-2022 走看看