SpringBoot攔截器執(zhí)行后,Controller層不執(zhí)行的問題及解決
問題描述
請求在SpringBoot攔截器中執(zhí)行后,在Controller層不執(zhí)行,前端錯誤碼400
原因分析
ServletRequest 中通過流獲取參數(shù)(getInputStream())只能讀取一次,
而@RequestBody注解也是根據(jù)流的形式獲取參數(shù)。
所以攔截器中 request 使用流獲取參數(shù)后,Controller中獲取不到參數(shù)
解決方案
// 攔截器中獲取請求 RequestWrapper myRequestWrapper = new RequestWrapper(request); String JSONData = myRequestWrapper.getBody();
public class RequestWrapper extends HttpServletRequestWrapper {
/**
* 存儲請求數(shù)據(jù)
*/
private String body;
public RequestWrapper(HttpServletRequest request) {
super(request);
renewBody(request);
}
/**
* 重寫getInputStream方法
* @return
*/
@Override
public ServletInputStream getInputStream() {
final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(body.getBytes());
ServletInputStream servletInputStream = new ServletInputStream() {
@Override
public boolean isFinished() {
return false;
}
@Override
public boolean isReady() {
return false;
}
@Override
public void setReadListener(ReadListener readListener) {
}
@Override
public int read() {
return byteArrayInputStream.read();
}
};
return servletInputStream;
}
/**
* 重寫getReader方法
* @return
*/
@Override
public BufferedReader getReader() {
return new BufferedReader(new InputStreamReader(this.getInputStream()));
}
/**
* 讀取body的值
* @param request
*/
private void renewBody(HttpServletRequest request) {
StringBuilder stringBuilder = new StringBuilder();
BufferedReader bufferedReader = null;
try {
InputStream inputStream = request.getInputStream();
if (inputStream != null) {
bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
char[] charBuffer = new char[128];
int bytesRead = -1;
while ((bytesRead = bufferedReader.read(charBuffer)) > 0) {
stringBuilder.append(charBuffer, 0, bytesRead);
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (bufferedReader != null) {
try {
bufferedReader.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
body = stringBuilder.toString();
}
public String getBody() {
return body;
}
}
@Component
public class HttpServletFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
ServletRequest requestWrapper = null;
if (servletRequest instanceof HttpServletRequest) {
requestWrapper = new RequestWrapper((HttpServletRequest) servletRequest);
System.out.println(((RequestWrapper) requestWrapper).getBody());
// do something
}
if (requestWrapper == null) {
filterChain.doFilter(servletRequest, servletResponse);
} else {
filterChain.doFilter(requestWrapper, servletResponse);
}
}
@Override
public void destroy() {
}
}總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
SpringBoot整合Canal與RabbitMQ監(jiān)聽數(shù)據(jù)變更記錄
這篇文章主要介紹了SpringBoot整合Canal與RabbitMQ監(jiān)聽數(shù)據(jù)變更記錄,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下2022-09-09
SpringBoot整合Swagger和Actuator的使用教程詳解
Swagger 是一套基于 OpenAPI 規(guī)范構(gòu)建的開源工具,可以幫助我們設(shè)計、構(gòu)建、記錄以及使用 Rest API。本篇文章主要介紹的是SpringBoot整合Swagger(API文檔生成框架)和SpringBoot整合Actuator(項目監(jiān)控)使用教程。感興趣的朋友一起看看吧2019-06-06
SpringBoot根據(jù)目錄結(jié)構(gòu)自動配置Url前綴方式
這篇文章主要介紹了SpringBoot根據(jù)目錄結(jié)構(gòu)自動配置Url前綴方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-11-11
springboot2.0如何通過fastdfs實現(xiàn)文件分布式上傳
這篇文章主要介紹了springboot2.0如何通過fastdfs實現(xiàn)文件分布式上傳,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2019-12-12
MyBatis-Plus不使用數(shù)據(jù)庫默認(rèn)值的問題及解決
這篇文章主要介紹了MyBatis-Plus不使用數(shù)據(jù)庫默認(rèn)值的問題及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-07-07
java使用DelayQueue實現(xiàn)延時任務(wù)
項目中經(jīng)常會用到類似一些需要延遲執(zhí)行的功能,比如緩存,java提供了DelayQueue來很輕松的實現(xiàn)這種功能,下面小編就來和大家介紹一下如何使用DelayQueue實現(xiàn)延時任務(wù)吧2023-10-10
Spring?Data?Jpa?復(fù)雜查詢方式總結(jié)(多表關(guān)聯(lián)及自定義分頁)
這篇文章主要介紹了Spring?Data?Jpa?復(fù)雜查詢方式總結(jié)(多表關(guān)聯(lián)及自定義分頁),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-02-02

