解决乱码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