1

JSONWebサービスの検証システムを作成しようとしています。アイデアは、インターセプターにすべてのJsonをキャッチさせ@RequestBody、それを使用してJSONオブジェクトを作成することですJacksonMapping。次にValidationAnnotations、そこから読み取ってデータを確認し、パスが完了すると通常のフローを完了します。それ以外の場合は、エラーメッセージを含むモデルとビューマップを使用して送信者に送り返します。

この文脈を知っていることはこれを考慮してください

@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か?

4

1 に答える 1

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);
}
于 2013-03-11T11:16:31.940 に答える