SpringBoot Filter修改返回內(nèi)容,解決請求卡死200的錯誤
更新時間:2023年07月19日 10:25:35 作者:Meta39
這篇文章主要介紹了SpringBoot Filter修改返回內(nèi)容,解決請求卡死200的錯誤問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
SpringBoot Filter修改返回內(nèi)容,解決請求卡死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);//獲取返回內(nèi)容
? ? ? ? filterChain.doFilter(request, hsrw);//一定要放到獲取內(nèi)容前面,否則會沒有數(shù)據(jù)
? ? ? ? byte[] content = hsrw.getContent();//response流的內(nèi)容
? ? ? ? String str = new String(content, StandardCharsets.UTF_8);
? ? ? ? System.out.println("原返回值:" + str);
?? ??? ?String newStr = "哈哈哈哈哈哈";
? ? ? ? //修改返回內(nèi)容長度,解決返回內(nèi)容長度不一致導(dǎo)致請求卡住的問題
? ? ? ? response.setContentLength(newStr.getBytes(StandardCharsets.UTF_8).length);//這里要注意:setContentLength(字符串的字節(jié)長度,不是字符串的長度)
? ? ? ? //修改完寫入輸出流,返回給前端
? ? ? ? //JDK8寫法
? ? ? ? try (ServletOutputStream out = response.getOutputStream()) {
? ? ? ? ? ? out.write(newStr.getBytes(StandardCharsets.UTF_8));//寫入返回內(nèi)容
? ? ? ? ? ? out.flush();//刷新
? ? ? ? }
? ? ? ? //JDK8之前的寫法
? ? ? ? /*ServletOutputStream out = response.getOutputStream();
? ? ? ? out.write(newStr.getBytes(StandardCharsets.UTF_8));//寫入返回內(nèi)容
? ? ? ? out.flush();//刷新
? ? ? ? out.close();//關(guān)閉流*/
? ? }
}繼承HttpServletResponseWrapper重寫方法獲取返回內(nèi)容
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,你好!
修改后
哈哈哈哈哈哈
- 修改完內(nèi)容卡200是因為沒有重新設(shè)置內(nèi)容長度
- 修改完內(nèi)容返回中文亂碼問題,其實不是亂碼問題是你設(shè)置的長度不是字符串的字節(jié)長度導(dǎo)致的。改成字符串的字節(jié)長度即可。
- 沒有數(shù)據(jù)可能是filterChain.doFilter(request, hsrw);位置放錯了,要放到獲取內(nèi)容之前,如果放到獲取內(nèi)容之后,則相當(dāng)于獲取的內(nèi)容為空
SpringBoot使用過濾器Filter,修改返回值會出現(xiàn)返回值截斷缺失
問題原因
原本的ServletResponse response中Content長度小于修改的長度。
當(dāng)使用ServletOutputStream out修改返回值的時候,超過原Content長度的部分會被截斷
解決方法
是在將新內(nèi)容寫入前改變Content的長度:
response.setContentLength(strChange.length()); ServletOutputStream out = response.getOutputStream(); out.write(strChange.getBytes()); out.flush();
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Java應(yīng)用程序CPU100%問題排查優(yōu)化實戰(zhàn)
這篇文章主要介紹了如何排查和優(yōu)化Java應(yīng)用程序CPU使用率達(dá)到100%的問題,文中通過代碼示例和圖文結(jié)合的方式講解的非常詳細(xì),具有一定的參考價值,需要的朋友可以參考下2025-02-02

