28°

文件上传与下载

第一节 文件上传

1.1 文件上传页面三要素

  • 提供form表单,method必须是post
  • form表单的enctype必须是multipart/form-data
  • 提供 input type="file" 类型输入

1.2 实现文件上传

1.2.1 编写上传页面

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>文件上传</title>
</head>
<body>
    <form action="${pageContext.request.contextPath}/upload" method="post" enctype="multipart/form-data">
        上传用户: <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>

1.2.2 编写文件上传工具类

package com.utils;

import java.io.File; import java.util.Map; import java.util.UUID;

public class UploadUtils { // 根据老的文件名生成新的文件名 public static String createNewFileName(String oldFileName){ // 为防止文件覆盖的现象发生,要为上传文件产生一个唯一的文件名 String uuid = UUID.randomUUID().toString().replace("-", ""); String newFileName = uuid + "_" + oldFileName; return newFileName; }

// 生成存放文件的目录
public static String createNewPath(String basePath, String oldFileName){
    //得到文件名的hashCode的值,得到的就是filename这个字符串对象在内存中的地址
    int hasCode = oldFileName.hashCode();
    int dir1 = hasCode &amp; 0xf;
    int dir2 = (hasCode &amp; 0xf0)&gt;&gt;&gt;4;
    String newPath = basePath + "/" + dir1 + "/" + dir2;
    File dir = new File(newPath);
    if (!dir.exists()){
        dir.mkdirs();
    }
    return newPath;
}

// 遍历文件夹
public static void listFiles(File dir, Map&lt;String, String&gt; map){
    File[] files = dir.listFiles();
    if (files != null){
        for (File file: files){
            if (file.isDirectory()){
                listFiles(file, map);
            }else {
                String uuidFileName = file.getName();
                String fileName = uuidFileName.substring(uuidFileName.indexOf("_") + 1);
                map.put(uuidFileName, fileName);
            }
        }
    }
}

}

1.2.3编写处理代码

package com.web;

import com.utils.UploadUtils;

import javax.servlet.ServletException; import javax.servlet.annotation.MultipartConfig; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.Part; import java.io.File; import java.io.IOException; import java.io.PrintWriter; import java.util.Collection;

@WebServlet(name = "ServletUpload", value = "/upload") @MultipartConfig(maxFileSize = 1024102410, maxRequestSize = 10241024100) public class ServletUpload extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("utf-8"); response.setContentType("text/html;charset=utf-8"); PrintWriter out = response.getWriter(); //1获取request中表单的部分(Part 表单中一部分内容 Collection<Part> parts = request.getParts(); String basePath=this.getServletContext().getRealPath("/WEB-INF/upload"); // System.out.println(basePath); File dir=new File(basePath); if(!dir.exists()){ dir.mkdirs();//创建文件夹 } if(parts!=null){ for (Part part : parts) { //判断是文件项,还是普通项 String submittedFileName = part.getSubmittedFileName(); if(submittedFileName==null){//普通表单元素 //获取用户名 String name = part.getName(); String value = request.getParameter(name); System.out.println(name+":"+value); }else{ // 表单文件项 没有选择文件 文件名称是 ""

                //重新获取名称,submittedFileName有问题(IE ,fireFox)form-data; name="file1"; filename="2.jpeg"
                String dis= part.getHeader("Content-Disposition");
                String realFileName=dis.substring(dis.lastIndexOf("filename=")+10,dis.length()-1);
                realFileName=realFileName.substring(realFileName.lastIndexOf("\\")+1);
                if(submittedFileName==""){
                    continue;//继续处理下一个
                }
                String newFileName = UploadUtils.createNewFileName(realFileName);
                String newPath = UploadUtils.createNewPath(basePath, realFileName);


                part.write(newPath+"/"+newFileName);
                //缓存文件
                part.delete();//
                //响应内容
                out.write("&lt;h3&gt;上传成功:&lt;/h3&gt;"+realFileName+"&lt;br/&gt;");
            }
        }
    }


}

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    doPost(request, response);
}

}

1.3文件上传需要注意的细节

  1. 为保证服务器安全, 上传文件应该放在外界无法直接访问的目录下,比如放于WEB-INF目录下
  2. 为防止文件覆盖的现象发生, 要为上传文件产生一个唯一的文件名。
  3. 为防止一个目录下面出现太多文件, 要使用hash算法打散存储。
  4. 要限制上传文件的最大值。
  5. 要限制上传文件的类型, 在收到上传文件名时, 判断后缀名是否合法。

第二节 文件上传

我们要将Web应用系统中的文件资源提供给用户进行下载, 首先我们要有一个页面列出上传文件目录下的所有文件, 当用户点击文件下载超链接时就进行下载操作, 编写一个ServletListFiles, 用于列出Web应用系统中所有下载文件

2.1 获取文件列表

2.1.1展示文件列表的界面

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>文件下载</title>
</head>
<body>
    <h1>下载列表</h1>
    <c:forEach items="${maps}" var="entry">
        ${entry.value}----><a href="${pageContext.request.contextPath}/download?filename=${entry.key}">下载</a><br>
    </c:forEach>
</body>
</html>

2.1.2 编写展示页面的处理代码

package com.web;

import com.utils.UploadUtils;

import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.File; import java.io.IOException; import java.util.HashMap; import java.util.Map;

@WebServlet(name = "ServletListFiles", value = "/list") public class ServletListFiles extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { Map<String, String> maps = new HashMap<>(); String basePath = this.getServletContext().getRealPath("/WEB-INF/upload"); System.out.println(basePath); UploadUtils.listFiles(new File(basePath), maps); request.setAttribute("maps", maps); for (Map.Entry<String, String> entry : maps.entrySet()) { System.out.println(entry.getKey() + ":" + entry.getValue()); } request.getRequestDispatcher("/list.jsp").forward(request, response); }

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    doPost(request, response);
}

}

2.2 编写处理文件下载的代码

package com.web;

import com.utils.UploadUtils;

import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.net.URLEncoder;

@WebServlet(name = "ServletDownload", value = "/download") public class ServletDownload extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("utf-8"); String uuidFileName = request.getParameter("filename"); String basePath = this.getServletContext().getRealPath("/WEB-INF/upload"); if (uuidFileName!=null&&uuidFileName.trim().length()!=0){ //文件名 String filename = uuidFileName.substring(uuidFileName.indexOf("_") + 1); String newPath = UploadUtils.createNewPath(basePath, filename); File file = new File(newPath + "/" + uuidFileName); if (file.exists()){ ServletOutputStream os = response.getOutputStream(); response.setHeader("content-disposition", "attachment;filename="+ URLEncoder.encode(filename, "utf-8")); FileInputStream fis = new FileInputStream(file); byte[] buf = new byte[1024*4]; int len = -1; while ((len=fis.read(buf))!=-1){ os.write(buf, 0, len); } }else { response.setContentType("text/html;charset=utf-8"); response.getWriter().write("文件已经删除了"); } } }

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    doPost(request, response);
}

}

本文由【JacksonMike】发布于开源中国,原文链接:https://my.oschina.net/jacksonmike/blog/3136342

全部评论: 0

    我有话说: