在自定义注释中实现@RequestBody的功能

时间:2015-09-03 09:44:18

标签: java json spring spring-mvc annotations

我已经创建了一个自定义注释@JsonSchema,我已经实现了@RequestBody的功能。我的注释将始终用于从Web请求中读取JSON。但是我希望在让它进一步传递之前对模式验证JSON。为此我有一个实现HandlerMethodArgumentResolver

的类

最初,我的注释仅用于String,因此我很容易从RequestResponseBodyMethodProcessor#resolveArgument获取通用对象,将其转换为字符串,验证它然后返回它。但是现在我想在自定义类中使用我的注释。

所以我想要了解的是@RequestBody如何将Web请求体中的JSON绑定到兼容类。如果我理解这是怎么回事,我可以先将主体提取为字符串,进行验证,然后将主体绑定到任何具有我的注释的类并将其返回。

我目前对resolveArgument

的实施
@Override
public Object resolveArgument(MethodParameter parameter,
        ModelAndViewContainer mavContainer, NativeWebRequest webRequest,
        WebDataBinderFactory binderFactory) throws Exception {
    Object value =  getRequestResponseBodyMethodProcessor()
            .resolveArgument(parameter, mavContainer, webRequest, binderFactory);
    return value;
//      return validateJson(value, parameter); I need to pass a String here

}

// Using message converters to read from body of web request. Can I parse the message earlier than it is cast to the required object type?
private RequestResponseBodyMethodProcessor getRequestResponseBodyMethodProcessor() {

    if (requestResponseBodyMethodProcessor == null) {
        List<HttpMessageConverter<?>> messageConverters = requestMappingHandlerAdapter().getMessageConverters();
        requestResponseBodyMethodProcessor = new RequestResponseBodyMethodProcessor(messageConverters);
    }
    return requestResponseBodyMethodProcessor;
}

1 个答案:

答案 0 :(得分:0)

经过一番研究,我发现了一种名为HttpMessageConverter的东西。消息转换器用于通过HTTP对JSON,XML等Java对象进行编组和解组。有一些默认转换器,其中StringHttpMessageConverter是一个。我们还可以添加自己的消息转换器。 Here是一篇很好的文章,解释了如何做到这一点。

我通过调用RequestMappingHandlerAdapter#getMessageConverters获得了默认的邮件转换器集合。我从中提取了StringHTTPMEssageConverter并调用了它的read方法来将主体读取为字符串。

以下是代码:

if (requestResponseBodyMethodProcessor == null) {
        List<HttpMessageConverter<?>> messageConverters = requestMappingHandlerAdapter().getMessageConverters();
        requestResponseBodyMethodProcessor = new RequestResponseBodyMethodProcessor(messageConverters);
}

String body = null;
StringHttpMessageConverter stringHttpMessageConverter = null;
HttpServletRequest servletRequest = webRequest.getNativeRequest(HttpServletRequest.class);
HttpInputMessage inputMessage = new ServletServerHttpRequest(servletRequest);
if (messageConverters.get(1) instanceof StringHttpMessageConverter)
        stringHttpMessageConverter = (StringHttpMessageConverter) messageConverters.get(1);

try {
        body = stringHttpMessageConverter.read(String.class, inputMessage);
} catch (IOException e) {
        e.printStackTrace();
}