Java解决下载中文乱码和URL中文乱码问题

解决浏览器下载中文乱码和URL中文乱码问题

下载中文乱码问题

中文乱码是个让人头痛的问题,这里整理针对下载时,中文乱码问题,下面是Java对应的实现,均已测试OK

 response.reset();
            response.setContentType("application/octet-stream");
            response.setCharacterEncoding(StandardCharsets.UTF_8.name());
            // 关键代码
            String fileName = HttpUtils.encodeAttachmentName(fileResponse.getOriginFileName(), request) ;
            response.addHeader("Content-Disposition", "attachment; filename=" + fileName);
            response.setHeader("Accept-ranges", "bytes");

HttpUtils.encodeAttachmentName实现:

public static String encodeAttachmentName(String fileName , HttpServletRequest request) {
        String enableFileName = fileName ;
        try {
            String userAgent = request.getHeader("User-Agent");
            if(StringUtils.isBlank(userAgent)){
                enableFileName = URLEncoder.encode(fileName, StandardCharsets.UTF_8.name()).replace("+", "%20").replace("*", "%2A").replace("~", "%7E");
            } else if (userAgent.indexOf("Firefox") > -1 ) {
                // Firefox
                enableFileName = "=?UTF-8?B?" + (new String(Base64.encodeBase64(fileName.getBytes(StandardCharsets.UTF_8)))) + "?=";
            } else if (userAgent.indexOf("Safari") > -1 || userAgent.toUpperCase().indexOf("MSIE") > -1) {
                // Safari Or IE
                enableFileName = new String(fileName.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1);
            } else {
                // 其他浏览器
                enableFileName = URLEncoder.encode(fileName, StandardCharsets.UTF_8.name()).replace("+", "%20").replace("*", "%2A").replace("~", "%7E");
            }
        } catch (Exception e){
            LOGGER.warn("Failed To encode file name", e);
            throw new IllegalArgumentException("Failed To encode file name", e);
        }

        return enableFileName ;
    }

注:

  1. 火狐浏览器Firefox,只支持 enableFileName = "=?UTF-8?B?" + (new String(Base64.encodeBase64(fileName.getBytes(StandardCharsets.UTF_8)))) + "?="; 这种方式;
  2. Safari 浏览器,只支持 enableFileName = new String(fileName.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1)
  3. Chrome 浏览器,可以支持 enableFileName = new String(fileName.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1)enableFileName = URLEncoder.encode(fileName, StandardCharsets.UTF_8.name())
  4. 其他类型的浏览器,统一使用URLEncoder.encode的方式,这种方式可保证中文时不会出现乱码情况

URL路径中含有中文处理方式:

public static String uriEncode(String urlPath, String encoding) {
        StringBuffer resultUri = new StringBuffer();
        String[] keys = urlPath.split("/");
        resultUri.append(urlEncode(keys[0], encoding));
        for (int i = 1; i < keys.length; i++) {
            resultUri.append("/").append(urlEncode(keys[i], encoding));
        }
        if (urlPath.endsWith("/")) {
            // String#split ignores trailing empty strings,
            // e.g., "a/b/" will be split as a 2-entries array,
            // so we have to append all the trailing slash to the uri.
            for (int i = urlPath.length() - 1; i >= 0; i--) {
                if (urlPath.charAt(i) == '/') {
                    resultUri.append("/");
                } else {
                    break;
                }
            }
        }
        return resultUri.toString();
    }

    /**
     * Encode a URL segment with special chars replaced.
     */
    public static String urlEncode(String url, String encoding) {
        if (StringUtils.isBlank(url)) {
            return "";
        }
        try {
            String encoded = URLEncoder.encode(url, encoding);
            return encoded.replace("+", "%20").replace("*", "%2A").replace("~", "%7E").replace("/", "%2F");
        } catch (UnsupportedEncodingException e) {
            throw new IllegalArgumentException("Failed To Encode Uri", e);
        }
    }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值