Spring MVC中的自定义HttpMessageConverter [英] Custom HttpMessageConverter in Spring MVC

查看:95
本文介绍了Spring MVC中的自定义HttpMessageConverter的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

实现RESTful API时,我将所有数据包装在一个对象中,使它看起来像这样。

When implementing RESTful API I wrap all my data in an object so it looks like this.

{error: null, code: 200, data: {...actual data...}}

这导致重复代码我在任何地方用来包装数据:

This results in repetitive code I use everywhere to wrap data:

@Transactional
@RequestMapping(value = "/", method = RequestMethod.GET)
public @ResponseBody Result<List<BookShortDTO>> books() {

    List<Book> books = booksDao.readBooks();
    return Result.ok(books); // this gets repeated everywhere
}

所以问题是如何修改它(也许使用自定义HttpMessageConverter可能还有其他方法吗?)只返回booksDao.readBooks()并自动包装。

So the question is how do I modify this (maybe with use of custom HttpMessageConverter maybe some other ways?) to just return booksDao.readBooks() and to get it wrapped automatically.

推荐答案

像@Ralph建议您可以使用 HandlerMethodReturnValueHandler 来包装处理程序的返回值。

Like @Ralph suggested you can use a HandlerMethodReturnValueHandler to wrap your handlers return value.

最简单的方法实现这一点是通过扩展 RequestResponseBodyMethodProcessor 并稍微改变它的行为。最好的方法是创建一个自定义注释来标记处理程序方法。这将确保默认情况下将调用 HandlerMethodReturnValueHandler 而不是 RequestMappingHandlerAdapter 所包含的其他内容。

The easiest way to achieve this is by extending RequestResponseBodyMethodProcessor and alter it's behavior a bit. Best is to create a custom annotation to mark your handler methods with. This will make sure your HandlerMethodReturnValueHandler will be called instead of others included by RequestMappingHandlerAdapter by default.

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface ResultResponseBody {}

以下是自定义 HandlerMethodReturnValueHandler 的简单实现 ResultResponseHandlerMethodProcessor ,它将支持从使用 ResultResponseBody 注释的方法返回的值。这很简单。只需覆盖 supportsReturnType() handleReturnValue()方法以满足您的需求(将返回值包装到结果类型)。

Here is a simple implementation of the custom HandlerMethodReturnValueHandler named ResultResponseHandlerMethodProcessor which will support values returned from methods annotated with ResultResponseBody. It's pretty simple. Just override the supportsReturnType() and handleReturnValue() methods to suit your needs (wrap the return value into a Result type).

public class ResultResponseHandlerMethodProcessor extends RequestResponseBodyMethodProcessor {
    public ResultResponseHandlerMethodProcessor(final List<HttpMessageConverter<?>> messageConverters) {
        super(messageConverters);
    }

    public ResultResponseHandlerMethodProcessor(final List<HttpMessageConverter<?>> messageConverters, final ContentNegotiationManager contentNegotiationManager) {
        super(messageConverters, contentNegotiationManager);
    }

    @Override
    public boolean supportsReturnType(final MethodParameter returnType) {
        return returnType.getMethodAnnotation(ResultResponseBody.class) != null;
    }

    @Override
    public void handleReturnValue(final Object returnValue, final MethodParameter returnType, final ModelAndViewContainer mavContainer, final NativeWebRequest webRequest) throws IOException, HttpMediaTypeNotAcceptableException {
        super.handleReturnValue(Result.ok(returnValue), returnType, mavContainer, webRequest);
    }
}

唯一剩下的就是将此类添加到自定义 HandlerMethodReturnValueHandler 列表,并提供 MappingJackson2HttpMessageConverter 实例。

The only thing left is to add this class to the list of custom HandlerMethodReturnValueHandlers and provide it with a MappingJackson2HttpMessageConverter instance.

@EnableWebMvc
@Configuration
public class ApplicationConfiguration extends WebMvcConfigurerAdapter
    @Override
    public void addReturnValueHandlers(final List<HandlerMethodReturnValueHandler> returnValueHandlers) {
        List<HttpMessageConverter<?>> messageConverters = new ArrayList<>();
        messageConverters.add(new MappingJackson2HttpMessageConverter());
        returnValueHandlers.add(new ResultResponseHandlerMethodProcessor(messageConverters));
    }
}

这篇关于Spring MVC中的自定义HttpMessageConverter的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