java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > SpringBoot Filter修改返回内容,解决请求卡死200

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

作者: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,你好!

修改后

哈哈哈哈哈哈

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

问题原因

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

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

解决方法

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

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

总结

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

您可能感兴趣的文章:
阅读全文