2012-08-09 4 views
1

Я пытаюсь создать систему проверки для своих веб-сервисов JSON. Идея состоит в том, чтобы поймать перехватчик каждый Json @RequestBody, сделать с ним объект JSON с помощью JacksonMapping. Затем прочитайте ValidationAnnotations, чтобы проверить данные, и когда проходит полный регулярный поток otherwhise, отправляйте обратно отправителю с моделью и отображением, содержащей сообщения об ошибках.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; 
    } 
} 

Как вы можете видеть, я захватываю поток ввода запроса, а затем перегружаю e getInputStream(), как это принято делать в этих ситуациях. В перехватчике вы можете видеть, как я создаю экземпляр этой обертки и передаю ее super.prehandle (...). Я ожидал, что я войду в контроллер и буду работать дальше с моим jsonobject. Однако результат скорее разочаровывает.

java.io.EOFException: No content to map to Object due to end of input 

Возможно, вызов метода входного потока overriden не называется? Или у меня этот механик совершенно неправы? Могу ли я использовать HandlerInterceptorAdapter?

ответ

4

Мне удалось выяснить, что с помощью HandlerInterceptorAdapter невозможно выполнить функции, которые я запросил в своем вопросе.

Мой единственный вариант, чтобы исправить это было использование javax.servlet.Filter

пример

@Override 
public void doFilter(ServletRequest request, ServletResponse response, 
     FilterChain chain) throws IOException, ServletException { 
    InterceptorRequestWrapper myRequestWrapper = new InterceptorRequestWrapper((HttpServletRequest) request); 
    String httpRequestMethod = ((HttpServletRequest) request).getMethod(); 
    if("POST".equals(httpRequestMethod) || "PUT".equals(httpRequestMethod)){ 
     String body = myRequestWrapper.getBody(); 
     ErrorObject errorObject = new ErrorObject(); 
     errorObject.setSource(body); 
     Map<String, List<ErrorMessage>> errorMessages = new HashMap<String, List<ErrorMessage>>(); 
     ErrorMessage error = new ErrorMessage(); 
     error.setErrorLabel("myerror"); 
     errorMessages.put("test", Arrays.asList(error)); 
     errorObject.setErrorMessages(errorMessages); 
     myRequestWrapper.setAttribute("errorObject", errorObject); 
    } 
    chain.doFilter(myRequestWrapper, response); 
} 
Смежные вопросы