文件上传和下载的新理解

几个技术要点。

1,hashcode打散,上传和下载都要同一个算法

2,路径问题,上传的是到服务器那里,

this.getServletContext().getRealPath("WEB-INF/upload");

this.getServletContext().getRealPath("/");//去到他的项目路径下D: omcat7apache-tomcat-7.0.75me-webapps ewBlob

3,文件名同名的问题,加上UUID_,后面用lastIndexOf()截取

4,上传的文件不是放在数据库,而且处理方式放在了servlet而不是jsp

上传

package test;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
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.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

public class UploadHandleServlet extends HttpServlet {
    /**
     * Constructor of the object.
     */
    public UploadHandleServlet() {
        super();
    }

    /**
     * Destruction of the servlet. <br>
     */
    public void destroy() {
        super.destroy(); // Just puts "destroy" string in log
        // Put your code here
    }

    /**
     * The doGet method of the servlet. <br>
     *
     * This method is called when a form has its tag value method equals to get.
     * 
     * @param request
     *            the request send by the client to the server
     * @param response
     *            the response send by the server to the client
     * @throws ServletException
     *             if an error occurred
     * @throws IOException
     *             if an error occurred
     */
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        String savePath = this.getServletContext()
                .getRealPath("WEB-INF/upload");
        String tempPath = this.getServletContext()
                .getRealPath("WEB-INF/upload");
        File tempFile = new File(tempPath);
        if (!tempFile.exists()) {
            System.out.println("文件目录不存在");
            tempFile.mkdir();
        }
        String message = "";
        try {
            // 1,创建一个DiskFileItemFactory工厂
            DiskFileItemFactory factory = new DiskFileItemFactory();
            // 设置上传时临时文件夹
            factory.setRepository(tempFile);
            // 2,创建一个文件上传解析器upload
            ServletFileUpload upload = new ServletFileUpload(factory);
            // 解决文件名中文的乱码
            upload.setHeaderEncoding("UTF-8");
            // 3,判断交上来的数据是否上传表单的数据(靠form的enctype="multipart/form-data"来判断
            if (!ServletFileUpload.isMultipartContent(request)) {
                // 如果是普通的表单
                return;
            }
            List<FileItem> list = upload.parseRequest(request);
            for (FileItem item : list) {
                if (item.isFormField()) {// 不是文件类型的<input type...>
                    String name = item.getFieldName();
                    String value = item.getString("UTF-8");
                    System.out.println(name + "=" + value);
                } else {// 如果fileitem中封装的是上传的文件
                    // String filename = item.getFieldName();不能这样用
                    String filename = item.getName();
                    if (filename == null || filename.trim().equals("")) {
                        // 如果没有的话就跳过
                        continue;
                    }
                    // 处理获取到上传文件名的路径部分,只保留文件名
                    filename = filename
                            .substring(filename.lastIndexOf("\") + 1);
                    // 获得输入流
                    InputStream in = item.getInputStream();
                    // 防止文件同名覆盖
                    String saveFilename = makeFileName(filename);
                    // 获得保存目录
                    String realSavePath = makePath(saveFilename, savePath);
                    FileOutputStream out = new FileOutputStream(realSavePath
                            + "\" + saveFilename);
                    System.out.println(realSavePath + "\" + saveFilename);
                    byte[] buffer = new byte[1024];
                    int len = 0;
                    for (; (len = in.read(buffer)) > 0;) {
                        out.write(buffer, 0, len);
                    }
                    in.close();
                    out.close();
                    item.delete();
                    message = "文件上传成功";
                }
            }
        } catch (Exception e) {
            message = "文件上传失败";
            e.printStackTrace();
        }
        request.setAttribute("message", message);
        request.getRequestDispatcher("/message.jsp").forward(request, response);
    }

    /**
     * The doPost method of the servlet. <br>
     *
     * This method is called when a form has its tag value method equals to
     * post.
     * 
     * @param request
     *            the request send by the client to the server
     * @param response
     *            the response send by the server to the client
     * @throws ServletException
     *             if an error occurred
     * @throws IOException
     *             if an error occurred
     */
    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }

    /**
     * Initialization of the servlet. <br>
     *
     * @throws ServletException
     *             if an error occurs
     */
    public void init() throws ServletException {
        // Put your code here
    }

    public String makeFileName(String filename) {
        // 防止同名文件
        return UUID.randomUUID().toString() + "_" + filename;
    }

    public String makePath(String filename, String savePath) {
        int hashcode = filename.hashCode();
        int dir1 = hashcode & 0x5;// 有5个文件
        // int dir2 = (hashcode & 0x50) >> 4;//这里我递归一次就好了
        String dir = savePath + "\" + dir1;
        File file = new File(dir);
        if (!file.exists()) {
            file.mkdirs();
        }
        return dir;
    }
}

列表的显示

package test;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class ListFileServlet extends HttpServlet {

    /**
     * Constructor of the object.
     */
    public ListFileServlet() {
        super();
    }

    /**
     * Destruction of the servlet. <br>
     */
    public void destroy() {
        super.destroy(); // Just puts "destroy" string in log
        // Put your code here
    }

    /**
     * The doGet method of the servlet. <br>
     *
     * This method is called when a form has its tag value method equals to get.
     * 
     * @param request
     *            the request send by the client to the server
     * @param response
     *            the response send by the server to the client
     * @throws ServletException
     *             if an error occurred
     * @throws IOException
     *             if an error occurred
     */
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        String uploadFilePath = this.getServletContext().getRealPath(
                "WEB-INF/upload");// 获得文件路径
        // 创建一个map
        Map<String, String> fileNameMap = new HashMap<String, String>();
        // 函数会把他真正的名字换给他(去掉UUID_
        listfile(new File(uploadFilePath), fileNameMap);
        // 传到request
        request.setAttribute("fileNameMap", fileNameMap);
        // 转向
        request.getRequestDispatcher("/listfile.jsp")
                .forward(request, response);
    }

    /**
     * The doPost method of the servlet. <br>
     *
     * This method is called when a form has its tag value method equals to
     * post.
     * 
     * @param request
     *            the request send by the client to the server
     * @param response
     *            the response send by the server to the client
     * @throws ServletException
     *             if an error occurred
     * @throws IOException
     *             if an error occurred
     */
    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }

