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);
        }
    }
发布了37 篇原创文章 · 获赞 25 · 访问量 18万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览