解決異常處理問題:getReader()?has?already?been?called?for?this
場景描述
在 Spring Boot 自定義攔截器中,需要對請求 body 中的內(nèi)容做簽名驗證。
在日志切面中,需要打印請求 body 中的內(nèi)容。
報錯內(nèi)容
java.lang.IllegalStateException: getReader() has already been called for this request
at org.apache.catalina.connector.Request.getInputStream(Request.java:1069)
at org.apache.catalina.connector.RequestFacade.getInputStream(RequestFacade.java:365)
at com.igg.aggregate.server.aspect.LogAspect.before(LogAspect.java:80)
原因分析
HttpServletRequest 的 getInputStream() 和 getReader() 都只能讀取一次,由于 Request Body 是流的形式讀取,那么
流讀了一次就沒有了,所以只能被調(diào)用一次。
解決辦法
先將 Request Body 保存,然后通過 Servlet 自帶的 HttpServletRequestWrapper 類覆蓋 getReader() 和
getInputStream() 方法,使流從保存的body讀取。
然后再Filter中將ServletRequest替換為AuthenticationRequestWrapper。
代碼示例:
public class MyRequestWrapper extends HttpServletRequestWrapper {
private byte[] body;
public MyRequestWrapper(HttpServletRequest request) throws IOException {
super(request);
StringBuilder sb = new StringBuilder();
String line;
BufferedReader reader = request.getReader();
while ((line = reader.readLine()) != null) {
sb.append(line);
}
String body = sb.toString();
this.body = body.getBytes(StandardCharsets.UTF_8);
}
public String getBody() {
return new String(body, StandardCharsets.UTF_8);
}
}// 獲取請求body
try {
MyRequestWrapper myRequestWrapper = new MyRequestWrapper(request);
return myRequestWrapper.getBody();
} catch (IOException e) {
log.error("get request body exception", e);
throw new RuntimeException(e);
}總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
- 解決java啟動時報線程占用報錯:Exception?in?thread?“Thread-14“?java.net.BindException:?Address?already?in?use:?bind
- 如何解決Mybatis--java.lang.IllegalArgumentException: Result Maps collection already contains value for X
- SVN出現(xiàn)提示org.apache.subversion.javahl.ClientException: Attempted to lock an already-locked dir解決方案
- 啟動tomcat時 錯誤: 代理拋出異常 : java.rmi.server.ExportException: Port already in use: 1099的解決辦法
- 如何解決getReader() has already been called for this request問題
相關(guān)文章
Java中try-catch-finally執(zhí)行順序你知道嗎
本文主要介紹了try-catch-finally執(zhí)行順序你知道嗎,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-06-06
SpringBoot整合Jasypt實現(xiàn)配置文件和數(shù)據(jù)庫字段敏感數(shù)據(jù)的加解密
很多時候為了保證數(shù)據(jù)的安全,在處理敏感數(shù)據(jù)、前后端數(shù)據(jù)傳輸、數(shù)據(jù)庫敏感數(shù)據(jù)入庫等,數(shù)據(jù)的加密和解密是不可忽視的重要環(huán)節(jié),下面我們就來看看如何在SpringBoot整合Jasypt實現(xiàn)配置文件和數(shù)據(jù)庫字段敏感數(shù)據(jù)的加解密吧2025-09-09
SpringMVC配置多個properties文件之通配符解析
這篇文章主要介紹了SpringMVC配置多個properties文件之通配符解析,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-09-09

