实现RESTful API时,我将所有数据包装在一个对象中,使它看起来像这样.
{error: null, code: 200, data: {...actual data...}}
这导致我在任何地方使用重复的代码来包装数据:
@Transactional @RequestMapping(value = "/", method = RequestMethod.GET) public @ResponseBody Result> books() { List
books = booksDao.readBooks(); return Result.ok(books); // this gets repeated everywhere }
所以问题是如何修改它(可能使用自定义HttpMessageConverter可能还有其他一些方法?)只返回booksDao.readBooks()并自动包装它.
就像@Ralph建议你可以使用a HandlerMethodReturnValueHandler
来包装你的处理程序返回值.
实现这一目标的最简单方法是通过扩展RequestResponseBodyMethodProcessor
和改变它的行为.最好的方法是创建一个自定义注释来标记处理程序方法.这将确保默认情况下您HandlerMethodReturnValueHandler
将被调用而不是其他人RequestMappingHandlerAdapter
.
@Target({ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) public @interface ResultResponseBody {}
这是一个自定义HandlerMethodReturnValueHandler
命名的简单实现ResultResponseHandlerMethodProcessor
,它将支持从带注释的方法返回的值ResultResponseBody
.这很简单.只需覆盖supportsReturnType()
和handleReturnValue()
方法以满足您的需要(将返回值包装到一个Result
类型中).
public class ResultResponseHandlerMethodProcessor extends RequestResponseBodyMethodProcessor { public ResultResponseHandlerMethodProcessor(final List> messageConverters) { super(messageConverters); } public ResultResponseHandlerMethodProcessor(final List > 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
实例.
@EnableWebMvc @Configuration public class ApplicationConfiguration extends WebMvcConfigurerAdapter @Override public void addReturnValueHandlers(final ListreturnValueHandlers) { List > messageConverters = new ArrayList<>(); messageConverters.add(new MappingJackson2HttpMessageConverter()); returnValueHandlers.add(new ResultResponseHandlerMethodProcessor(messageConverters)); } }