SpringMVC(Springboot)返回文件方法

原本的返回方法

@RequestMapping(value = "/download/{fileName}")
	public void downloadFile(@PathVariable String fileName) throws IOException{
		// 拼接真实路径
		String realPath = getRequest().getServletContext().getRealPath("/")
				+ "/" + fileName + ".xls";
		// 读取文件
		File file = new File(realPath);
		if(file.exists()){
			OutputStream os = new BufferedOutputStream(getResponse().getOutputStream());
			try {
				getResponse().setContentType("application/octet-stream");
				if (getRequest().getHeader("User-Agent").toUpperCase().indexOf("MSIE") > 0) {   //IE浏览器
					fileName = URLEncoder.encode(fileName + ".xls", "UTF-8");  
				} else {  
					fileName = URLDecoder.decode(fileName + ".xls");//其他浏览器
				}
				
				getResponse().setHeader("Content-disposition", "attachment; filename="
						+ new String(fileName.getBytes("utf-8"), "ISO8859-1")); // 指定下载的文件名
				os.write(FileUtils.readFileToByteArray(file));
				os.flush();
			} catch (IOException e) {
				e.printStackTrace();
			} finally {
				if(os != null){
					os.close();
				}
			}
		}
	}

使用response 的输出流直接操作。但是其实一般上面的操作都会放进Service层进行,这就需要将HttpServletresponse传进Service层或者在Controller层进行write操作,感觉不是很优雅,于是有了第二种方法。

ResponseEntity<byte[]>

@RequestMapping(value = "/download/{fileName}")
	public ResponseEntity<byte[]> downloadFile(@PathVariable String fileName)
			throws Exception {
		fileName = fileName + ".xls";
		// 1.拼接真实路径
		String realPath = getRequest().getServletContext().getRealPath("/") + "/" + fileName;
		// 2.读取文件
		File file = new File(realPath);
		
		// 4.设置格式
		HttpHeaders headers = new HttpHeaders();
		headers.setContentDispositionFormData("attachment", fileName);
		headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
		// 5.返回下载
		return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(file),
				headers, HttpStatus.OK);
}

是不是看起来清爽多了,不需要自己操作流;

这里有几个需要注意的点:

  • headers.setContentDispositionFormData("attachment", fileName) 设置的文件名是保存时候的文件名,attachment表示在浏览器打开url时会直接下载;但是有时候我们有MP3的查看需求,这时候想要在浏览器调用自己的播放器来显示MP3,那就可以将attachment换成inline,这样表示直接在浏览器使用;
  • ContentType 要准确

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×