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();

总结

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

相关文章

  • Java中的FutureTask实现异步任务代码实例

    Java中的FutureTask实现异步任务代码实例

    这篇文章主要介绍了Java中的FutureTask实现异步任务代码实例,普通的线程执行是无法获取到执行结果的,FutureTask 间接实现了 Runnable 和 Future 接口,可以得到子线程耗时操作的执行结果,AsyncTask 异步任务就是使用了该机制,需要的朋友可以参考下
    2024-01-01
  • Java聊天室之实现聊天室服务端功能

    Java聊天室之实现聊天室服务端功能

    这篇文章主要为大家详细介绍了Java简易聊天室之实现聊天室服务端功能,文中的示例代码讲解详细,具有一定的借鉴价值,需要的可以了解一下
    2022-10-10
  • MyBatis学习教程(四)-如何快速解决字段名与实体类属性名不相同的冲突问题

    MyBatis学习教程(四)-如何快速解决字段名与实体类属性名不相同的冲突问题

    我们经常会遇到表中的字段名和表对应实体类的属性名称不一定都是完全相同的情况,如何解决呢?下面脚本之家小编给大家介绍MyBatis学习教程(四)-如何快速解决字段名与实体类属性名不相同的冲突问题,一起学习吧
    2016-05-05
  • Spring源码解析之BeanPostProcessor知识总结

    Spring源码解析之BeanPostProcessor知识总结

    今天给大家带来的文章是Spring的相关知识,文章围绕着BeanPostProcessor的使用展开,文中有非常详细的介绍,需要的朋友可以参考下
    2021-06-06
  • java实现堆的操作方法(建堆,插入,删除)

    java实现堆的操作方法(建堆,插入,删除)

    下面小编就为大家分享一篇java实现堆的操作方法(建堆,插入,删除),具有很好的参考价值,希望对大家有所帮助
    2017-12-12
  • Java使用iTextPDF生成PDF文件的实现方法

    Java使用iTextPDF生成PDF文件的实现方法

    这篇文章主要介绍了Java使用iTextPDF生成PDF文件的实现方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-02-02
  • SpringBoot实现Excel读取的实例教程

    SpringBoot实现Excel读取的实例教程

    这篇文章主要给大家介绍了关于SpringBoot实现Excel读取的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-12-12
  • SpringBoot 插件化开发模式详细总结

    SpringBoot 插件化开发模式详细总结

    插件化开发模式正在很多编程语言或技术框架中得以广泛的应用实践,大大提升了系统的扩展性和伸缩性,也拓展了系统整体的使用价值,那么为什么要使用插件呢,本文就详细介绍SpringBoot 插件化开发模式,感兴趣的同学可以参考下
    2023-06-06
  • Java String类字符串的理解与认知

    Java String类字符串的理解与认知

    String字符串和char字符不同,char使用单引号,只能表示一个字符,字符串就是一段文本。String是个类。这个类使用final修饰,所以这个类是不可以继承扩充和修改它的方法的
    2021-10-10
  • 使用SpringMVC访问Controller接口返回400BadRequest

    使用SpringMVC访问Controller接口返回400BadRequest

    这篇文章主要介绍了使用SpringMVC访问Controller接口返回400BadRequest,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-03-03

最新评论