网页文件下载实现
一、解决不同浏览器中文乱码
String userAgent = request.getHeader("User-Agent");
if(userAgent.contains("MSIE") || userAgent.contains("Trident") || userAgent.contains("Edge")){//ie浏览器使用
newName = java.net.URLEncoder.encode(fileName, "UTF-8");
}else{//非ie浏览器使用
newName = new String(fileName.getBytes(StandardCharsets.UTF_8),StandardCharsets.ISO_8859_1);
}
二、完成文件下载需要设置两个东西
Content-disposition和Content-length
Content-Disposition的设置格式是content-disposition = "Content-Disposition" ":" disposition-type *( ";" disposition-parm )
字段说明:
Content-Disposition为属性名
disposition-type是以什么方式下载,如attachment为以附件方式下载
disposition-parm为默认保存时的文件名
服务端向客户端游览器发送文件时,如果是浏览器支持的文件类型,一般会默认使用浏览器打开,比如txt、jpg等,会直接在浏览器中显示,如果需要提示用户保存,就要利用Content-Disposition进行一下处理,关键在于一定要加上attachment,同时当代码里面使用Content-Disposition来确保浏览器弹出下载对话框的时候,response.addHeader("Content-Disposition","attachment");一定要确保没有做过关于禁止浏览器缓存的操作
response.setHeader("Pragma", "No-cache"); response.setHeader("Cache-Control", "No-cache"); response.setDateHeader("Expires", 0);
response.setHeader:设置消息头信息
Content-length是设置下载文件的大小
response.setHeader("Content-Disposition", "attachment; filename=" + newFileName);
response.setHeader("Content-Length",String.valueOf(file.length()));
三、进行文件传输
这就是通常io输出输入流进行文件传输,这里可以通过BufferedInputStream和BufferedOutputStream来进行操作,好处在于会这两个io流会有缓冲区
InputStream in=new BufferedInputStream(new FileInputStream(file)); OutputStream os=new BufferedOutputStream(response.getOutputStream()); int len=-1; //野性的呼唤.mp4 byte[] bytes=new byte[1024*1024*5]; while((len=in.read(bytes))!=-1){ os.write(bytes,0,len); }
四、最后文件下载代码
@RequestMapping(value = "download/{filename:.+}")
public void downLoadFile( @PathVariable("filename") String fileName, HttpServletRequest request, HttpServletResponse response) throws IOException {
String newFileName;
//System.out.println(fileName);
String userAgent = request.getHeader("User-Agent");
if(userAgent.contains("MSIE") || userAgent.contains("Trident") || userAgent.contains("Edge")){//ie浏览器使用
newFileName = java.net.URLEncoder.encode(fileName, "UTF-8");
}else{//非IE浏览器使用
newFileName = new String(fileName.getBytes(StandardCharsets.UTF_8),StandardCharsets.ISO_8859_1);
}
//System.out.println(newFileName);
response.setHeader("Content-Disposition", "attachment; filename=" + newFileName);
response.setCharacterEncoding("utf-8");
//System.out.println(request.getServletContext().getRealPath("file/video/videos")+newFileName);
File file=new File(request.getServletContext().getRealPath("file/video/videos"),fileName);
response.setHeader("Content-Length",String.valueOf(file.length()));
InputStream in=new BufferedInputStream(new FileInputStream(file));
OutputStream os=new BufferedOutputStream(response.getOutputStream());
int len=-1;
//野性的呼唤.mp4
byte[] bytes=new byte[1024*1024*5];
while((len=in.read(bytes))!=-1){
os.write(bytes,0,len);
}
os.flush();
in.close();
os.close();
}
这里需要提示的是在springmvc中会自动将小数点.后的数字去掉,如野性的呼唤.mp4,传过来的是一个文件的名字,会自动将.mp4删除掉,如果采用resultful风格的话需要用到SpEL进行拼接{filename:.+},也就是这个,当然这个我也是不是很清楚,通过查找资料找到的,request.getServletContext().getRealPath("file/video/videos")这个的话就是获得file/video/videos在电脑中真实的文件地址。

浙公网安备 33010602011771号