IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> response contentType值的问题 -> 正文阅读

[网络协议]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:
在这里插入图片描述

  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2022-01-28 12:18:36  更:2022-01-28 12:18:54 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 10:14:55-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码