SpringBoot Filter修改返回内容,解决请求卡死200的错误

 更新时间:2023年07月19日 10:25:35   作者:Meta39  
这篇文章主要介绍了SpringBoot Filter修改返回内容,解决请求卡死200的错误问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

SpringBoot Filter修改返回内容,解决请求卡死200

Filter

import org.springframework.stereotype.Component;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
/**
 * 过滤器
 */
@Component
@WebFilter(urlPatterns = "/*", filterName = "testFilter")
public class TestFilter implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {
        HSRW hsrw = new HSRW((HttpServletResponse) response);//获取返回内容
        filterChain.doFilter(request, hsrw);//一定要放到获取内容前面,否则会没有数据
        byte[] content = hsrw.getContent();//response流的内容
        String str = new String(content, StandardCharsets.UTF_8);
        System.out.println("原返回值:" + str);
        String newStr = "哈哈哈哈哈哈";
        //修改返回内容长度,解决返回内容长度不一致导致请求卡住的问题
        response.setContentLength(newStr.getBytes(StandardCharsets.UTF_8).length);//这里要注意:setContentLength(字符串的字节长度,不是字符串的长度)
        //修改完写入输出流,返回给前端
        //JDK8写法
        try (ServletOutputStream out = response.getOutputStream()) {
            out.write(newStr.getBytes(StandardCharsets.UTF_8));//写入返回内容
            out.flush();//刷新
        }
        //JDK8之前的写法
        /*ServletOutputStream out = response.getOutputStream();
        out.write(newStr.getBytes(StandardCharsets.UTF_8));//写入返回内容
        out.flush();//刷新
        out.close();//关闭流*/
    }
}

继承HttpServletResponseWrapper重写方法获取返回内容

import javax.servlet.ServletOutputStream;
import javax.servlet.WriteListener;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import java.io.*;
public class HSRW extends HttpServletResponseWrapper {
    private final ByteArrayOutputStream buffer;
    private final ServletOutputStream out;
    public HSRW(HttpServletResponse httpServletResponse) {
        super(httpServletResponse);
        buffer = new ByteArrayOutputStream();
        out = new WrapperOutputStream(buffer);
    }
    @Override
    public ServletOutputStream getOutputStream() {
        return out;
    }
    @Override
    public void flushBuffer() throws IOException {
        if (out != null) {
            out.flush();
        }
    }
    public byte[] getContent() throws IOException {
        flushBuffer();
        return buffer.toByteArray();
    }
    static class WrapperOutputStream extends ServletOutputStream {
        private final ByteArrayOutputStream bos;
        public WrapperOutputStream(ByteArrayOutputStream bos) {
            this.bos = bos;
        }
        @Override
        public void write(int b) {
            bos.write(b);
        }
        @Override
        public boolean isReady() {
            return false;
        }
        @Override
        public void setWriteListener(WriteListener arg0) {
        }
    }
}

测试

没修改前

Meta,你好!

修改后

哈哈哈哈哈哈

  • 修改完内容卡200是因为没有重新设置内容长度
  • 修改完内容返回中文乱码问题,其实不是乱码问题是你设置的长度不是字符串的字节长度导致的。改成字符串的字节长度即可。
  • 没有数据可能是filterChain.doFilter(request, hsrw);位置放错了,要放到获取内容之前,如果放到获取内容之后,则相当于获取的内容为空

SpringBoot使用过滤器Filter,修改返回值会出现返回值截断缺失

问题原因

原本的ServletResponse response中Content长度小于修改的长度。

当使用ServletOutputStream out修改返回值的时候,超过原Content长度的部分会被截断

解决方法

是在将新内容写入前改变Content的长度:

response.setContentLength(strChange.length());
ServletOutputStream out = response.getOutputStream();
out.write(strChange.getBytes());
out.flush();

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Spring Boot2.6.0新特性之默认禁止循环引用

    Spring Boot2.6.0新特性之默认禁止循环引用

    Spring Boot2.6.0为我们带来很多好用的新特性/改进,这篇文章主要给大家介绍了关于Spring Boot2.6.0新特性之默认禁止循环引用的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-02-02
  • Java构建乘积数组的方法

    Java构建乘积数组的方法

    这篇文章主要为大家详细介绍了Java构建乘积数组的方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-03-03
  • java字符串与格式化输出的深入分析

    java字符串与格式化输出的深入分析

    本篇文章是对java字符串与格式化输出进行了详细的分析介绍,需要的朋友参考下
    2013-06-06
  • springMVC利用FastJson接口返回json数据相关配置详解

    springMVC利用FastJson接口返回json数据相关配置详解

    本篇文章主要介绍了springMVC利用FastJson接口返回json数据相关配置详解,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-06-06
  • Java实现Word、Excel、PDF文件在线预览几种实现方式

    Java实现Word、Excel、PDF文件在线预览几种实现方式

    在Web开发中,经常需要实现文件的在线预览功能,比如预览PDF、Word、Excel等文档格式,这篇文章主要介绍了Java实现Word、Excel、PDF文件在线预览几种实现方式的相关资料,需要的朋友可以参考下
    2025-12-12
  • 浅谈Java安全编码之文件和共享目录的安全性

    浅谈Java安全编码之文件和共享目录的安全性

    Java程序是跨平台的,可以运行在windows也可以运行在linux。但是平台不同,平台中的文件权限也是不同的。windows大家经常使用,并且是可视化的权限管理,这里就不多讲了。本文主要讲讲linux下面的文件的权限和安全性问题,并且探讨一下如何在java程序中考虑文件的安全性
    2021-06-06
  • Java switch语句的使用详解

    Java switch语句的使用详解

    Java switch语句随JDK演进支持int/char、String及模式匹配,具备表达式限制、穿透控制、作用域隔离等特性,适用于状态机、命令解析等场景,需注意类型兼容性及break使用,推荐使用箭头语法和编译器优化提升代码质量
    2025-07-07
  • Java反射如何修改private final成员变量值

    Java反射如何修改private final成员变量值

    这篇文章主要介绍了Java反射如何修改private final成员变量值,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-07-07
  • 详解Java中Array和ArrayList的比较和转换

    详解Java中Array和ArrayList的比较和转换

    在 Java 编程中,arrays 和 arraylists 都是基本的数据结构,用来存放数据集合,虽然两者的用途一样,但是它们的特点极大地影响应用的性能和灵活性,本文探讨 arrays 和 arraylists 的重要特性,它们各自的强项和弱点,,需要的朋友可以参考下
    2023-08-08
  • 解析Mybatis Porxy动态代理和sql解析替换问题

    解析Mybatis Porxy动态代理和sql解析替换问题

    这篇文章主要介绍了Mybatis Porxy动态代理和sql解析替换,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-04-04

最新评论