整理java文件下载(中文乱码、火狐浏览器乱码、空格变+号、文件名包含空格时文件名可能显示不全等问题)

这篇博客总结了解决Java文件下载中出现的中文乱码、火狐浏览器下载时乱码以及空格被转换为+号等问题的方法。通过特定的编码处理和字符串替换,可以确保文件名正确显示和下载。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

首先感谢网上各路大仙提供的资料:(参考如下)
Java文件下载处理中文名(使用URLEncoder编码及空格变+解决)

FIREFOX 下载中文文件名出现乱码的java解决方案

用火狐浏览器下载中文文件名的文件乱码及其解决

解决attachment; filename含空格时显示不完全的问题

1.一般中文乱码处理方式
采用URLEncoder.encode(fileName, "UTF-8")处理中文名字;
但是这样的话,不是通用的,火狐浏览器就不行了。需要单独处理

2.火狐浏览器下载中文文件名的文件乱码及其解决
.火狐浏览器下载中文文件名的文件乱码及其解决
采用 new String(fileName.getBytes("GB2312"),"ISO-8859-1")处理中文名字;

2.空格变+号
空格变+号
%20是空格在UTF-8下的编码;
只需要在URLEncoder.encode(fileName, "UTF-8")替换+号为%20;

fileName = fileName.Replace("+", "%20");  //encode后替换  解决空格问题

3.文件名包含空格时文件名显示不全
我开始遇到这问题了,后来不知道怎么测试想截图的时候,加不加这个双引号包含都没问题;反正我还是加了,有备无患;

response.setHeader("Content-Disposition", "attachment;filename=\""+ filenamedisplay  +"\"");//将文件名用 双引号包含,否则带空格的文件名,显示不完全

贴个部分代码(仅供参考)

// 1.获取要下载的文件的绝对路径
        String filepath = "";
        if (fil_fileindex != null) {
            filepath = filepath + fileserverurl;
        }
// 2.获取要下载的文件名
        String fileName = fil_fileindex.getFilename();
        int fileSize = Integer.parseInt(fil_fileindex.getFilesize());
        response.reset();  
        // 设置为下载application/x-download  
        //response.setContentType("application/x-download charset=UTF-8");
        if ("FF".equals(getBrowser(request))) {  
            // 针对火狐浏览器处理方式不一样了  
            fileName = new String(fileName.getBytes("GB2312"), "ISO-8859-1");  
        }else{
            fileName = URLEncoder.encode(fileName, "UTF-8");//encode解决中文乱码
            fileName = fileName.replace("+", "%20");//encode后替换  解决空格问题
        } 
        // 3.设置Content-Disposition响应头控制浏览器弹出保存框,若没有此句则浏览器会直接打开并显示文件。中文名要经过URLEncoder.encode编码,否则虽然客户端能下载但显示的名字是乱码
        response.setHeader("Content-Disposition", "attachment;filename=\""+ fileName +"\"");//将文件名用 双引号包含,否则带空格的文件名,显示不完全
        response.setContentLength(fileSize);
        // 4.获取要下载的文件输入流、输出流
        InputStream in = null;
        OutputStream out = null;
        try {
            in = getInputStreamByPath(filepath);
            int len = 0;
            // 5.创建数据缓冲区
            byte[] buffer = new byte[1024];
            // 6.通过response对象获取OutputStream流
            out = response.getOutputStream();
            // 7.将FileInputStream流写入到buffer缓冲区
            while ((len = in.read(buffer)) > 0) {
                // 8.使用OutputStream将缓冲区的数据输出到客户端浏览器
                out.write(buffer, 0, len);
            }
            out.flush();
        } catch (IOException e) {
            response.reset();//重置响应头信息
            request.setCharacterEncoding("UTF-8");
            response.setHeader("Pragma", "No-cache");
            response.setHeader("Cache-Control", "no-cache");
            response.setDateHeader("Expires", 0L);
            response.getWriter().print("<script>alert(decodeURIComponent('" + URLEncoder.encode("没有找到该文件,已被删除!", "UTF-8") + "'));</script>");
        }finally{
            if(out != null){
                out.close();
            }
            if(in != null){
                in.close();
            }
        }
     /** 
     * 通过url返回输入流  
     * @param url 
     * @return 
     * @throws IOException 
     */  
    private InputStream getInputStreamByPath(String path) throws IOException{  
        URL url = null;  
        InputStream is =null;  
        try {  
            url = new URL(path);  
        } catch (MalformedURLException e) {  
            e.printStackTrace();  
        } 

        HttpURLConnection conn = (HttpURLConnection) url.openConnection();//利用HttpURLConnection对象,我们可以从网络中获取网页数据. 
        //设置超时间为3秒  
        conn.setConnectTimeout(3*1000);  
        //防止屏蔽程序抓取而返回403错误  
        conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");  

        // 设置是否向conn输出,因为这个是post请求,参数要放在http正文内,因此需要设为true, 默认情况下是false;   
        conn.setDoOutput(true);
        // 设置是否从conn读入,默认情况下是true;
        conn.setDoInput(true); 
        // Post 请求不能使用缓存   
        conn.setUseCaches(false);
        // 设定传送的内容类型是可序列化的java对象(如果不设此项,在传送序列化对象时,当WEB服务默认的不是这种类型时可能抛java.io.EOFException)   
        conn.setRequestProperty("Content-type", "application/x-java-serialized-object");   
        // 设定请求的方法为"POST",默认是GET   
        conn.setRequestMethod("POST");
        // 连接,从上述url.openConnection()至此的配置必须要在connect之前完成,   
        conn.connect();  
        is = conn.getInputStream(); //得到网络返回的输入流  

        return is;  
    }
    /**
     *  以下为服务器端判断客户端浏览器类型的方法  
     * @param request
     * @return
     */
    private String getBrowser(HttpServletRequest request) {  
        String UserAgent = request.getHeader("USER-AGENT").toLowerCase();  
        if (UserAgent != null) {  
             if (UserAgent.indexOf("msie") != -1)  
                return "IE";  
            if (UserAgent.indexOf("firefox") != -1)  
                return "FF";  
            if (UserAgent.indexOf("safari") != -1)  
                return "SF";  
        }  
        return null;  
    } 
