web开发中,文件的上传与下载是系统必备的功能。无论是PC端的web系统还是手机APP软件,发票与合同的下载,对所有的用户来说都是不可或缺的。
文件的下载实质上就是文件的网络传输,其过程是文件从服务器经过网络流传向用户的本地,其间需要用户在本地浏览器指定下载路径。
使用Spring开发时,有三种方式可以实现文件的下载。分别是:
- 超链接
- 文件流
- ResponseEntity
1. 超链接
第一种方式比较简单,使用a标签:
1 <a href="url">点击下载</a>
就可以实现对静态资源的下载,但只能下载静态资源,应用比较局限。
2. I/O流
使用I/O流下载文件实质上就是将文件内容暂存于reponse的消息体中,然后设置相应类型告知浏览器下载文件,最终激活浏览器的下载窗口,由用户选择路径
1 @Override 2 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 3 // 服务器文件路径 4 String serverFilePath = "D:\\Hello world.txt"; 5 File serverFile = new File(serverFilePath); 6 7 // 设置ContentType, 固定写法 8 response.setContentType("text/html;charset=utf-8"); 9 // 告知浏览器下载附件 10 response.addHeader("Content-Disposition", "attachment;filename=" + serverFile.getName()); 11 12 // 读取文件内容 13 ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); 14 InputStream inputStream = null; // 服务器文件读取流 15 try { 16 inputStream = new FileInputStream(serverFile); 17 byte[] buffer = new byte[1024]; 18 int len = 0; 19 while ((len = inputStream.read(buffer)) != -1) { 20 byteArrayOutputStream.write(buffer, 0, len); 21 } 22 } catch (Exception e) { 23 e.printStackTrace(); 24 } 25 byte[] data = byteArrayOutputStream.toByteArray(); 26 27 // 输出文件内容到response 28 OutputStream outputStream = response.getOutputStream(); 29 outputStream.write(data); 30 31 // 关闭流 32 FileUtil.closeStream(byteArrayOutputStream, inputStream, outputStream); 33 }
3. ResponseEntity
使用I/O流下载文件的写法复杂且可读性非常差。Spring提供了一种比较优雅的方式-ResponseEntity,实现文件下载。
ResponseEntity类是HttpEntity类的扩展类,它只比HttpEntity多了一个状态属性。HttpEntity是http请求/响应消息的抽象实体,包括header和body。
ResponseEntity接收一个内容泛型,在文件下载时可以指定byte[]
类型接收下载文件内容。
1 @RequestMapping("/downloadFile") 2 public ResponseEntity<byte[]> testResponseEntity(HttpServletRequest request, HttpServletResponse response) { 3 ResponseEntity<byte[]> responseEntity = null; 4 try { 5 // 服务器文件路径 6 String serverFilePath = "D:\\Hello world.txt"; 7 File serverFile = new File(serverFilePath); 8 9 // 响应头,告知浏览器下载附件 10 HttpHeaders headers = new HttpHeaders(); 11 headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=" + serverFile.getName()); 12 // 响应内容。 13 byte[] body = FileUtil.readByteArrayFromLocalFile(serverFilePath); 14 // 响应状态 15 HttpStatus statusCode = HttpStatus.OK; 16 17 responseEntity = new ResponseEntity(body, headers, statusCode); 18 } catch (Exception e) { 19 e.printStackTrace(); 20 } 21 return responseEntity; 22 }