在我的項目中,我有一組api調用,它們應該通過某些常用驗證集進行過濾。在這種情況下,我必須在請求通過REST控制器之前攔截請求,讀取請求體,執行驗證並在請求通過驗證時將其傳遞給控制器。在使用HttpServletRequestWrapper複製副本後,缺少所需的請求主體
由於HttpServletRequest
不能被反序列化多次,所以我使用HttpServletRequestWrapper
複製了實際的請求。使用它的副本,我做了驗證。
以下是攔截請求的配置類。
public class InterceptorConfig extends WebMvcConfigurerAdapter {
@Autowired
CustomInterceptor customInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(customInterceptor).addPathPatterns("/signup/**");
}
}
這裏是我的內部延伸HandlerInterceptorAdaptor
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
ServletRequest copiedRequest = new HttpRequestWrapper(request);
Map<String, Object> jsonMap = mapper.readValue(copiedRequest.getInputStream(), Map.class);
if(jsonMap.containsKey("userId")){
long userId = jsonMap.get("userId");
MyClass myObject= myAutowiredService.getMyObject(userId);
if(myObject == null){
response.setStatus(HttpStatus.SC_NOT_ACCEPTABLE);
return false;
}
// some more validations which end up returning false if they are met
}
return true;
}
這是我HttpRequestWrapper
public class HttpRequestWrapper extends HttpServletRequestWrapper {
private byte[] requestBody;
public HttpRequestWrapper(HttpServletRequest request) throws IOException{
super(request);
try {
requestBody = IOUtils.toByteArray(request.getInputStream());
} catch (IOException ex) {
requestBody = new byte[0];
}
}
@Override
public ServletInputStream getInputStream() throws IOException {
final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(requestBody);
return new ServletInputStream() {
@Override
public boolean isFinished() {
return byteArrayInputStream.available() == 0;
}
@Override
public boolean isReady() {
return true;
}
@Override
public void setReadListener(ReadListener listener) {
throw new RuntimeException("Not implemented");
}
public int read() throws IOException {
return byteArrayInputStream.read();
}
};
}
}
所有設置現在CustomInterceptor
類preHandle
方法。現在,當我向/signup/**
模式的任何url發送請求時,所有驗證都正常發生。但是,一旦請求觸及控制器方法,就會彈出錯誤消息,說明請求主體不可用。
必需的請求體丟失:公共 com.mypackage.myResponseObject com.mypackage.myController.myControllerMethod(com.mypackage.myDTO)
我苦苦尋找這樣做的原因和也是解決問題的一種方法。有什麼我在RequestWrapper類中做錯了嗎?或缺少什麼?
幫我把這個東西排序出來。
謝謝!
你是不讀的副本,你正在閱讀的實際要求來使用此過濾器。如果你想要這樣做,你需要在一個過濾器中做到這一點,並傳遞包裝的請求。目前該請求仍然被消耗。 –