文件的上传和下载

256 阅读2分钟

文件的上传

前置条件:

  1. 导入jar包commons-io.jar 与commons-fileupload.jar
  2. 表单一定要标记enctype="multipart/form-data"
<html>
<head>
    <title>Title</title>
</head>
<body>
<form action="http://localhost:8080/09_EL_JSTL/upload" method="post" enctype="multipart/form-data">
    用户名:<input type="text" name="username"/>
    文件:<input type="file" name="photo"/>
    <input type="submit">
</form>
</body>
</html>

解析上传的数据

1.先判断上传的数据是否多段数据(只有是多段的数据,才是文件上传的)
2.创建 FileItemFactory 工厂实现
3.创建用于解析上传数据的工具类 ServletFileUpload 类
4.解析上传的数据,得到每一个表单项 FileItem
5.循环判断,每一个表单项,是普通类型,还是上传的文件
6.分类处理

if(ServletFileUpload.isMultipartContent(req)){
    FileItemFactory fileItemFactory = new DiskFileItemFactory();
    ServletFileUpload servletFileUpload = new ServletFileUpload(fileItemFactory);
    List<FileItem> list = null;
    try {
        list = servletFileUpload.parseRequest(req);
    } catch (FileUploadException e) {
        e.printStackTrace();
    }
    for(FileItem item:list){
        if(item.isFormField()){
            System.out.println("表单的name属性值:"+item.getFieldName());
            System.out.println("表单的value"+item.getString("UTF-8"));
        }else{
            System.out.println("name值:"+item.getFieldName());
            System.out.println("文件名:"+item.getName());
            try {
                item.write(new File("d://"+item.getName()));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

}

文件下载

1.获取下载文件名
2.获取下载的内容
3.在回传前,通过响应头告诉客户端回传的数据类型
4.告诉客户端回传的数据用于下载(还是通过响应头)
5.把下载的内容回传给客户端

String downloadFileName = "p1.jpg";
ServletContext servletContext = getServletContext();
String mimeType = servletContext.getMimeType("/file/" + downloadFileName);
resp.setContentType(mimeType);
resp.setHeader("Content-Disposition","attachment;filename="+ URLEncoder.encode("p1.jpg","UTF-8"));

InputStream resourceAsStream = servletContext.getResourceAsStream("/file/" + downloadFileName);
ServletOutputStream outputStream = resp.getOutputStream();
IOUtils.copy(resourceAsStream,outputStream);

response.setHeader("Content-Disposition", "attachment; fileName=p1.jpg"); 这个响应头告诉浏览器。这是需要下载的。而 attachment 表示附件,也就是下载的一个文件。fileName=后面, 表示下载的文件名。

附件中文名乱码问题解决方案

方案一:URLEncoder 解决附件中文名问题。

把中文名进行 UTF-8 编码操作,然后把编码后的字符串设置到响应头中即可。

String str = "attachment; fileName=" + URLEncoder.encode("中文.jpg", "UTF-8");
response.setHeader("Content-Disposition", str);

方案2:BASE64编解码解决附件中文名问题

需要把请求头 Content-Disposition: attachment; filename=中文名 编码成为:Content-Disposition: attachment; filename==?charset?B?xxxxx?= 说明
=? 编码内容的开始
charset 表示字符集
B 表示BASE64编码
xxxx 表示文件名BASE64编码后的内容
?= 表示编码内容的结束

操作:

String str = "attachment; fileName=" + "=?utf-8?B?" + new BASE64Encoder().encode("中文.jpg".getBytes("utf-8")) + "?=";    
response.setHeader("Content-Disposition", str)