今天在寫攔截器的時候,如果判斷用戶未登錄,直接返回一個錯誤碼,提醒用戶登錄。
但是在前端接收的提示信息中,結果是
{code: "58888", msg: "???"}
這里的???應該是請登錄
檢查一下工具類,發現工具類里面是設置過編碼
public static void writeJson(HttpServletResponse response , Object content ) throws IOException {
try(PrintWriter out = response.getWriter()){
response.setContentType(MediaType.APPLICATION_JSON_VALUE);
response.setCharacterEncoding("UTF-8");
String returnText = JSONObject.toJSONString(content, SerializerFeature.DisableCircularReferenceDetect);
out.write(returnText);
out.flush();
}
}
然后又檢查了一下,頁面上的response headers的信息
編碼集變成了 ISO-8859-1
說明代碼里,設置編碼集的代碼沒有生效。
點進源碼看看到底為啥沒生效。
public void setCharacterEncoding(final String charset) {
// writer != null , 就不會再設置編碼集了
if (insideInclude || responseStarted() || writer != null || isCommitted()) {
return;
}
charsetSet = charset != null;
this.charset = charset;
if (contentType != null) {
exchange.getResponseHeaders().put(Headers.CONTENT_TYPE, getContentType());
}
}
如果writer對象不是空,就不會再設置編碼集。
所以response.setCharacterEncoding("UTF-8");
代碼要在response.getWriter()
之前調用,不然編碼不會生效。
順便再看一下getWriter() 方法都干了啥?
public PrintWriter getWriter() throws IOException {
if (writer == null) {
// 如果編碼沒有set,設置編碼
// getCharacterEncoding() 如果web-app,container都沒有設置編碼集,就默認ISO_8859_1
if (!charsetSet) {
//servet 5.5
setCharacterEncoding(getCharacterEncoding());
}
if (responseState == ResponseState.STREAM) {
throw UndertowServletMessages.MESSAGES.getOutputStreamAlreadyCalled();
}
responseState = ResponseState.WRITER;
createOutputStream();
final ServletPrintWriter servletPrintWriter = new ServletPrintWriter(servletOutputStream, getCharacterEncoding());
writer = ServletPrintWriterDelegate.newInstance(servletPrintWriter);
}
return writer;
}
public String getCharacterEncoding() {
if (charset != null) {
return charset;
}
// first check, web-app context level default response encoding
if (servletContext.getDeployment().getDeploymentInfo().getDefaultResponseEncoding() != null) {
return servletContext.getDeployment().getDeploymentInfo().getDefaultResponseEncoding();
}
// now check the container level default encoding
if (servletContext.getDeployment().getDeploymentInfo().getDefaultEncoding() != null) {
return servletContext.getDeployment().getDeploymentInfo().getDefaultEncoding();
}
// if no explicit encoding is specified, this method is supposed to return ISO-8859-1 as per the
// expectation of this API
return StandardCharsets.ISO_8859_1.name();
}
綜上所述,編碼集要在getWriter()
之前設置,不然就會有亂碼的問題