JavaWeb实现文件下载

1. 编写文件上传Servlet

  1 public class FileUpload1 extends HttpServlet {
  2     @Override
  3     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  4 
  5         InputStream in = null;
  6         OutputStream out = null;
  7 
  8         // 获取上传文件目录
  9         String savePath = this.getServletContext().getRealPath("/WEB-INF/upload");
 10 
 11         try {
 12             // 使用默认配置创建解析器工厂
 13             DiskFileItemFactory factory = new DiskFileItemFactory();
 14             // 获取解析器
 15             ServletFileUpload upload = new ServletFileUpload(factory);
 16             upload.setProgressListener(new ProgressListener() {
 17                 @Override
 18                 public void update(long l, long l1, int i) {
 19                     System.out.println("文件大小为:" + l1 + ",当前已处理:" + l);
 20                 }
 21             });
 22             // 解决上传文件名的中文乱码问题
 23             upload.setHeaderEncoding("UTF-8");
 24             // 上传表单是否为multipart/form-data类型
 25             if (!upload.isMultipartContent(request)) {
 26                 return;
 27             }
 28             // 解析request的输入流
 29             List<FileItem> fileItemList = upload.parseRequest(request);
 30             // 迭代list集合
 31             for (FileItem fileItem : fileItemList) {
 32                 if (fileItem.isFormField()) {
 33                     // 普通字段
 34                     String name = fileItem.getFieldName();
 35                     // 调用getString重载方法, 解决上传数据的中文乱码问题
 36                     String value = fileItem.getString("UTF-8");
 37                     System.out.println(name + "=" + value);
 38                 } else {
 39                     // 上传文件
 40                     // 获取上传文件名
 41                     String fileName = fileItem.getName();
 42                     // input:file没有指定上传文件时, 结束本次循环并继续下一次循环
 43                     if(fileName == null && fileName.trim().equals("")) {
 44                         continue;
 45                     }
 46                     fileName = fileName.substring(fileName.lastIndexOf("\\")+1);
 47                     // 使用UUID作为上传文件的名称
 48                     fileName = makeFileName(fileName);
 49                     // 获取输入流
 50                     in = fileItem.getInputStream();
 51 
 52                     // 上传文件名若不存在, 则先创建
 53                     File savePathDir = new File(savePath);
 54                     if (!savePathDir.exists()) {
 55                         savePathDir.mkdir();
 56                     }
 57 
 58                     // 使用hash算法产生当前上传图片的随机目录
 59                     String currentFileSavePath = makePath(savePath, fileName);
 60 
 61                     // 获取输出流
 62                     out = new FileOutputStream(currentFileSavePath + "\\" + fileName);
 63                     int len = 0;
 64                     byte[] buffer = new byte[1024];
 65                     while((len=in.read(buffer)) > 0) {
 66                         out.write(buffer, 0, len);
 67                     }
 68                 }
 69             }
 70         } catch (Exception e) {
 71             e.printStackTrace();
 72         } finally {
 73             if (in != null) {
 74                 in.close();
 75             }
 76             if (out != null) {
 77                 out.close();
 78             }
 79         }
 80 
 81     }
 82     public String makeFileName(String fileName) {
 83         return UUID.randomUUID().toString() + "_" + fileName;
 84     }
 85     public String makePath(String savePath, String fileName) {
 86         // 根据文件名产生int型hashcode, 32位二进制
 87         int hashcode = fileName.hashCode();
 88         // 获取第4位 0-15
 89         int dir1 = hashcode&0xf;
 90         // 获取第5-8位 0-15
 91         int dir2 = (hashcode&0xf0)>>4;
 92         // 凭借随机目录
 93         String dir = savePath + "\\" + dir1 + "\\" + dir2;  // upload\2\4
 94         // 若目录不存在时, 创建目录
 95         File file = new File(dir);
 96         if(!file.exists()) {
 97             file.mkdirs();
 98         }
 99         return dir;
100     }
101 
102     @Override
103     protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
104         doGet(req, resp);
105     }
106 }

2. 编写获取所有下载文件名称Servlet

 1 /**
 2  * Created by IntelliJ IDEA.
 3  *
 4  * @Auther: ShaoHsiung
 5  * @Date: 2018/8/26 16:26
 6  * @Title:
 7  * @Description: 列出网站所有下载文件
 8  */
 9 public class ListFileServlet extends HttpServlet {
10     @Override
11     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
12 
13         // 获取下载目录路径
14         String filePath = this.getServletContext().getRealPath("/WEB-INF/upload");
15         // 创建存储文件下载路径的Map集合
16         Map filePathMap = new HashMap();
17         // 将下载目录中所有文件名称存储到Map集合中
18         listFile(new File(filePath), filePathMap);
19         // 存储数据后跳转
20         request.setAttribute("map", filePathMap);
21         request.getRequestDispatcher("/listfile.jsp").forward(request, response);
22     }
23 
24     /**
25      * 将下载目录中所有文件名称存储到Map集合中
26      * @param file 下载目录
27      * @param filePathMap Map集合
28      */
29     private void listFile(File file, Map filePathMap) {
30         if(!file.isFile()) {
31             // 文件为目录时
32             File[] files = file.listFiles();
33             for (File f : files) {
34                 // 递归调用
35                 listFile(f, filePathMap);
36             }
37         } else {
38             // 9349249849-88343-8344_阿_凡_达.avi 处理结果为: 阿_凡_达.avi
39             String realName = file.getName().substring(file.getName().indexOf("_")+1);
40             // 9349249849-88343-8344_阿_凡_达.avi -> 阿_凡_达.avi
41             filePathMap.put(file.getName(), realName);
42         }
43     }
44 
45     @Override
46     protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
47         doGet(req, resp);
48     }
49 }

