原理解析:
通过查询SpringMVC下面这个类,我们能看到有两属性:
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter
// 属性
customArgumentResolvers
customReturnValueHandlers
customArgumentResolvers 需要实现 HandlerMethodArgumentResolver 作用就是实现自定义入参注解及参数注入(例如:解析通用的协议(解密或者解码),构造成通用入参对象);
customReturnValueHandlers 需要实现 HandlerMethodReturnValueHandler 作用就是实现自定义出参注解及结果输出(例如:解析所有ajax返回结果,构造统一的对象);
示例:
**
* 此类在执行完intercepter的preHandler方法后执行
* @author woter
*
*/
public class MobileRequestParamResolver implements HandlerMethodArgumentResolver{
private static final HjtcLogger log = HjtcLogger.getLogger(MobileRequestParamResolver.class);
/**
* 请求参数
*/
@SuppressWarnings("all")
@Override
public Object resolveArgument(MethodParameter methodparameter,
ModelAndViewContainer modelandviewcontainer,
NativeWebRequest nativewebrequest,
WebDataBinderFactory webdatabinderfactory) throws Exception {
HttpServletRequest httprequest = (HttpServletRequest)nativewebrequest.getNativeRequest();
Annotation[] annotations = methodparameter.getParameterAnnotations();
String jsonData = httprequest.getParameter(MobileConfig.MOBILE_CLIENT_REQ_STR);
if(jsonData ==null){
return null;
}
if(StringUtil.isEmpty(jsonData)){
return null;
}
Object tempObj = null;
for (Annotation annotation : annotations) {
if (MobileReqeustParam.class.isInstance(annotation)){
JSONObject jsonobject = JsonObjectUtils.strToJSONObject(jsonData);
if(jsonobject == null){
return null;
}
MobileReqeustParam mobileReqeustParam = (MobileReqeustParam)annotation;
Class paramCls = methodparameter.getParameterType();
if(paramCls == ReqVo.class){
return getReqObject(jsonobject,paramCls);
}
if(paramCls == ReqHeader.class){
return getHeaderObject(jsonobject,paramCls);
}
return getDataObject(jsonobject,paramCls);
}
}
return null;
}
/**
* 判断是否支持当前@MobileReqeustParam注解
*/
@Override
public boolean supportsParameter(MethodParameter methodparameter) {
Annotation[] annotations = methodparameter.getParameterAnnotations();
for (Annotation annotation : annotations) {
if (MobileReqeustParam.class.isInstance(annotation)){
return true;
}
}
return false;
}
/**
* JSON转ReqHeader对象
* @param jsonObject
* @param cls
* @return
*/
public Object getHeaderObject(JSONObject jsonObject,Class<?> cls){
Object tempObj = jsonObject.get(MobileConfig.MOBILE_REQ_HEADER_STR);
JSONObject headerObject = JsonObjectUtils.forceCastJSONObject(tempObj);
if(headerObject == null){
try {
return cls.newInstance();
} catch (Exception e) {
log.error(cls+".newInstatce()异常",e);
}
return null;
}
return JsonObjectUtils.toBean(headerObject,cls);
}
/**
* JSON转ReqVo对象
* @param jsonObject
* @param cls
* @return
*/
public Object getReqObject(JSONObject jsonObject,Class<?> cls){
return JsonObjectUtils.toBean(jsonObject,cls);
}
/**
* JSON转VO对象
* @param jsonObject
* @param cls
* @return
*/
public Object getDataObject(JSONObject jsonObject,Class<?> cls){
Object tempObj = jsonObject.get(MobileConfig.MOBILE_REQ_DATA_STR);
JSONObject dataObject = JsonObjectUtils.forceCastJSONObject(tempObj);
if(dataObject == null){
try {
return cls.newInstance();
} catch (Exception e) {
log.error(cls+".newInstatce()异常",e);
}
return null;
}
return JsonObjectUtils.toBean(dataObject,cls);
}
}
/**
*
* 此方法是在Interceptor的postHandler方法执行前执行,并且执行完此handleReturnValue后会继续去执行postHandler
*
*
*/
@Component
public class ResponseBodyResolver implements HandlerMethodReturnValueHandler {
private static Logger logger = LoggerFactory.getLogger(ResponseBodyResolver.class);
@Override
public void handleReturnValue(Object returnValue, MethodParameter returnType, ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws IOException, HttpMediaTypeNotAcceptableException, HttpMessageNotWritableException {
HttpServletResponse httpResponse = (HttpServletResponse) webRequest.getNativeResponse();
if(returnValue == null){
return;
}
if (logger.isDebugEnabled()) {
logger.debug(returnValue.toString());
}
mavContainer.setRequestHandled(true);
if (returnValue instanceof JsonMessage) {
JsonMessage jsonMessage = (JsonMessage)returnValue;
try {
WebHelper.write(httpResponse, jsonMessage.toString());
return ;
} catch (IOException e1) {
logger.error("输出数据异常", e1);
}
}else{
try {
WebHelper.write(httpResponse,JsonUtils.beanToJson(returnValue));
return ;
} catch (IOException e1) {
logger.error("输出数据异常", e1);
}
}
}
@Override
public boolean supportsReturnType(MethodParameter returnType) {
return (AnnotationUtils.findAnnotation(returnType.getContainingClass(), ResponseWarp.class) != null ||
returnType.getMethodAnnotation(ResponseWarp.class) != null);
}
}
SpringMVC中实现:
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<property name="messageConverters">
<list>
<ref bean="stringHttpMessageConverter"/>
<ref bean="mappingJacksonHttpMessageConverter"/>
</list>
</property>
<property name="customArgumentResolvers">
<list>
<bean class="com.woter.fct.base.resolver.MobileRequestParamResolver"></bean>
</list>
</property>
<property name="customReturnValueHandlers">
<list>
<ref bean="responseBodyResolver" />
</list>
</property>
</bean>
SpringBoot实现:
@Configuration
public class ApplicationConfiguration extends WebMvcConfigurerAdapter{
@Autowired
private LoginInterceptor loginInterceptor;
@Autowired
private PermissionInterceptor permissionInterceptor;
@Autowired
private ResponseBodyResolver responseBodyResolver;
@Autowired
private RequestMappingHandlerAdapter requestMappingHandlerAdapter;
@Autowired
private DateConverter dateConverter;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(loginInterceptor);
registry.addInterceptor(permissionInterceptor);
super.addInterceptors(registry);
}
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(new ByteArrayHttpMessageConverter());
converters.add(mappingJackson2HttpMessageConverter());
super.configureMessageConverters(converters);
}
public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter(){
MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter();
mappingJackson2HttpMessageConverter.setSupportedMediaTypes(Lists.newArrayList(MediaType.TEXT_PLAIN,MediaType.APPLICATION_JSON_UTF8));
ObjectMapper objectMapper= new ObjectMapper();
objectMapper.setPropertyNamingStrategy(new LowerCasePropertyNamingStrategy());
objectMapper.configure(MapperFeature.ALLOW_EXPLICIT_PROPERTY_RENAMING, true);
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
mappingJackson2HttpMessageConverter.setObjectMapper(objectMapper);
return mappingJackson2HttpMessageConverter;
}
@Override
public void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> returnValueHandlers) {
returnValueHandlers.add(responseBodyResolver);
super.addReturnValueHandlers(returnValueHandlers);
}
@PostConstruct
public void webBindingInitializer(){
requestMappingHandlerAdapter.setWebBindingInitializer(dateConverter);
}
}
使用:
@ResponseWarp
@RequestMapping("/qhisorder")
public RespVo qhisorder(@MobileReqeustParam ReqVo reqVo){
JsonMessage jsonMessage = new JsonMessage();
return jsonMessage;
}