关于 reponse 返回类型 contentType 是 application/json;charset=ISO-8859-1 现象的阐述
现象发生描述:
在 Interceptor 的 preHandle 方法对 response 设置 contentType和charset
response.setContentType(MediaType.APPLICATION_JSON_VALUE);
response.setCharacterEncoding("UTF-8");
之后,发现了浏览器F12页面中的请求结果的 responseHeader 中 contentType 属性始终是 application/json;charset=ISO-8859-1 ,并不符合预期结果,最终结果的应该是 application/json;charset=UTF-8 才是理想的啊。
排查:
经过对上述代码代码以及上下文代码进行debug,最终通过源码逻辑获得到了编码始终不对的原因。
原因:
产生问题时的代码:
PrintWriter writer = response.getWriter();
response.setContentType(MediaType.APPLICATION_JSON_VALUE);
response.setCharacterEncoding("UTF-8");
处理之后的代码:
response.setContentType(MediaType.APPLICATION_JSON_VALUE);
response.setCharacterEncoding("UTF-8");
PrintWriter writer = response.getWriter();
对比代码可以看到,没错!就是 response.getWriter(); 这句代码的执行顺序导致的,它是在设置类型和编码之前还是之后!
那为什么先调用 response.getWriter(); 就会导致设置的编码类型不成功呢?来看源码:
org.apache.catalina.connector.Response#getWriter:
@Override
public PrintWriter getWriter()
throws IOException {
if (usingOutputStream) {
throw new IllegalStateException
(sm.getString("coyoteResponse.getWriter.ise"));
}
if (ENFORCE_ENCODING_IN_GET_WRITER) {
setCharacterEncoding(getCharacterEncoding());
}
usingWriter = true;
outputBuffer.checkConverter();
if (writer == null) {
writer = new CoyoteWriter(outputBuffer);
}
return writer;
}
首先看注释,注释中就描述了“如果未制定response的编码,就默认为ISO-8859-1”。
并且会执行 usingWriter = true; 语句,记住这句,一会就用到了。
其次看代码 setCharacterEncoding(getCharacterEncoding()); 内容:
org.apache.catalina.connector.Response#getCharacterEncoding:
org.apache.catalina.connector.Response#setCharacterEncoding:
|