我想为我的JSON webservices创建一个验证系统。这个想法是让一个拦截器捕获每个Json @RequestBody
,通过JacksonMapping
来创建一个JSON对象。然后从它读取ValidationAnnotations
来检查数据,以及何时通过完成正常流程,然后通过包含错误消息的modelandviewmap发回给发件人。HandlerInterceptorAdapter似乎并没有转发HttpServletRequestWrapper
知道此背景下考虑这个
@RequestMapping(value="/rest/contact/list/filter", method = RequestMethod.POST, consumes="application/json", produces="application/json")
public @ResponseBody JsonContactList findFilteredContacts(@RequestBody JsonContactSelectorData selectorData, Model model) throws Exception {
MbaLog.debugLog(logger,"Finding Contacts with selector data: " + selectorData);
JsonContactList result = contactService.findContacts(selectorData);
return result;
}
这是我的控制器方法拦截器会前,以下是拦截
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
ValidationRequestWrapper wrapper = new ValidationRequestWrapper(request);
//do complex validation here
return super.preHandle(wrapper, response, handler);
}
下就行了是RequestWrapper此类
public class ValidationRequestWrapper extends HttpServletRequestWrapper {
private String jsonString;
public ValidationRequestWrapper(HttpServletRequest request) throws IOException {
super(request);
jsonString = "";
Scanner scanner = new Scanner(request.getInputStream(), "UTF-8").useDelimiter("\\A");
if (scanner.hasNext())
jsonString = scanner.next();
System.out.println("need a break");
}
@Override
public ServletInputStream getInputStream()
throws IOException {
final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(jsonString.getBytes());
ServletInputStream inputStream = new ServletInputStream() {
public int read()
throws IOException {
return byteArrayInputStream.read();
}
};
return inputStream;
}
}
正如你所看到的,我抓住请求输入流,然后重写如在这些情况下习惯做的那样,getInputStream()
。在拦截器中,你可以看到我实例化这个包装并将它传递给super.prehandle(...)。我期望然后进入控制器,并与我的jsonobject一起愉快地工作。但结果相当令人失望。
java.io.EOFException: No content to map to Object due to end of input
被覆盖的inputstream方法似乎没有被调用?或者我有这个机制完全错误?我甚至可以使用HandlerInterceptorAdapter
?