3. 处理文件下载请求Servlet

 1 public class FileDownload extends HttpServlet {
 2     @Override
 3     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
 4 
 5         // 获取下载文件名称的key
 6         String filename = request.getParameter("filename");  //23239283-92489-dfsd_阿凡达.avi
 7         // 解决get请求的中文乱码问题
 8         filename = new String(filename.getBytes("iso8859-1"),"UTF-8");
 9         // 获取下载目录
10         String path = makePath(filename,this.getServletContext().getRealPath("/WEB-INF/upload"));
11         // 获取下载文件
12         File file = new File(path + "\\" + filename);
13         // 下载文件不存在时
14         if(!file.exists()){
15             request.setAttribute("message", "您要下载的资源已被删除!!");
16             request.getRequestDispatcher("/message.jsp").forward(request, response);
17             return;
18         }
19         // 获取下载文件名称 阿凡达.avi
20         String realname = filename.substring(filename.indexOf("_") + 1);
21         // 通知浏览器以下载方式打开, 不同浏览器可能不同
22         response.setHeader("content-disposition", "attachment;filename=" + URLEncoder.encode(realname, "UTF-8"));
23         // 下载文件
24         FileInputStream in = new FileInputStream(path + "\\" + filename);
25         OutputStream out = response.getOutputStream();
26         byte buffer[] = new byte[1024];
27         int len = 0;
28         while((len=in.read(buffer))>0){
29             out.write(buffer, 0, len);
30         }
31         in.close();
32         out.close();
33 
34     }
35 
36     /**
37      * 根据文件名称产生随机目录并将下载路径与随机目录拼接
38      * @param filename 文件名称
39      * @param savePath 下载路径
40      * @return 下载路径与随机目录拼接结果
41      */
42     private String makePath(String filename,String savePath){
43 
44         int hashcode = filename.hashCode();
45         int dir1 = hashcode&0xf;  //0--15
46         int dir2 = (hashcode&0xf0)>>4;  //0-15
47 
48         String dir = savePath + "\\" + dir1 + "\\" + dir2;  //upload\2\3  upload\3\5
49         File file = new File(dir);
50         if(!file.exists()){
51             file.mkdirs();
52         }
53         return dir;
54     }
55 
56     @Override
57     protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
58         doGet(req, resp);
59     }
60 }

4. 配置web.xml

 1 <!-- 文件上传 -->
 2 <servlet>
 3     <servlet-name>FileUpload1</servlet-name>
 4     <servlet-class>fileupload.FileUpload1</servlet-class>
 5 </servlet>
 6 <servlet-mapping>
 7     <servlet-name>FileUpload1</servlet-name>
 8     <url-pattern>/servlet/FileUpload1</url-pattern>
 9 </servlet-mapping>
10 
11 <!--文件下载-->
12 <servlet>
13     <servlet-name>ListFileServlet</servlet-name>
14     <servlet-class>fileupload.ListFileServlet</servlet-class>
15 </servlet>
16 <servlet-mapping>
17     <servlet-name>ListFileServlet</servlet-name>
18     <url-pattern>/servlet/ListFileServlet</url-pattern>
19 </servlet-mapping>
20 <servlet>
21     <servlet-name>FileDownload</servlet-name>
22     <servlet-class>fileupload.FileDownload</servlet-class>
23 </servlet>
24 <servlet-mapping>
25     <servlet-name>FileDownload</servlet-name>
26     <url-pattern>/servlet/FileDownload</url-pattern>
27 </servlet-mapping>

5. 编写获取文件名称JSP

 1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
 2 <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
 3 
 4 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
 5 <html>
 6   <head>
 7     <title>My JSP 'listfile.jsp' starting page</title>
 8   </head>
 9   
10   <body>
11 
12     <c:forEach var="me" items="${map}">
13         <c:url value="/servlet/FileDownload" var="downurl">
14             <c:param name="filename" value="${me.key}"></c:param>
15         </c:url>
16         ${me.value }  <a href="${downurl}">下载</a>  <br/>
17     </c:forEach>
18     
19   </body>
20 </html>

注意:

URL地址栏 -> 非ASCII码字符 -> URL编码
使用c:url传递中文数据

6. 编写文件上传JSP

 1 <%@ page contentType="text/html;charset=UTF-8" language="java" %>
 2 <html>
 3 <head>
 4     <title>演示文件上传</title>
 5 </head>
 6 <body>
 7     <form action="${pageContext.request.contextPath}/servlet/FileUpload1" method="post" enctype="multipart/form-data">
 8         用户名: <input type="text" name="username"/><br/>
 9         文件1: <input type="file" name="file1"/><br/>
10         文件2: <input type="file" name="file1"/><br/>
11         <input type="submit"/>
12     </form>
13 </body>
14 </html>

7. 效果演示

在浏览器中访问http://localhost:8080/servlet/ListFileServlet

 

posted on 2018-08-26 16:57  ert999  阅读(980)  评论(0编辑  收藏  举报

导航