应用代码
HttpResponsehttpResponse= ...; httpResponse.body();
body 源码
... /*** 获取响应主体* * @return String* @throws HttpException 包装IO异常*/publicStringbody() throwsHttpException { returnHttpUtil.getString(bodyBytes(), this.charset, null==this.charsetFromResponse); } /*** 获取响应流字节码<br>* 此方法会转为同步模式* * @return byte[]*/publicbyte[] bodyBytes() { sync(); returnthis.bodyBytes; } /*** 从流中读取内容<br>* 首先尝试使用charset编码读取内容(如果为空默认UTF-8),如果isGetCharsetFromContent为true,则通过正则在正文中获取编码信息,转换为指定编码;** @param contentBytes 内容byte数组* @param charset 字符集* @param isGetCharsetFromContent 是否从返回内容中获得编码信息* @return 内容*/publicstaticStringgetString(byte[] contentBytes, Charsetcharset, booleanisGetCharsetFromContent) { if (null==contentBytes) { returnnull; } if (null==charset) { charset=CharsetUtil.CHARSET_UTF_8; } Stringcontent=newString(contentBytes, charset); if (isGetCharsetFromContent) { finalStringcharsetInContentStr=ReUtil.get(META_CHARSET_PATTERN, content, 1); if (StrUtil.isNotBlank(charsetInContentStr)) { CharsetcharsetInContent=null; try { charsetInContent=Charset.forName(charsetInContentStr); } catch (Exceptione) { if (StrUtil.containsIgnoreCase(charsetInContentStr, "utf-8") ||StrUtil.containsIgnoreCase(charsetInContentStr, "utf8")) { charsetInContent=CharsetUtil.CHARSET_UTF_8; } elseif (StrUtil.containsIgnoreCase(charsetInContentStr, "gbk")) { charsetInContent=CharsetUtil.CHARSET_GBK; } // ignore } if (null!=charsetInContent&&false==charset.equals(charsetInContent)) { content=newString(contentBytes, charsetInContent); } } } returncontent; } ...
该死的代码
finalStringcharsetInContentStr=ReUtil.get(META_CHARSET_PATTERN, content, 1); /*** 正则:匹配meta标签的编码信息*/publicstaticfinalPatternMETA_CHARSET_PATTERN=Pattern.compile("<meta[^>]*?charset\\s*=\\s*['\"]?([a-z0-9-]*)", Pattern.CASE_INSENSITIVE);
貌似在说如果你的内容里有 charset 关键词的话就会匹配上,好吧,上一个反例但又是合情合理的业务场景,这个用例中就出现内容里含有这个,但是不能代表说我这个解析就要用这个编码呀!
{"content":"<meta http-equiv=\\\"Content-Type\\\" content=\\\"text/html; charset=utf-8\\\"></meta>"}
解决方案
/*** byte[] 转 String UTF-8* @param content*/publicstaticStringparseString(byte[] content) throwsUnsupportedEncodingException { returnnewString(content, CharsetNames.UTF_8); }