SpringMVC old code ModelAndView converted to API

This article is from iteye http://fair-jm.iteye.com/ Please indicate the source

 

The requirements are special, and it is necessary to convert all the actions of a project's ModelAndView into the form returned by the API, and return a string representing JSON.  

If you change it manually, it will be a lot of work and very boring. The best way is to operate on the facet.  

Finally, consider implementing it in the Interceptor. This Interceptor is placed in the first position. The preHandle returns true by default (not overridden), and the ModelAndView and Response can be accessed in the postHandle. The final code is as follows:

public class ModelAndViewToResponseBodyInterceptor extends HandlerInterceptorAdapter {
    //Use jasckson to serialize Map
    private final ObjectMapper objectMapper = new ObjectMapper();
    // Use Spring's HttpMessageConvert to output information
    private final StringHttpMessageConverter mConverter = new StringHttpMessageConverter();
    // The output media type can be replaced with application json
    private final MediaType mMediaType = new MediaType("text", "plain", Charset.forName("UTF-8"));
    {
        //Because StringHttpMessageConverter Response is used, there will be a lot of Accept-Charset by default. Don't hit
        mConverter.setWriteAcceptCharset(false);
    }
    @Override
    public void postHandle(final HttpServletRequest request, final HttpServletResponse response,
            final Object handler,
            final ModelAndView modelAndView) throws Exception {
        if (modelAndView != null) {
            final String viewName = modelAndView.getViewName();
            final Map<String, Object> model = new HashMap<>(modelAndView.getModelMap().size(), 1);
            for(final Entry<String,Object> entry : modelAndView.getModelMap().entrySet()) {
                // spring will write objects like BindResult to ModelAndView that cannot be serialized...
                if(entry.getKey().startsWith("org.springframework.validation")) {
                    continue;
                }
                model.put(entry.getKey(), entry.getValue());
            }
            model.put("OLD_VIEW_NAME", viewName);
            final HttpOutputMessage outputMessage = new ServletServerHttpResponse(response);
            mConverter.write(objectMapper.writeValueAsString(model), mMediaType, outputMessage);
            modelAndView.clear();
        }
    }
}

 

modelAndView.clear();

 If this code is not written, it will be rendered in Spring's DispatcherServlet, because we also wrote Response, and the second write will report an error.  

 Relevant code:

			// Did the handler return a view to render?
			if (mv != null && !mv.wasCleared()) {
				render(mv, processedRequest, response);
				if (errorView) {
					WebUtils.clearErrorRequestAttributes(request);
				}
			}

 

Without StringHttpMessageConverter, the code will be garbled. The PrintWriter of the Response written directly before is still garbled. Finally, I took the code to process the @ResponseBody annotation.  

 

An aspect of SpringMVC will use ModelFactory to write the BindResult of objects of non-array, non-collection, non-basic type classes in the ModelAndView object. This BindResult will cause serialization failure, and should not appear in the API, it can be handled specially.

 

above.

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326830737&siteId=291194637