解決亂碼setCharacterEncoding("UTF-8")不生效的問題


今天在寫攔截器的時候,如果判斷用戶未登錄,直接返回一個錯誤碼,提醒用戶登錄。

但是在前端接收的提示信息中,結果是

{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()之前設置,不然就會有亂碼的問題


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM