response contentType值的问题

关于 reponse 返回类型 contentType 是 application/json;charset=ISO-8859-1 现象的阐述

现象发生描述:

在 Interceptor 的 preHandle 方法对 response 设置 contentType和charset

response.setContentType(MediaType.APPLICATION_JSON_VALUE);
response.setCharacterEncoding("UTF-8");

之后,发现了浏览器F12页面中的请求结果的 responseHeader 中 contentType 属性始终是 application/json;charset=ISO-8859-1 ,并不符合预期结果,最终结果的应该是 application/json;charset=UTF-8 才是理想的啊。

排查:

经过对上述代码代码以及上下文代码进行debug,最终通过源码逻辑获得到了编码始终不对的原因。

原因:

产生问题时的代码:

PrintWriter writer = response.getWriter();
response.setContentType(MediaType.APPLICATION_JSON_VALUE);
response.setCharacterEncoding("UTF-8");

处理之后的代码:

response.setContentType(MediaType.APPLICATION_JSON_VALUE);
response.setCharacterEncoding("UTF-8");
PrintWriter writer = response.getWriter();

对比代码可以看到,没错!就是 response.getWriter(); 这句代码的执行顺序导致的,它是在设置类型和编码之前还是之后!

那为什么先调用 response.getWriter(); 就会导致设置的编码类型不成功呢?来看源码:

org.apache.catalina.connector.Response#getWriter

    @Override
    public PrintWriter getWriter()
        throws IOException {

        if (usingOutputStream) {
            throw new IllegalStateException
                (sm.getString("coyoteResponse.getWriter.ise"));
        }
				// 看这个if,这个是问题产生的核心内容
        if (ENFORCE_ENCODING_IN_GET_WRITER) {
            /*
             * If the response's character encoding has not been specified as
             * described in <code>getCharacterEncoding</code> (i.e., the method
             * just returns the default value <code>ISO-8859-1</code>),
             * <code>getWriter</code> updates it to <code>ISO-8859-1</code>
             * (with the effect that a subsequent call to getContentType() will
             * include a charset=ISO-8859-1 component which will also be
             * reflected in the Content-Type response header, thereby satisfying
             * the Servlet spec requirement that containers must communicate the
             * character encoding used for the servlet response's writer to the
             * client).
             */
            setCharacterEncoding(getCharacterEncoding());
        }

        usingWriter = true;
        outputBuffer.checkConverter();
        if (writer == null) {
            writer = new CoyoteWriter(outputBuffer);
        }
        return writer;
    }

首先看注释,注释中就描述了“如果未制定response的编码,就默认为ISO-8859-1”。

并且会执行 usingWriter = true; 语句,记住这句,一会就用到了。

其次看代码 setCharacterEncoding(getCharacterEncoding()); 内容:

org.apache.catalina.connector.Response#getCharacterEncoding:
在这里插入图片描述

org.apache.catalina.connector.Response#setCharacterEncoding:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值