SpringMVC 老代码ModelAndView转为API

本文出自iteye http://fair-jm.iteye.com/ 转截请注明出处

 

需求比较特殊,需要将一个项目的ModelAndView的action全部转成API返回的形式,返回代表JSON的字符串.  

如果手工去改,那工作量很大且非常无聊,最好的方式就是在切面进行操作.  

最后考虑在Interceptor中实现,这个Interceptor放在第一个位置,preHandle默认返回true(不覆写),postHandle中能接触到ModelAndView以及Response就在这里操作,最后的代码如下:

public class ModelAndViewToResponseBodyInterceptor extends HandlerInterceptorAdapter {
    //用jasckson做Map的序列化
    private final ObjectMapper objectMapper = new ObjectMapper();
    // 使用Spring的HttpMessageConvert输出信息
    private final StringHttpMessageConverter mConverter = new StringHttpMessageConverter();
    // 输出的media type 可以换成application json 
    private final MediaType mMediaType = new MediaType("text", "plain", Charset.forName("UTF-8"));
    {
        //因为用了StringHttpMessageConverter Response默认会有一大堆的Accept-Charset 不要打
        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会向ModelAndView中写入BindResult 这样的对象是不能序列化的...
                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();

 这段代码不写会在Spring的DispatcherServlet中进行render,因为我们以及写了Response,二次写会报错.  

 相关代码:

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

 

不用StringHttpMessageConverter会乱码,之前直接写的Response的PrintWriter各种调编码还是乱码,最后拿了处理@ResponseBody注解的代码.  

 

SpringMVC的一个切面会使用ModelFactory在ModelAndView对象里写入非数组 非集合 非基本类型的类的对象的BindResult,这个BindResult会造成序列化失败,而且不应在API中出现,可以特殊处理下.

 

以上.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值