解决乱码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()之前设置,不然就会有乱码的问题

posted @   InkYi  阅读(2075)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端
· AI Agent开发,如何调用三方的API Function,是通过提示词来发起调用的吗
点击右上角即可分享
微信分享提示