在我的项目中,我有一组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类中做错了吗?或缺少什么?
帮我把这个东西排序出来。
谢谢!
你是不读的副本,你正在阅读的实际要求来使用此过滤器。如果你想要这样做,你需要在一个过滤器中做到这一点,并传递包装的请求。目前该请求仍然被消耗。 –