文件上传和下载

2017/04/01 JavaEE

文件上传请求

表单

<!-- enctype指定后不能用req.getParameter()获取参数 -->
<form method="post" enctype="multipart/form-data" action="/fileUpload">
    <input type="file" name="fileName"/>
    <input type="text" name="username"/>
</form>

多部件表单体

分割出多个部件,一个表单项一个部件,每个部件有自己的请求头,空行和体。

  • 普通部件
    • 1个头,Content-Disposition:包含表单项名称name
    • 1个体:表单项的值
  • 文件部件:
    • 2个头:
      • Content-Disposition:包含表单项名称name,还有filename
      • Content-Type:上传文件的MIME类型,如image/pjpeg
    • 1个体:上传文件内容

上传

commons-fileupload文件上传

commons-fileupload会帮助我们解析request的请求的每个部件为一个FileItem对象

public class FileUploadServlet extends HttpServlet {
    private String basePath;
    private String tempPath;

    @Override
    public void init(ServletConfig config) throws ServletException {
        basePath = config.getInitParameter("basePath");
        tempPath = config.getInitParameter("tempPath");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("UTF-8");
        resp.setContentType("text/html;charset=UTF-8");

        // Servlet直接获取流数据
        // ServletInputStream servletInputStream = req.getInputStream();

        //获取工厂获取servletFileUpload对象 设置缓存大小20kb,设置缓存路径
        DiskFileItemFactory diskFileItemFactory = new DiskFileItemFactory(20 * 1024, new File(tempPath));
        ServletFileUpload servletFileUpload = new ServletFileUpload(diskFileItemFactory);

        servletFileUpload.setSizeMax(100 * 1024);// 总上传大小控制 100k
        servletFileUpload.setFileSizeMax(1024 * 1024);// 单文件上传大小限制 1M
        // 上传进度监控
        servletFileUpload.setProgressListener(new ProgressListener() {
            public void update(long pBytesRead, long pContentLength, int pItems) {
                System.out.println("总大小:" + pContentLength + "已上传:" + pBytesRead);
            }
        });
        List<FileItem> fileItems = null;
        try {
            // 转换上传请求为fileItem
            fileItems = servletFileUpload.parseRequest(req);
        } catch (FileUploadException e) {
            e.printStackTrace();
            // 处理总大小和单文件大小限制
            if (e instanceof FileUploadBase.SizeLimitExceededException) {
                req.setAttribute("msg", "max size limit exceed");
            } else if (e instanceof FileUploadBase.FileSizeLimitExceededException) {
                req.setAttribute("msg", "file max size limit exceed");

            }
            return;
        }
        for (FileItem fileItem : fileItems) {
            // 文件类型
            if (fileItem.isFormField()) {
                String name = fileItem.getName();
                // 兼容部分浏览器全路径文件名问题
                int index = name.indexOf("\\");
                if (index != -1) {
                    name = name.substring(index + 1);
                }
                // 防止重名
                String destinationFileName = UUID.randomUUID() + name;
                // 根据哈希值稀疏文件存储路径
                char[] dirString = Integer.toHexString(destinationFileName.hashCode()).toCharArray();
                String pathname = basePath + File.separator + dirString[0] + File.separator + dirString[1];
                // 创建目录
                File file = new File(pathname);
                file.mkdirs();
                try {
                    //写入文件
                    fileItem.write(new File(pathname, destinationFileName));
                } catch (Exception e) {
                    e.printStackTrace();
                    return;
                }

            } else {// 普通表单类型
                String name = fileItem.getName();
                String value = fileItem.getString("UTF-8");
                System.out.println(name + ":" + value);
            }
        }
    }
}

JavaEE 6.0 文件上传

JavaEE 6.0 文件上传

下载

向客户端响应字节数据

文件下载响应

  • 2个头:
    • Content-Type:下载文件的MIME类型,如image/pjpeg
    • Content-Disposition:attachment;filename=fileName
      • 默认是inline,表示在浏览器中打开
  • 1个流:
    • 下载的文件数据

servlet文件下载

public class FileDownloadServlet extends HttpServlet {
    private String basePath = "WEB-INF/files/";

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, UnsupportedEncodingException {

        req.setCharacterEncoding("UTF-8");

        String fileName = req.getParameter("fileName");
        File file = new File(basePath, fileName);
        // 设置下载文件类型
        resp.setContentType(getServletContext().getMimeType(basePath + fileName));
        // 设置相应内容类型为附件,使用url编码防止中文文件名乱码不显示问题
        resp.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
        // 输出文件流到客户端
        BufferedInputStream bufferedInputStream = null;
        try {
            bufferedInputStream = new BufferedInputStream(new FileInputStream(file));
            byte[] bytes = new byte[1024];
            int length;
            while ((length = bufferedInputStream.read(bytes)) > 0) {
                resp.getOutputStream().write(bytes, 0, length);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                bufferedInputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

以上概念总结于传智播客JavaWeb课程

Search

    Post Directory