网页文件下载实现

一、解决不同浏览器中文乱码

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在电脑中真实的文件地址。

posted @ 2020-12-20 20:59  飞翔的阿飞  阅读(337)  评论(0)    收藏  举报