实现RESTful API时,我将所有数据包装在一个对象中,使它看起来像这样.
{error: null,code: 200,data: {...actual 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()并自动包装它.
解决方法
像@Ralph建议你可以使用HandlerMethodReturnValueHandler来包装你的处理程序返回值.
实现这一目标的最简单方法是扩展RequestResponseBodyMethodProcessor并稍微改变它的行为.最好的方法是创建一个自定义注释来标记处理程序方法.这将确保默认情况下将调用HandlerMethodReturnValueHandler而不是RequestMappingHandlerAdapter包含的其他HandlerMethodReturnValueHandler.
@Target({ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) public @interface ResultResponseBody {}
下面是名为ResultResponseHandlerMethodProcessor的自定义HandlerMethodReturnValueHandler的简单实现,它将支持从使用ResultResponseBody注释的方法返回的值.这很简单.只需覆盖supportsReturnType()和handleReturnValue()方法以满足您的需要(将返回值包装到Result类型中).
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); } }
剩下的唯一事情是将此类添加到自定义HandlerMethodReturnValueHandlers列表中,并为其提供MappingJackson2HttpMessageConverter实例.
@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)); } }