• 记SpringBoot拦截器报错getWriter() has already been called for this response



    title: 记 SpringBoot 拦截器报错 getWriter() has already been called for this response
    date: 2022-09-01 10:40:59
    tags:

    • SpringBoot
      categories:
    • 问题记录
      cover: https://cover.png
      feature: false

    1. 问题

    在拦截器中返回信息时,使用 response.getWriter() 报错 getWriter() has already been called for this response。这里使用的 getWriter()操作的是字符,所以使用 print()write()都可以(print()wirte区别见 3)

    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述

    2. 原因分析

    这里先确定一个前提,上面的拦截器返回的是 true,还会走后面的拦截器或过滤器,假如返回 false 直接结束,则不会有上述问题。 通过跟踪 getWriter()方法,在类 Response.class 源码中

    在这里插入图片描述

    可以看到在调用 getWriter()方法时,首先会判断 usingOutputStream,如果是 true,就抛出异常,否则设置 usingWriter=true;。所以调用 getWriter()方法后,会导致:usingWriter=true;

    同样在类 Response.class 源码中再查看 getOutputStream()的源码

    在这里插入图片描述

    可以看到在调用 getOutputStream()方法时,首先会判断 usingWriter,如果是 true,就抛出异常,否则设置 usingOutputStream=true;。所以调用 getOutputStream()方法后,会导致:usingOutputStream=true;

    在这样的设定下,就无法同时使用 getWriter()getOutputStream() 方法,调用其中一个之后必然会使其标记为 true,从而调用另一个方法时会报错

    之所以两者互相排斥,调用一个方法后不能再调用另一方法,因为 getWriter()是字符流,getOutputStream()是字节流,缓存区不可能同时存在两种格式

    3. 解决

    在所有的 Filter 和 Interceptor 中,要么都使用 getWriter() 方法,要么都使用 getOutputStream() 方法,不能两者都使用

    我这里后面并没有再自定义拦截器或过滤器,推测 SpringBoot 可能默认使用的是 getOutputStream()返回白页等信息,而我并没有 retrun false,同时存在两种格式导致报错。重新修改如下(测试 return false 时下图忘记改成 return true 了,但不影响引出问题):

    在这里插入图片描述

    这里使用的是 print(),会报错 Not an ISO 8859-1 character,因为 Stream 输出的是二进制流,没有对字符进行编码,Stream 只适用于 ISO 8859-1编码的字符。Writer 输出的是文本的信息, 是进行过系统编码后的

    在这里插入图片描述

    使用 write() ,将数据用字节传输则正常

    在这里插入图片描述

    在这里插入图片描述

  • 相关阅读:
    物联网通信技术|课堂笔记|week10-2 11月1日|应用层协议|域名解析
    Vue组件知识点详解(组件创建、组件通信)
    酒店管理系统|基于java和小程序的酒店管理小程序系统设计与实现(源码+数据库+文档)
    音视频进阶教程-实现直播SEI补充增强信息
    浅析React Hook之useReducer
    数据库性能翻3倍:Redis on Flash分层存储技术是如何做到的?
    霍夫曼树(Huffman Tree)
    Spring Boot 集成 Redis 配置 MyBatis 二级缓存
    使用Python和BeautifulSoup提取网页数据的实用技巧
    PHP8.1新特性大讲解之initializers初始化器
  • 原文地址:https://blog.csdn.net/ACE_U_005A/article/details/126637958