在我的项目中,我有一组 api 调用,应通过某些常见验证集进行过滤。在这种情况下,我必须在请求到达 REST 控制器之前拦截该请求,读取请求正文,进行验证,如果请求通过验证,则将其传递给控制器。
自从HttpServletRequest
不能多次反序列化,我使用了HttpServletRequestWrapper
制作实际请求的副本。我使用它制作的副本进行验证。
下面是拦截请求的配置类。
public class InterceptorConfig extends WebMvcConfigurerAdapter {
@Autowired
CustomInterceptor customInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(customInterceptor).addPathPatterns("/signup/**");
}
}
这是我的preHandle
里面的方法CustomInterceptor
扩展的类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();
}
};
}
}
现在一切就绪。现在,当我向任何具有以下模式的 url 发送请求时/signup/**
,所有验证都进展顺利。但是,一旦请求到达控制器方法,就会弹出错误,指出请求正文不可用。
缺少必需的请求正文:public
com.mypackage.myResponseObject
com.mypackage.myController.myControllerMethod(com.mypackage.myDTO)
我正在努力寻找其原因以及解决该问题的方法。我在 RequestWrapper 类中做错了什么吗?或者缺少什么?
帮我解决一下这件事。
Thanks!