文件上传下载之commons-fileupload

  1. 文件上传

    web应用中,经常会使用到文件的上传功能,其中有一些约束条件:

    • 上传文件大小、格式的限制,一般前台js进行限制后,后台同样也需要限制
    • 保证短之间内不让用户上传太多的文件
    • 服务器端对文件结构的管理,不能暴露文件目录
    • 防止文件被同名覆盖
    • 有条件的情况下会和杀毒软件厂家对接,防止用户上传病毒或者恶意代码,比如CKnife

工程环境
只需要commons-fileupload-1.3.2.jar和commons-io-2.5.jar
这里写图片描述
直接上代码

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
  <display-name>fileupload_mhm</display-name>

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



  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
</web-app>


/**
 * 不用缓冲区的上传
 * 
 * @author MHm
 * @time 2017年8月10日下午5:15:39
 */
public class FileUploadServlet extends HttpServlet {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException {
        String message = "";
        String savePath = this.getServletContext().getRealPath("/WEB-INF/upload");
        File srcFile = new File(savePath);
        if (!srcFile.exists() && !srcFile.isDirectory()) {
            srcFile.mkdir();
        }

        // 使用commonFile
        DiskFileItemFactory factory = new DiskFileItemFactory();
        ServletFileUpload upload = new ServletFileUpload(factory);
        upload.setHeaderEncoding("utf-8");
        if (!ServletFileUpload.isMultipartContent(req)) {
            return;
        }
        InputStream in = null;
        FileOutputStream fos = null;
        try {
            List<FileItem> list = upload.parseRequest(req);
            for (FileItem it : list) {
                if (it.isFormField()) {
                    String name = it.getFieldName();
                    String value = it.getString("utf-8");
                    System.out.println(name + ":" + value);
                } else {
                    String filename = it.getName();
                    System.out.println(filename);
                    if (filename == null || filename.trim().equals("")) {
                        continue;
                    }

                    filename = filename.substring(filename.lastIndexOf("\\") + 1);

                    in = it.getInputStream();
                    fos = new FileOutputStream(savePath + "\\" + filename);
                    byte[] buffer = new byte[1024];
                    int len = 0;
                    while ((len = in.read(buffer)) > 0) {
                        fos.write(buffer, 0, len);
                    }
                    //
                    // 关闭输入流
//                    in.close();
//                    // 关闭输出流
//                    fos.close();
                    // 删除处理文件上传时生成的临时文件,关闭流之后再删除临时文件
                    it.delete();
                    message = message + filename + ":文件上传成功!" + File.separator;
                }

            }

        } catch (FileUploadException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                in.close();
                fos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
        try {
            req.setAttribute("message", message);
            req.getRequestDispatcher("/pages/message.jsp").forward(req, resp);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

uploadFile.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>Insert title here</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>Insert title here</title>
</head>
<body>
${message }
</body>
</html>

使用临时文件管理的方式上传


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

/**
 * 带临时目录缓冲区
 * 
 * @author MHm
 * @time 2017年8月10日下午5:15:39
 */
public class FileUploadTempServlet extends HttpServlet {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException {
        String message = "";
        String fileTypeStr = "doc,docx,pdf,txt";
        String savePath = this.getServletContext().getRealPath("/WEB-INF/upload");
        String tempPath = this.getServletContext().getRealPath("/WEB-INF/temp");
        File tempFile = new File(tempPath);
        if (!tempFile.exists() && !tempFile.isDirectory()) {
            tempFile.mkdir();
        }

        // 使用commonFile
        // 1、创建一个DiskFileItemFactory工厂
        DiskFileItemFactory factory = new DiskFileItemFactory();
        // 100KB缓冲区
        factory.setSizeThreshold(1024 * 100);
        // 设置上传时生成的临时文件的保存目录
        factory.setRepository(tempFile);
        // 2、创建一个文件上传解析器
        ServletFileUpload upload = new ServletFileUpload(factory);
        // 进度监听器
        upload.setProgressListener(new ProgressListener() {

            @Override
            public void update(long byteRead, long contentLength, int arg2) {
                System.out.println("文件大小为:" + contentLength + ",当前已处理:" + byteRead);
            }
        });

        upload.setHeaderEncoding("utf-8");
        // 是否普通表单提交
        if (!ServletFileUpload.isMultipartContent(req)) {
            return;
        }
        // 设置上传单个文件的大小的最大值,目前是设置为10MB
        int fileSizeMax = 1024 * 1024 * 10;
        upload.setFileSizeMax(fileSizeMax);
        // 设置上传文件总量的最大值,最大值=同时上传的多个文件的大小的最大值的和,目前设置为10MB
        int sizeMax = 1024 * 1024 * 10;
        upload.setSizeMax(sizeMax);
        InputStream in = null;
        FileOutputStream fos = null;
                try {
            List<FileItem> list = upload.parseRequest(req);
            for (FileItem it : list) {
                if (it.isFormField()) {
                    String name = it.getFieldName();
                    String value = it.getString("utf-8");
                    System.out.println(name + ":" + value);
                } else {
                    String filename = it.getName();
                    if (filename == null || filename.trim().equals("")) {
                        continue;
                    }

                    filename = filename.substring(filename.lastIndexOf("\\") + 1);
                    // 扩展名
                    String fileExtName = filename.substring(filename.lastIndexOf(".") + 1);

                    if (fileTypeStr.indexOf(fileExtName) == -1) {
                        System.out.println("上传的文件的扩展名是:" + fileExtName);
                        continue;
                    }

                    String saveFileName = UUID.randomUUID().toString() + "_" + filename;
                    String saveFilePathName = buildPath(saveFileName, savePath);

                    in = it.getInputStream();
                    fos = new FileOutputStream(saveFilePathName + "\\" + saveFileName);
                    byte[] buffer = new byte[1024];
                    int len = 0;
                    while ((len = in.read(buffer)) > 0) {
                        fos.write(buffer, 0, len);
                    }
                    //
                    in.close();
                    fos.close();
                    it.delete();
                    message = message + filename + ":文件上传成功!" + File.separator;
                }
            }
            req.setAttribute("message", message);
            req.getRequestDispatcher("/pages/message.jsp").forward(req, resp);

        } catch (FileUploadException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                in.close();
                fos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
    }

    /**
     * @param saveFileName
     * @param savePath
     * @return
     */
    private String buildPath(String saveFileName, String savePath) {
        int hashcode = saveFileName.hashCode();
        int dir1 = hashcode & 0xf;
        int dir2 = (hashcode & 0xf0) >> 4;
        String dir = savePath + "\\" + dir1 + "\\" + dir2;
        File file = new File(dir);
        if (!file.exists()) {
            // 创建目录
            file.mkdirs();
        }
        return dir;
    }

}

看看效果
这里写图片描述

2.文件下载

文件列表

<servlet>
        <servlet-name>fileList</servlet-name>
        <servlet-class>com.mhm.upload.FileListServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>fileList</servlet-name>
        <url-pattern>/fileList</url-pattern>
    </servlet-mapping>

    <servlet>
        <servlet-name>download</servlet-name>
        <servlet-class>com.mhm.upload.DownloadServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>download</servlet-name>
        <url-pattern>/download</url-pattern>
    </servlet-mapping>

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>Insert title here</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>
 </form>
</body>
</html>

文件列表查询:

/**
 * @author MHm
 * @time 2017年8月11日上午11:27:18
 */
public class FileListServlet extends HttpServlet{

    /**
     * 
     */
    private static final long serialVersionUID = 2692787517286234116L;

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String uploadFilePath = this.getServletContext().getRealPath("/WEB-INF/upload");
        Map<String,String> fileNameMap = new HashMap<String,String>();
        listFile(new File(uploadFilePath),fileNameMap);
        req.setAttribute("fileNameMap", fileNameMap);
        req.getRequestDispatcher("/pages/uploadFile.jsp").forward(req, resp);

    }

    private void listFile(File file,Map<String,String> map){
        if(!file.isFile()){
            File[] files = file.listFiles();
            for(File f :files){
                listFile(f,map);
            }
        }else{
            String real_name = file.getName().substring(file.getName().indexOf("_")+1);
            map.put(file.getName(), real_name);
        }
    }

}

文件下载:

package com.mhm.upload;

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

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

/**
 * @author MHm
 * @time 2017年8月11日上午11:36:17
 */
public class DownloadServlet extends HttpServlet {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException {
        FileInputStream in = null;
        OutputStream out = null;
        try {
            String fileName = req.getParameter("filename");
            fileName = new String(fileName.getBytes("iso-8859-1"), "utf-8");
            String realPath = this.getServletContext().getRealPath("/WEB-INF/upload");

            String fileRealPath = buildPath(fileName, realPath);
            // 得到要下载的文件
            File file = new File(fileRealPath + "\\" + fileName);
            // 如果文件不存在
            if (!file.exists()) {
                req.setAttribute("message", "您要下载的资源已被删除!!");
                req.getRequestDispatcher("/pages/message.jsp").forward(req, resp);
                return;
            }
            // 处理文件名
            String realname = fileName.substring(fileName.indexOf("_") + 1);
            // 设置响应头,控制浏览器下载该文件
            resp.setHeader("content-disposition", "attachment;filename=" + URLEncoder.encode(realname, "UTF-8"));
            // 读取要下载的文件,保存到文件输入流
            in = new FileInputStream(fileRealPath + "\\" + fileName);
            // 创建输出流
            out = resp.getOutputStream();
            // 创建缓冲区
            byte buffer[] = new byte[1024];
            int len = 0;
            // 循环将输入流中的内容读取到缓冲区当中
            while ((len = in.read(buffer)) > 0) {
                // 输出缓冲区的内容到浏览器,实现文件下载
                out.write(buffer, 0, len);
            }

        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                // 关闭文件输入流
                in.close();
                // 关闭输出流
                out.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }

    /**
     * @param saveFileName
     * @param savePath
     * @return
     */
    private String buildPath(String saveFileName, String savePath) {
        int hashcode = saveFileName.hashCode();
        int dir1 = hashcode & 0xf;
        int dir2 = (hashcode & 0xf0) >> 4;
        String dir = savePath + "\\" + dir1 + "\\" + dir2;
        File file = new File(dir);
        if (!file.exists()) {
            // 创建目录
            file.mkdirs();
        }
        return dir;
    }

}

猜你喜欢

转载自blog.csdn.net/mhm52368/article/details/77092297