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 Hibernate中的查询策略和抓取策略

    Java Hibernate中的查询策略和抓取策略

    Hibernate是一种Java对象关系映射框架,提供了多种查询和抓取策略,用于优化数据库访问性能。查询策略包括延迟加载、立即加载、查询缓存等,抓取策略包括join抓取、子查询抓取、批量抓取等。这些策略可以根据实际应用场景进行选择和配置,提高数据访问的效率和稳定性
    2023-04-04
  • java中压缩文件并下载的实例详解

    java中压缩文件并下载的实例详解

    在本篇内容里小编给大家整理的是一篇关于java中压缩文件并下载的实例详解内容,有兴趣的朋友们可以学习下。
    2021-02-02
  • Spring Cloud Alibaba 本地调试介绍及方案设计

    Spring Cloud Alibaba 本地调试介绍及方案设计

    为了解决 本地调试 的问题,本文实现了一种简单实用的策略,可以通过 Nacos 动态配置服务路由,还可以基于用户,部门,组织等级别配置服务路由,实现 本地调试 的同时,实际上也实现 灰度发布,感兴趣的朋友跟随小编一起看看吧
    2021-07-07
  • JavaWeb之监听器案例讲解

    JavaWeb之监听器案例讲解

    这篇文章主要介绍了JavaWeb之监听器案例讲解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-08-08
  • SpringBoot+MyBatisPlus+MySQL8实现树形结构查询

    SpringBoot+MyBatisPlus+MySQL8实现树形结构查询

    这篇文章主要为大家详细介绍了SpringBoot+MyBatisPlus+MySQL8实现树形结构查询,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-06-06
  • Spring boot 集成Dubbox的方法示例

    Spring boot 集成Dubbox的方法示例

    本篇文章主要介绍了Spring boot 集成Dubbox的方法示例,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-05-05
  • JAVAEE项目结构以及并发随想

    JAVAEE项目结构以及并发随想

    每个代码里面的工具都是工具,API是你最需要理解的,哪个好,哪个不好,没有准确答案。 一切皆对象,对于Java来讲是纯粹的,代理是对象,反射是对象,对象是对象,基本数据类型不是对象。
    2016-04-04
  • SpringBoot整合Spring Security构建安全的Web应用

    SpringBoot整合Spring Security构建安全的Web应用

    pring Security是一个强大的身份验证和访问控制框架,本文主要介绍了SpringBoot整合Spring Security构建安全的Web应用,具有一定的参考价值,感兴趣的可以了解一下
    2024-01-01
  • Java编程小实例—数字时钟的实现代码示例

    Java编程小实例—数字时钟的实现代码示例

    正所谓拳不离手曲不离口,java学习的过程中,练习还是要多一点比较好。接下来分享给大家一个Java编程的小实例,供朋友们参考。
    2017-10-10
  • java常见的字符串拼接方式总结

    java常见的字符串拼接方式总结

    这篇文章主要为大家详细介绍了java中常见的字符串拼接方式,文中的示例代码讲解详细,具有一定的借鉴价值,感兴趣的小伙伴可以跟随小编一起学习一下
    2023-09-09

最新评论