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();
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。
