使用 SpringMVC 实现文件的上传/下载

在 TCP/IP 协议族中,最早出现的文件上传机制是 FTP,而在HTTP协议中,通过设置请求头/响应头也可以实现文件的上传和下载。所以对上传下载的理解,关键在于对请求头和响应头的理解。

1 文件的上传

  • Content-Type: multipart/form-data; boundary=流分隔符值。这个分隔符用于区分表单中的不同字段。
1.1 在页面中,使用表单进行文件上传。

为 input 元素设置 type = "file" 以及多个文件上传时设置 "multiple"
属性。name属性用于后端接受文件使用。


对表单中的 enctype 属性做个详细的说明:

  • application/x-www=form-urlencoded:默认方式,只处理表单域中的 value 属性值,采用这种编码方式的表单会将表单域中的值处理成 URL 编码方式。
  • multipart/form-data:这种编码方式会以二进制流的方式来处理表单数据,这种编码方式会把文件域指定文件的内容也封装到请求参数中,不会对字符编码。
  • text/plain:除了把空格转换为 "+" 号外,其他字符都不做编码处理,这种方式适用直接通过表单发送邮件。
1.2 后端接收上传的文件

Spring MVC为文件上传提供了直接的支持,这种支持是用即插即用的MultipartResolver实现的,它的实现依赖Apache提供的Commons FileUpload组件jar包。
在controller里面,使用 @RequestParam("file") MultipartFile file 或者 @RequestParam(value = "file") List files 参数来接收文件。
MultipartFile类的API:

  • void transferTo(File dest):将上传文件写入磁盘
  • String getOriginalFilename():获取上传文件的原名。你可能需要给原名加一个时间戳。
  • boolean isEmpty():是否有上传文件
  • String getName():获取表单中文件组件的名字

2 文件的下载

2.1 前端

很简单,一个url链接就可以实现下载。

2.2 后端

在响应消息头中设置 Content-Disposition 和 Content-Type使得浏览器不打开文件,而是保存文件,也就是文件的下载。
文件中的中文注意编码问题。

  • Content-Disposition 的值为 attachment;filename=文件名
  • Content-Type 的值为 application/octet-stream 或者 application/x-msdownload。文件编码也是设置Content-Type。

Content-Disposition 的第一个参数的值有两个:

  • inline 默认值,表示响应中的消息体会以页面的一部分或者整个页面的形式展示。
  • attachment 表示响应的消息体应被下载到本地
    一个pdf/txt/jpg类型的文件,浏览器具有打开的能力,如果你想下载而不是打开,就需要设置Content-Disposition(处理方式)为attachment(附件)。即便是一个html页面,如果响应头设置的处理方式是附件,那么浏览器也会下载该html,而不是打开并渲染它。
// 正常解析渲染
Content-Disposition: inline
// 下载文件
Content-Disposition: attachment
// 下载文件,并将文件保存为filename.jpg
Content-Disposition: attachment; filename="filename.jpg"
// 设置响应头通知浏览器下载
HttpHeaders headers = new HttpHeaders();
// 也可以是这样 headers.add("Content-Disposition", "attachment;filename="+fileName);
headers.setContentDispositionFormData("attachment", filename);
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
return new ResponseEntity(FileUtils.readFileToByteArray(file), headers, HttpStatus.OK);
2.3 不使用springMVC,使用IO流实现下载:

设置 response 响应头
读取文件 -- InputStream
写出文件 -- OutputStream
关流

@RequestMapping(value="/downloadFile")
    public String downloads(HttpServletResponse response) throws Exception{
        String  path = "C:/";
        String  fileName = "default.png";
        //1、设置response 响应头
        response.reset();
        response.setCharacterEncoding("UTF-8");
        response.setContentType("multipart/form-data");
        response.setHeader("Content-Disposition", 
                "attachment;fileName="+URLEncoder.encode(fileName, "UTF-8"));
        
        File file = new File(path,fileName);
        //2、 读取文件--输入流
        InputStream input=new FileInputStream(file);
        //3、 写出文件--输出流
        OutputStream out = response.getOutputStream();
        byte[] buff =new byte[1024];
        int index=0;
        //4、执行 写出操作
        while((index= input.read(buff))!= -1){
            out.write(buff, 0, index);
            out.flush();
        }
        out.close();
        input.close();
        return null;
    }

你可能感兴趣的:(使用 SpringMVC 实现文件的上传/下载)