JavaWeb - Hutool Bug HttpResponse body 方法中文乱码

Posted 程序员牧码

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaWeb - Hutool Bug HttpResponse body 方法中文乱码相关的知识,希望对你有一定的参考价值。

应用代码

​HttpResponse httpResponse = ...;
httpResponse.body();

body 源码

...

/**
 * 获取响应主体
 * 
 * @return String
 * @throws HttpException 包装IO异常
 */
public String body() throws HttpException {
	return HttpUtil.getString(bodyBytes(), this.charset, null == this.charsetFromResponse);
}

/**
 * 获取响应流字节码<br>
 * 此方法会转为同步模式
 * 
 * @return byte[]
 */
public byte[] bodyBytes() {
	sync();
	return this.bodyBytes;
}

/**
 * 从流中读取内容<br>
 * 首先尝试使用charset编码读取内容(如果为空默认UTF-8),如果isGetCharsetFromContent为true,则通过正则在正文中获取编码信息,转换为指定编码;
 *
 * @param contentBytes            内容byte数组
 * @param charset                 字符集
 * @param isGetCharsetFromContent 是否从返回内容中获得编码信息
 * @return 内容
 */
public static String getString(byte[] contentBytes, Charset charset, boolean isGetCharsetFromContent) {
	if (null == contentBytes) {
		return null;
	}

	if (null == charset) {
		charset = CharsetUtil.CHARSET_UTF_8;
	}
	String content = new String(contentBytes, charset);
	if (isGetCharsetFromContent) {
		final String charsetInContentStr = ReUtil.get(META_CHARSET_PATTERN, content, 1);
		if (StrUtil.isNotBlank(charsetInContentStr)) {
			Charset charsetInContent = null;
			try {
				charsetInContent = Charset.forName(charsetInContentStr);
			} catch (Exception e) {
				if (StrUtil.containsIgnoreCase(charsetInContentStr, "utf-8") || StrUtil.containsIgnoreCase(charsetInContentStr, "utf8")) {
					charsetInContent = CharsetUtil.CHARSET_UTF_8;
				} else if (StrUtil.containsIgnoreCase(charsetInContentStr, "gbk")) {
					charsetInContent = CharsetUtil.CHARSET_GBK;
				}
				// ignore
			}
			if (null != charsetInContent && false == charset.equals(charsetInContent)) {
				content = new String(contentBytes, charsetInContent);
			}
		}
	}
	return content;
}

...

该死的代码

final String charsetInContentStr = ReUtil.get(META_CHARSET_PATTERN, content, 1);

/**
 * 正则:匹配meta标签的编码信息
 */
public static final Pattern META_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
 */
public static String parseString(byte[] content) throws UnsupportedEncodingException {
    return new String(content, CharsetNames.UTF_8);
}

以上是关于JavaWeb - Hutool Bug HttpResponse body 方法中文乱码的主要内容,如果未能解决你的问题,请参考以下文章

Hutool 3.0.8 发布,Java 工具集

HttpClient报错cn.hutool.http.HttpException: Read timed out

通过Hutool 调用远程API接口(POST/GET)

Tomcat运行javaweb项目时出现的一个bug

JavaUtil_07_HttpUtil_使用Hutool 封装的 HttpUtil

Javaweb项目开发的前后端解耦的必要性