Accept application/json, text/plain, */* Accept-Encoding gzip, deflate, br, zstd Accept-Language zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2 Authorization eyJjdHkiOiJIUzI1NiIsInR5cCI6IkpXVCIsImFsZyI6IkhTMjU2In0.eyJwZXJtaXNzaW9ucyI6Ilt7XCJhdXRob3JpdHlcIjpcInJlY2hhcmdlXCJ9LHtcImF1dGhvcml0eVwiOlwiYWZmYWlyc1wifSx7XCJhdXRob3JpdHlcIjpcInN5c3RlbVwifSx7XCJhdXRob3JpdHlcIjpcImNvcHktbWV0ZXJcIn0se1wiYXV0aG9yaXR5XCI6XCJyZXBvcnRcIn0se1wiYXV0aG9yaXR5XCI6XCJhbmFseXNpc1wifSx7XCJhdXRob3JpdHlcIjpcIm1haW50ZW5hbmNlXCJ9LHtcImF1dGhvcml0eVwiOlwiYXBwbGljYXRpb25cIn0se1wiYXV0aG9yaXR5XCI6XCJsb2dcIn0se1wiYXV0aG9yaXR5XCI6XCJvdGhlclwifSx7XCJhdXRob3JpdHlcIjpcImRhc2hib2FyZFwifSx7XCJhdXRob3JpdHlcIjpcImN1c3RvbWVyXCJ9LHtcImF1dGhvcml0eVwiOlwiUk9MRV9BRE1JTlwifV0iLCJpZCI6MSwiZXhwIjozNjQ2NTQxMjk2LCJ1c2VybmFtZSI6ImFkbWluIn0.o1W0LnqKQ6HBe3Tm_xc4dQXmOhF7Ho9KYiZ3dJN9n6c Connection keep-alive Content-Length 2 Content-Type application/json Cookie JSESSIONID=3YA5rtveexBSXoYFglr4j2HNdDXFNHkf0zJrBlB6 Host localhost:8080 Origin http://localhost:8080 Priority u=0 Referer http://localhost:8080/customer Sec-Fetch-Dest empty Sec-Fetch-Mode cors Sec-Fetch-Site same-origin User-Agent Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:139.0) Gecko/20100101 Firefox/139.0 这是火狐浏览器导出文件的请求头 application/json, text/plain, */* accept-encoding gzip, deflate, br, zstd accept-language zh-CN,zh;q=0.9 authorization eyJjdHkiOiJIUzI1NiIsInR5cCI6IkpXVCIsImFsZyI6IkhTMjU2In0.eyJwZXJtaXNzaW9ucyI6Ilt7XCJhdXRob3JpdHlcIjpcImN1c3RvbWVyXCJ9LHtcImF1dGhvcml0eVwiOlwicmVjaGFyZ2VcIn0se1wiYXV0aG9yaXR5XCI6XCJhZmZhaXJzXCJ9LHtcImF1dGhvcml0eVwiOlwic3lzdGVtXCJ9LHtcImF1dGhvcml0eVwiOlwiY29weS1tZXRlclwifSx7XCJhdXRob3JpdHlcIjpcInJlcG9ydFwifSx7XCJhdXRob3JpdHlcIjpcImFuYWx5c2lzXCJ9LHtcImF1dGhvcml0eVwiOlwibWFpbnRlbmFuY2VcIn0se1wiYXV0aG9yaXR5XCI6XCJhcHBsaWNhdGlvblwifSx7XCJhdXRob3JpdHlcIjpcImxvZ1wifSx7XCJhdXRob3JpdHlcIjpcIm90aGVyXCJ9LHtcImF1dGhvcml0eVwiOlwiZGFzaGJvYXJkXCJ9LHtcImF1dGhvcml0eVwiOlwiUk9MRV9BRE1JTlwifV0iLCJpZCI6MSwiZXhwIjozNjQ2MTA3MDk0LCJ1c2VybmFtZSI6ImFkbWluIn0.aIIIU1blfIHTbCM9mVY8_6Aj27IiwieOyHDK1IflJSo cache-control no-cache connection keep-alive content-length 2 content-type application/json cookie JSESSIONID=GjCp6r_LYcQVO201PsIOuppOMQ3xoAqeSdYrCTvJ; Webstorm-be5713b8=c4fd27ab-3f56-4132-9bd3-601434e5118c host localhost:8080 origin http://localhost:8080 pragma no-cache referer http://localhost:8080/customer sec-ch-ua "Google Chrome";v="137", "Chromium";v="137", "Not/A)Brand";v="24" sec-ch-ua-mobile ?0 sec-ch-ua-platform "Windows" sec-fetch-dest empty sec-fetch-mode cors sec-fetch-site same-origin user-agent Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36这是谷歌浏览器导出文件的请求头 还是火狐浏览器导出的excel文件就有文件保护,谷歌浏览器导出的excel文件就没有
07-22
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值