Java – Custom httpmessageconverter in spring MVC

When implementing the restful API, I wrap all the data in one object to make it look like this

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

This leads me to wrap data with duplicate code anywhere:

@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
}

So the question is how to modify it (you may use a custom httpmessageconverter, and there may be other methods?) Return only booksdao Readbooks () and automatically wrap it

Solution

As @ Ralph suggests, you can use handlermethodreturnvaluehandler to wrap the return value of your handler

The easiest way to achieve this is to extend the requestresponsebodymethodprocessor and change its behavior slightly The best way is to create a custom comment to mark the handler method This ensures that the handlermethodreturnvaluehandler will be called by default instead of the other handlermethodreturnvaluehandler contained in the requestmappinghandleradapter

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

The following is a simple implementation of a custom handlermethodreturnvaluehandler named resultresponsehandlermethodprocessor, which will support values returned from methods annotated with resultresponsebody It's simple Just override the supportsreturntype () and handlereturnvalue () methods to meet your needs (wrap the return value in the 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);
    }
}

The only thing left is to add this class to the custom handlermethodreturnvaluehandlers list 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));
    }
}
The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>