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,你好!
修改后
哈哈哈哈哈哈
- 修改完内容卡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();
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。