问题
线上海外有非中文或者英文,如果发送HTTP请求时,使用json格式,但是没有指定字符集,而服务端在解析的时候使用Jackson反序列化的时候,会有反序列化失败的情况。
HttpPost httpPost = new HttpPost(uri);
httpPost.setConfig(requestConfig);
StringEntity entity = new StringEntity(JsonUtils.toJSON(object), ContentType.APPLICATION_JSON);
//ByteArrayEntity entity = new ByteArrayEntity(JsonUtils.toJSON(object).getBytes(StandardCharsets.UTF_8));
//entity.setContentEncoding("UTF-8");
//没必要重复设置,因为在StringEntity已经设置了。
//entity.setContentType("application/json;charset=UTF-8");
httpPost.setEntity(entity);
return httpClient.execute(httpPost, handler);
如果只是使用StringEntity entity = new StringEntity(JsonUtils.toJSON(object));会有服务端反序列化失败的问题。
/**
* Creates a StringEntity with the specified content. The content type defaults to
* {@link ContentType#TEXT_PLAIN}.
*
* @param string content to be used. Not {@code null}.
*
* @throws IllegalArgumentException if the string parameter is null
* @throws UnsupportedEncodingException if the default HTTP charset is not supported.
*/
public StringEntity(final String string)
throws UnsupportedEncodingException {
this(string, ContentType.DEFAULT_TEXT);
}
public static final ContentType DEFAULT_TEXT = TEXT_PLAIN;
// 默认字符集为ISO_8859_1
public static final ContentType TEXT_PLAIN = create(
"text/plain", Consts.ISO_8859_1);
// JSON的字符集为UTF_8
public static final ContentType APPLICATION_JSON = create(
"application/json", Consts.UTF_8);
public StringEntity(final String string, final ContentType contentType) throws UnsupportedCharsetException {
super();
Args.notNull(string, "Source string");
Charset charset = contentType != null ? contentType.getCharset() : null;
if (charset == null) {
charset = HTTP.DEF_CONTENT_CHARSET;
}
// 关键问题在此!!!
this.content = string.getBytes(charset);
if (contentType != null) {
// 所以在业务代码上,没必要重复设置
setContentType(contentType.toString());
}
}
Jackson在反序列化的时候会探测反序列化内容的字符集。
Content-Type
用于定义消息体的类型:常见的如application/json,text/plain。
Content-Encoding
content-encoding表示的是压缩算法,一般只出现在服务端。浏览器通过Accept-Encoding告知服务端,浏览器可以支持的压缩算法,服务端从中选择一种,将返回内容按照该压缩算法压缩内容,返回给浏览器。浏览器按照response中的Content-Encoding来解压缩。
客户端也可以将请求体进行压缩,但是需要服务端自己支持。