Springmvc框架下的下载方法有两种,一个是使用输出流方法进行下载,还有一个就是用ResponseEntity方法进行下载,两者有什么区别呢,让我们来分析一下:
输出流下载方法的特点就是Controller方法配置的时候是用输出流进行配置的如下:
@RequestMapping("/download/{filename}")
public void download(@PathVariable String filename, HttpSession session, HttpServletResponse resp){
System.out.println(filename);
String path=session.getServletContext().getRealPath("/WEB-INF/upload/");
File file=new File(path,filename);
这就是输出流的方法,HttpServletResponse类,参数为resp,最终使用copy方法把输入流的名字传到输出流处,完成用户的文件下载:
StreamUtils.copy(new FileInputStream(file),resp.getOutputStream());
然而,ResponseEntity的下载方法是怎么样的呢?和使用输出流的下载方法有什么不一样呢,让我们来分析一下。
首先让我们来看看ResponseEntity下载方法的Controller代码:
@RequestMapping("/download2")
public ResponseEntity<byte[]> download2(String filename,HttpSession session) throws IOException{
String path=session.getServletContext().getRealPath("/WEB-INF/upload/");
File file=new File(path,filename);
byte[] bytes= FileUtils.readFileToByteArray(file);
HttpHeaders httpHeaders=new HttpHeaders();
httpHeaders.add("content-disposition","attachment;filename="+filename);
return new ResponseEntity<byte[]>(bytes,httpHeaders, HttpStatus.OK);
}
为了方便区别,我把输出流的Controller代码也放上来:
@RequestMapping("/download")
public void download(String filename, HttpSession session, HttpServletResponse resp){
System.out.println(filename);
String path=session.getServletContext().getRealPath("/WEB-INF/upload/");
File file=new File(path,filename);
try {
filename="成龙";
filename=new String(filename.getBytes("utf-8"),"iso8859-1");
resp.setHeader("content-disposition","attachment;filename="+filename);
StreamUtils.copy(new FileInputStream(file),resp.getOutputStream());
} catch (IOException e) {
e.printStackTrace();
}
}
响应体方法ResponseEntity,你可以点进去看看它的方法,可以发现它是一个泛型
public class ResponseEntity<T> extends HttpEntity<T> {
private final Object statusCode;
因此,我们需要向这个泛型方法传入一个泛型<byte[]>,这个时代表字节的意思,就是让这个响应体变成字节类型方便响应文件,然后可以看到它的传入参数中比输出流的下载方法的传入参数中少了一个输出流方法
public ResponseEntity<byte[]> download2(String filename,HttpSession session) throws IOException
public void download(String filename, HttpSession session, HttpServletResponse resp)
对比一下两个传入参数的方法,可以看出ResponseEntity下载方法中不仅少了输出流方法,而且还多了抛出异常。
接下来就是传递文件的路径和文件名给file
String path=session.getServletContext().getRealPath("/WEB-INF/upload/");
File file=new File(path,filename);
ResponseEntity最关键的三步是配置文件数据,请求头,状态码,这是ResponseEntity最终要返回的三个数据
因此我们需要配置第一个,文件数据
byte[] bytes= FileUtils.readFileToByteArray(file);
把文件file传进来转换为文件字节数据,作为文件数据
HttpHeaders httpHeaders=new HttpHeaders();
httpHeaders.add("content-disposition","attachment;filename="+filename);
new一个HttpHeaders,建立请求头,并且设定名字和点击下载的时候是否会弹框出来询问
最后一个就是状态码了,状态码不用怎么配置,只需要在最后return那里写上OK就可以
最终return结果如下:
return new ResponseEntity<byte[]>(bytes,httpHeaders, HttpStatus.OK);
分别return了文件数据,请求头,状态码
总结一下,输出流下载方法和ResponseEntity响应体下载方法的JSP方法基本上是一样的
输出流下载方法就是需要一个文件名参数(配置到file中),session参数(用于获取文件路径,并配置到file中),输出流参数(用于获取请求头和最终copy输入流中的文件过来进行下载)
而ResponseEntity下载方法则是需要一个byte[]泛型,一个文件名filename参数(用于配置file),一个session参数(用于获取文件路径,也是用于配置file),然后它最终是需要返回三个数值,分别是文件数据,请求头,状态码,文件数据就是file中要传入filename和path,然后要转换为byte[]数组的文件数据,请求头就是设置下载的文件名和点击下载后是否弹出对话框功能,状态码就只是最后return的时候加个OK就行
配上最终完成结果