    /**
     * Initialization of the servlet. <br>
     *
     * @throws ServletException
     *             if an error occurs
     */
    public void init() throws ServletException {
        // Put your code here
    }

    public void listfile(File file, Map<String, String> map) {
        if (!file.isFile()) {// 如果是文件夹,就会递归下去
            File[] files = file.listFiles();
            for (File f : files) {
                listfile(f, map);
            }
        } else {// 去掉前面uuid_的部分
            String realName = file.getName().substring(
                    file.getName().indexOf("_") + 1);
            map.put(file.getName(), realName);
        }
    }
}

下载处理

package test;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class DownloadServlet extends HttpServlet {

    /**
     * Constructor of the object.
     */
    public DownloadServlet() {
        super();
    }

    /**
     * Destruction of the servlet. <br>
     */
    public void destroy() {
        super.destroy(); // Just puts "destroy" string in log
        // Put your code here
    }

    /**
     * The doGet method of the servlet. <br>
     *
     * This method is called when a form has its tag value method equals to get.
     * 
     * @param request
     *            the request send by the client to the server
     * @param response
     *            the response send by the server to the client
     * @throws ServletException
     *             if an error occurred
     * @throws IOException
     *             if an error occurred
     */
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        String fileName = request.getParameter("filename");
        // 如果你的tomcat是默认的就不能删掉,如果你在server.xml加了URIEncoding="UTF-8"就不用加了
        // fileName = new String(fileName.getBytes("iso8859-1"), "UTF-8");
        String fileSaveRootPath = this.getServletContext().getRealPath(
                "/WEB-INF/upload");
        // 根据之前的路径找
        String path = findFileSavePathByFileName(fileName, fileSaveRootPath);
        File file = new File(path + "\" + fileName);
        if (!file.exists()) {
            request.setAttribute("message", "你要的资源已经被删除了");
            request.getRequestDispatcher("/message.jsp").forward(request,
                    response);
        }
        String realname = fileName.substring(fileName.indexOf("_") + 1);
        // 设置响应头,控制浏览器下载该文件
        response.setHeader("content-disposition", "attachment;filename="
                + URLEncoder.encode(realname, "UTF-8"));
        FileInputStream in = new FileInputStream(path + "\" + fileName);
        OutputStream out = response.getOutputStream();
        byte buffer[] = new byte[1024];
        int len = 0;
        for (; (len = in.read()) != -1;) {
            out.write(buffer, 0, len);
        }
        in.close();
        out.close();
    }

    /**
     * The doPost method of the servlet. <br>
     *
     * This method is called when a form has its tag value method equals to
     * post.
     * 
     * @param request
     *            the request send by the client to the server
     * @param response
     *            the response send by the server to the client
     * @throws ServletException
     *             if an error occurred
     * @throws IOException
     *             if an error occurred
     */
    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }

    /**
     * Initialization of the servlet. <br>
     *
     * @throws ServletException
     *             if an error occurs
     */
    public void init() throws ServletException {
        // Put your code here
    }

    public String findFileSavePathByFileName(String filename,
            String saveRootPath) {// 防止同文件夹
        // 注意这个要和上传文件的目录一样,否则找不到文件
        int hashcode = filename.hashCode();
        int dir1 = hashcode & 0x5;
        // 只设置了一层
        // int dir2 = (hashcode & 0xf0) >> 4;
        String dir = saveRootPath + "\" + dir1;
        File file = new File(dir);
        if (!file.exists()) {
            file.mkdirs();
        }
        return dir;
    }

}

下载页面

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%
    String path = request.getContextPath();
    String basePath = request.getScheme() + "://"
            + request.getServerName() + ":" + request.getServerPort()
            + path + "/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">

<title>My JSP 'listfile.jsp' starting page</title>

<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
    <link rel="stylesheet" type="text/css" href="styles.css">
    -->

</head>

<body>
    <c:forEach var="me" items="${fileNameMap }">
        <c:url value="/servlet/DownloadServlet" var="download">
            <c:param name="filename" value="${me.key }"></c:param>
        </c:url>
        ${me.value }<a href="${download }">下载</a><br/>
    </c:forEach>
</body>
</html>
原文地址:https://www.cnblogs.com/vhyc/p/6692737.html