目錄
1、背景
2、解決方案
2.1、自定義HttpServletRequestWrapper
2.2、JsonRequestHeaderParamsHelper
2.3、HttpServletRequestReplacedFilter
2.4、使用
1、背景
當前系統Content-Type為application/json,參數接收方式采用@RequestBody和@RequestParam,但Interceptor攔截器和Aspect切面中存在再次調用request獲取其中請求參數或者請求頭等操作,導致報錯getReader()和getInputStream()只能調用一次(getInputStream() has already been called for this request)。
2、解決方案
2.1、自定義HttpServletRequestWrapper
由于請求信息存儲在流中,只能調用一次,因此將其存儲到字節數組中,保證之后調用getReader()和getInputStream()均通過body數組來獲取數據。
public class BodyReaderHttpServletRequestWrapper extends
HttpServletRequestWrapper {private final byte[] body;public BodyReaderHttpServletRequestWrapper(HttpServletRequest request)throws IOException {super(request);body = JsonRequestHeaderParamsHelper.bufferReaderToString(request.getReader()).getBytes();}@Overridepublic BufferedReader getReader() throws IOException {return new BufferedReader(new InputStreamReader(getInputStream()));}@Overridepublic ServletInputStream getInputStream() throws IOException {final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(body);return new ServletInputStream() {@Overridepublic boolean isFinished() {return false;}@Overridepublic boolean isReady() {return false;}@Overridepublic void setReadListener(ReadListener readListener) {}@Overridepublic int read() {return byteArrayInputStream.read();}};}
}
2.2、JsonRequestHeaderParamsHelper
@Slf4j
public class JsonRequestHeaderParamsHelper {public static JSONObject parseHeader(ServletRequest request) throws IOException {return JSON.parseObject(bufferReaderToString(request.getReader()));}public static String bufferReaderToString(BufferedReader reader) throws IOException {StringBuilder sb = new StringBuilder();try {char[] buff = new char[1024];int len;while ((len = reader.read(buff)) != -1) {sb.append(buff, 0, len);}} catch (IOException e) {log.error("bufferReaderToString error", e);}return sb.toString();}
}
2.3、HttpServletRequestReplacedFilter
通過Order(0)使其最優先加載,保證所有請求都先將request替換為自定義的。
此處的init()和destroy()方法不要使用super.init(),務必清空idea自動生成的內容。
@Slf4j
@Order(value = 0)
@WebFilter(filterName = "httpServletRequestReplacedFilter", urlPatterns = "/*")
public class HttpServletRequestReplacedFilter implements Filter {@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {log.info("進入HttpServletRequestReplacedFilter");ServletRequest requestWrapper = null;if(request instanceof HttpServletRequest) {requestWrapper = new BodyReaderHttpServletRequestWrapper((HttpServletRequest) request);}if(null == requestWrapper) {chain.doFilter(request, response);} else {chain.doFilter(requestWrapper, response);}}@Overridepublic void init(FilterConfig filterConfig) throws ServletException {}@Overridepublic void destroy() {}
}
2.4、使用
之后就可以愉快地使用request.getParameter,@RequestBody等等了。
附上get和post手動獲取請求參數的方法:
if("GET".equals(request.getMethod())|| "DELETE".equals(request.getMethod())) {JSONObject jsonObject = JSONObject.fromObject(request.getParameterMap());params=jsonObject.toString();log.info("get請求參數為:{}", params);}else {com.alibaba.fastjson.JSONObject jsonObject =JsonRequestHeaderParamsHelper.parseHeader(request);params=jsonObject.toJSONString();log.info("post請求參數為:{}",params);}
如果對你有幫助,點贊、收藏、關注是我更新的動力!
往期精彩:
#11vue3中使用el-dialog展示與關閉交由父組件控制的寫法-CSDN博客文章瀏覽閱讀1k次,點贊40次,收藏28次。vue3中使用elementplus的el-dialog展示與關閉交由父組件控制的寫法,分兩種方法,使用difineExpose或者defineEmits實現
https://blog.csdn.net/weixin_42718399/article/details/136155379?spm=1001.2014.3001.5501#10外部網頁跳轉vue3+SpringMVC解碼GBK編碼的參數-CSDN博客文章瀏覽閱讀2.2k次,點贊64次,收藏18次。外部網頁跳轉vue3頁面解碼GBK編碼的參數問題(包括亂碼、解碼失敗、無法進入頁面、URI malformed等問題)
https://blog.csdn.net/weixin_42718399/article/details/135995885?spm=1001.2014.3001.5501#6解析@PreAuthorize以及其中的Spel-CSDN博客文章瀏覽閱讀1.2k次,點贊41次,收藏18次。#6解析@PreAuthorize以及其中的Spel _@preauthorize
https://blog.csdn.net/weixin_42718399/article/details/135558235?spm=1001.2014.3001.5501#2Vite+Vue3+SpringMVC前后端分離 解決跨域問題和session每次請求不一致問題_vue3前后端分離跨域問題-CSDN博客文章瀏覽閱讀1.1k次,點贊37次,收藏15次。Vite+Vue3+SpringMVC前后端分離通過vite/nginx解決跨域問題和session一致性問題_vue3前后端分離跨域問題
https://blog.csdn.net/weixin_42718399/article/details/135388463?spm=1001.2014.3001.5501