首页 > 技术文章 > SpringMVC 拦截返回值,并自定义

cmlblog 2015-04-24 10:43 原文

有关取代mvc:annotation-driven使用自定义配置请看:

http://blog.csdn.net/cml_blog/article/details/45222431


1、在项目开发中,自定义全局返回值拦截是非常实用的,就如在Struts2的拦截器中,可以根据Action的返回值自定义返回信息,如果返回SUCCESS就统一返回一个成功的json对象,如果FAIL就返回全局的定义信息


2、配置xml:

<context:component-scan base-package="com.cml.mvc.*" />

	<!-- 取代mvc:annotation-driven> -->
	<bean
		class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping">
	</bean>

	<!-- 采用SpringMVC自带的JSON转换工具,支持@ResponseBody注解 -->
	<bean
		class=" org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
		<!-- 自定义返回值拦截 -->
		<property name="responseBodyAdvice">
			<list>
				<bean class="com.cml.mvc.base.MyResponseBodyAdvice"></bean>
			</list>
		</property>
		<!-- 自定义返回值校验 -->
		<property name="customReturnValueHandlers">
			<list>
				<bean class="com.cml.mvc.base.MyReturnValues"></bean>
			</list>
		</property>
		
		<!-- 注入全局的propertiesEditor -->
		<property name="webBindingInitializer">
			<bean class="com.cml.mvc.base.BaseWebBindingInital">
				<property name="timeFormatter" value="yyyy-MM-dd HH:mm:ss"></property>
			</bean>
		</property>
		<property name="contentNegotiationManager" ref="contentNegotiationManager"></property>
	</bean>
	<!-- 避免IE执行AJAX时,返回JSON出现下载文件 -->
	<bean id="mappingJacksonHttpMessageConverter"
		class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
		<property name="supportedMediaTypes">
			<list>
				<value>text/html;charset=UTF-8</value>
			</list>
		</property>
	</bean>
	<bean id="contentNegotiationManager"
		class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
		<property name="favorPathExtension" value="false" />
		<property name="favorParameter" value="true" />
		<property name="mediaTypes">
			<value>
				json=application/json
				xml=application/xml
			</value>
		</property>
	</bean>

	<!-- 取代mvc:annotation-driven> end -->

2、自定义返回值拦截类,只要实现 org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice接口即可

package com.cml.mvc.base;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

import com.cml.mvc.beans.Result;

public class MyResponseBodyAdvice implements ResponseBodyAdvice<Result> {

	private static Log log = LogFactory.getLog(MyResponseBodyAdvice.class);

	@Override
	public boolean supports(MethodParameter returnType,
			Class<? extends HttpMessageConverter<?>> converterType) {
		log.debug("MyResponseBodyAdvice==>supports:" + converterType);
		log.debug("MyResponseBodyAdvice==>supports:" + returnType.getClass());
		log.debug("MyResponseBodyAdvice==>supports:"
				+ MappingJackson2HttpMessageConverter.class
						.isAssignableFrom(converterType));
		return MappingJackson2HttpMessageConverter.class
				.isAssignableFrom(converterType);
	}

	@Override
	public Result beforeBodyWrite(Result body, MethodParameter returnType,
			MediaType selectedContentType,
			Class<? extends HttpMessageConverter<?>> selectedConverterType,
			ServerHttpRequest request, ServerHttpResponse response) {

		log.debug("MyResponseBodyAdvice==>beforeBodyWrite:" + returnType + ","
				+ body);
		body.setB("我是后面设置的");
		return body;
	}

}

3、controller中只要返回自定义的Result对象,就可以拦截到转换信息,controller代码

       @RequestMapping("/times")
	@ResponseBody
	public Result getTime( Integer id) {
		
		log.debug("==========>getTime,id:" + id);
		Result result=new Result();
		result.setA(1);
		return result;
	}
action中设置了A的值为1,在页面上返回结果:


成功实现自定义返回信息。


推荐阅读