CloseableHttpClient获取文件名乱码解决

          最近在用httpclient获取服务器上文件的文件名时,当文件名是中文时乱码。乱码的话,肯定是编解码集不一致导致的。

通常咱们在使用HttClient进行文件下载时,须要获取到文件的名称及类型,可是不少时候提供给咱们的url中是不包含这些信息的,因此须要经过HttpResponse中的信息来获取这些。code

将上面下载时获取的response做为参数进行传递。

/**
 * 获取response header中Content-Disposition中的filename值
 * @param response
 * @return
 */
    private String getFileName(HttpResponse response) {
    Header contentHeader = response.getFirstHeader("Content-Disposition");
    String filename = UUID.randomUUID().toString().replace("-","");
    if (contentHeader != null) {
       HeaderElement[] values = contentHeader.getElements();
       if (values.length == 1) {
          NameValuePair param = values[0].getParameterByName("filename");
          if (param != null) {
             try {
                String code1 = "windows-1252";
                String code2 = "ISO-8859-1";
                String name = param.getValue();

                //判断如今的编码格式
                if(name.equals(new String(name.getBytes(code1),code1))){
                   //GBK为铁塔在Content-Disposition中filename使用的编码格式
                   filename = new String(name.getBytes(code1), "GBK");

                   if(!EncodeUtils.isLetterDigitOrChinese(filename)){
                      filename=URLDecoder.decode(param.getValue(),"utf-8");
                   }
                }else if(name.equals(new String(name.getBytes(code2),code2))){
                   filename = new String(name.getBytes(code2), "GBK");
                   if(!EncodeUtils.isLetterDigitOrChinese(filename)){
                      filename=URLDecoder.decode(param.getValue(),"utf-8");
                      if(!EncodeUtils.isLetterDigitOrChinese(filename)){
                         filename=URLDecoder.decode(param.getValue(),"utf-8");
                      }
                   }
                }
                //filename = param.getValue();
             } catch (Exception e) {
                e.printStackTrace();
             }
          }
       }
    }
    return filename;
 }

通常咱们获取到的信息,若是没有进行特殊处理,都是默认的ISO-8859-1编码格式的,可是在windows10的系统下,有时会将ISO-8859-1编码认为是window-1252进行传递(这也是个坑)。这样就会致使在进行解码时,解出来的仍是乱码。blog

这里我针对传递的参数通过了GBK编码和普通编码的处理,不针对全部的乱码都能解决,可是对一些按照正常解码方式还没法进行解码的能够尝试用这种方式进行解码。

通常的解码方式:filename = URLDecoder.decode(param.getValue(),"UTF-8");

或者:filename = new String(param.getValue().getBytes(),"UTF-8");

上面的isLetterDigitOrChinese:是我自定义的一个判断解析后的文件名是否符合要求的正则。

/** 判断是否只包含数字,字母,汉字和英文的(),.,-,_ 和中文的()**/
public static boolean isLetterDigitOrChinese(String str) {
    String regex = "^[a-z_0-9A-Z-.()()\u4e00-\u9fa5]+$";//其余须要,直接修改正则表达式就好
    return str.matches(regex);
}

上面一段是百度的,但是还是没有解决问题。那就只能自己解决问题了。

乱码,首先要知道字符的原来编码,以及现在的编码,这样问题就迎刃而解了。

推荐一个网站,乱码猜测,识别原来乱码的字符编码集

http://www.mytju.com/classcode/tools/messyCodeRecover.asp

通过上面的结果,我们就能知道字符编码格式,再进行编码。问题就解决了

这里我项目HttpClient原来的编码是IOS_8859_1,现在的编码格式是UTF-8

            HttpGet httpget = new HttpGet(url);
			CloseableHttpClient httpclient = HttpClientBuilder.create().build();
			//配置请求的超时设置
			RequestConfig requestConfig = RequestConfig.custom()
					.setConnectionRequestTimeout(10000)
					.setConnectTimeout(10000)
					.setSocketTimeout(10000).build();
			httpget.setConfig(requestConfig);
			CloseableHttpResponse response = httpclient.execute(httpget);
			Header contentHeader = response.getFirstHeader("Content-Disposition");
			HeaderElement[] elements = contentHeader.getElements();
			HeaderElement[] values = contentHeader.getElements();
			NameValuePair filename = values[0].getParameterByName("filename");
			String name = new String(filename.getValue().getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8);

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值