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 boot mybatis全注解化

    详解spring boot mybatis全注解化

    这篇文章主要介绍了spring boot mybatis全注解化的相关资料,需要的朋友可以参考下
    2017-09-09
  • Intellij IDEA安装lombok插件及使用详解

    Intellij IDEA安装lombok插件及使用详解

    今天小编就为大家分享一篇关于Intellij IDEA安装lombok插件及使用详解,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2018-12-12
  • Kotlin 基础语法详细介绍

    Kotlin 基础语法详细介绍

    这篇文章主要介绍了Kotlin 基础语法详细介绍的相关资料,需要的朋友可以参考下
    2017-05-05
  • java实现简单的给sql语句赋值的示例

    java实现简单的给sql语句赋值的示例

    这篇文章主要介绍了java实现简单的给sql语句赋值的示例,需要的朋友可以参考下
    2014-05-05
  • Java枚举(enum) 详解7种常见的用法

    Java枚举(enum) 详解7种常见的用法

    这篇文章主要介绍了Java枚举(enum) 详解7种常见的用法,具有一定的参考价值,有需要的可以了解一下。
    2016-11-11
  • Java应用程序CPU100%问题排查优化实战

    Java应用程序CPU100%问题排查优化实战

    这篇文章主要介绍了如何排查和优化Java应用程序CPU使用率达到100%的问题,文中通过代码示例和图文结合的方式讲解的非常详细,具有一定的参考价值,需要的朋友可以参考下
    2025-02-02
  • Spring异常捕获且回滚事务解决方案

    Spring异常捕获且回滚事务解决方案

    这篇文章主要介绍了Spring异常捕获且回滚事务解决方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-06-06
  • Java多线程之线程状态的迁移详解

    Java多线程之线程状态的迁移详解

    线程状态迁移,又常被称作线程的生命周期,指的是线程从创建到终结需要经历哪些状态,什么情况下会出现哪些状态.线程的状态直接关系着并发编程的各种问题,本文就线程的状态迁移做一初步探讨,并总结在何种情况下会出现这些状态,需要的朋友可以参考下
    2021-06-06
  • Alibaba Fastjson之超好用的JOSN解析库

    Alibaba Fastjson之超好用的JOSN解析库

    这篇文章主要介绍了Alibaba Fastjson之超好用的JOSN解析库,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-10-10
  • 继承jpa Repository 写自定义方法查询实例

    继承jpa Repository 写自定义方法查询实例

    这篇文章主要介绍了继承jpa Repository 写自定义方法查询实例,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-12-12

最新评论