zoukankan      html  css  js  c++  java
  • 解决乱码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()之前设置,不然就会有乱码的问题

  • 相关阅读:
    学生党 应该去 研究研究 Socket(套接字) 实现原理
    收录一些 硬件 相关的 文章
    谈谈 软件 开源项目
    我决定 开启 一个 人工智能 机器学习 技术 的 普及项目 Let it Learn
    我邀请 民科吧 网友 和 三江老师 来 反相吧 辩论 调和级数
    共量子论 丢番图方程组 数值求解 最小分子解
    刚 看了一下 一元三次方程 的 解法
    研究发展 C 语言
    对 量子病态定理 提出的 代数方程 不成立 的 证明
    数学 改革
  • 原文地址:https://www.cnblogs.com/inkyi/p/15194653.html
Copyright © 2011-2022 走看看