spring mvc 自定义HandlerMethodArgumentResolver

在使用spring mvc时,因为接口参数用到了泛型,如果不处理,有泛型的参数就是空。因此考虑自定义HandlerMethodArgumentResolver ,统一转换参数。


1.首先定义HandlerMethodArgumentResolver

public class CloudMethodArgumentsResolver implements HandlerMethodArgumentResolver {



/*
* (non-Javadoc)

* @see
* org.springframework.web.method.support.HandlerMethodArgumentResolver#
* resolveArgument(org.springframework.core.MethodParameter,
* org.springframework.web.method.support.ModelAndViewContainer,
* org.springframework.web.context.request.NativeWebRequest,
* org.springframework.web.bind.support.WebDataBinderFactory)
*/
@Override
public Object resolveArgument(MethodParameter parameter,
ModelAndViewContainer mavContainer, NativeWebRequest webRequest,
WebDataBinderFactory binderFactory) throws Exception {
// Req<T>
Type type = parameter.getGenericParameterType();

// 带data
Map<String, String[]> paramMap = webRequest.getParameterMap();
String[] reqParam = paramMap.get("data");
if(reqParam == null || reqParam.length == 0){
throw new MyException("9999", "data参数为空");
}
String reqStr = reqParam[0];
reqStr = URLDecoder.decode(reqStr, "utf-8");
Req req = JSON.parseObject(reqStr, type);
try{
ValidateUtils.validate(req.getHeader());
ValidateUtils.validate(req.getBody());

}catch(MyException e){
throw new MyException(e.getErrcode(), e.getErrInfo(), req.getHeader());

}
return req;
// 不带data
/*
String tmp;
String[] val;
Type[] params = ((ParameterizedType) type).getActualTypeArguments(); 
Class clazz = (Class) params[0];
for (Iterator<String> itr = webRequest.getParameterNames(); itr.hasNext();) {
tmp = (itr.next());
String fieldName = tmp;

String secondFiledName = "";
int arrBeginIndex = tmp.indexOf("[");
int arrEndIndex = tmp.indexOf("]");
if(arrBeginIndex != -1 && arrEndIndex != -1){
fieldName = tmp.substring(0, arrBeginIndex);
secondFiledName = tmp.substring(arrBeginIndex+1, arrEndIndex);
}

Field field = FieldUtils.getDeclaredField(o.getClass(), fieldName, true);
Object obj = field.get(o);
if(obj == null){
if(type != null){
obj = clazz.newInstance();
}else{
Class cla = field.getDeclaringClass();
obj = cla.newInstance();
}
FieldUtils.writeField(field, o, obj, true);
}

val = webRequest.getParameterValues(tmp.toString());
if(!"".equals(secondFiledName)){
Field[] fields = o.getClass().getDeclaredFields();
for(int i = 0; i < fields.length; i++){
Class clazz2 = fields[i].getType();
if(clazz2.isAssignableFrom(clazz)){
clazz2 = clazz;
}
System.out.println(clazz2);
System.out.println(secondFiledName);
Field seconedField = FieldUtils.getDeclaredField(clazz2, secondFiledName, true);
if(seconedField != null){
System.out.println(val[0]);
FieldUtils.writeField(seconedField, obj, val[0], true);
}
}

}else{
FieldUtils.writeField(field, obj, val[0], true);
}

}

return o;*/
}


/*
* (non-Javadoc)

* @see
* org.springframework.web.method.support.HandlerMethodArgumentResolver#
* supportsParameter(org.springframework.core.MethodParameter)
*/
@Override

public boolean supportsParameter(MethodParameter parameter) {

// 只对有ReqModel注解的参数处理

return parameter.hasParameterAnnotation(ReqModel.class);
}


}


2.定义配置文件

<mvc:annotation-driven>
<mvc:message-converters register-defaults="true"> 
        <bean class="com.test.framework.convertor.UTF8StringHttpMessageConverter"/>
       
        <bean id="fastJsonHttpMessageConverter"
class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>application/json;charset=UTF-8</value>
</list>
</property>
<property name="features">
<list>
<value>DisableCircularReferenceDetect</value>
<value>QuoteFieldNames</value>
<value>WriteDateUseDateFormat</value>
</list>
</property>
</bean>
    </mvc:message-converters>
    <mvc:argument-resolvers>
    <bean class="com.test.controller.CloudMethodArgumentsResolver"></bean>
    </mvc:argument-resolvers>
   
</mvc:annotation-driven>


纠结的是,刚开始,不是按照此种方式配置,导致返回数据乱码,也就是说UTF8StringHttpMessageConverter没有生效。

以下就是刚开始的错误配置:

<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<property name="synchronizeOnSession" value="true" />
<property name="customArgumentResolvers">
<list>
<bean class="com.test.controller.CloudMethodArgumentsResolver" />
</list>
</property>
</bean>

<!-- 主要作用于@Controller,激活该模式 下面是一种简写形式,完全可以手动配置替代这种简写形式; 它会自动注册DefaultAnnotationHandlerMapping与AnnotationMethodHandlerAdapter 
两个bean, 是spring MVC为@Controllers分发请求所必须的 -->
<mvc:annotation-driven>
<mvc:message-converters register-defaults="true"> 
        <bean class="com.test.framework.convertor.UTF8StringHttpMessageConverter"/>
       
        <bean id="fastJsonHttpMessageConverter"
class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>application/json;charset=UTF-8</value>
</list>
</property>
<property name="features">
<list>
<value>DisableCircularReferenceDetect</value>
<value>QuoteFieldNames</value>
<value>WriteDateUseDateFormat</value>
</list>
</property>
</bean>
    </mvc:message-converters>
   
</mvc:annotation-driven>

在这种情况下,必须将RequestMappingHandlerAdapter移动到mvc:annotation-driven标签上,不然RequestMappingHandlerAdapter会不生效。

3. controller参数

@ResponseBody
@RequestMapping("test")
public String test(@ReqModel Req<Test> req)

4.Req类部分内容

public class Req<T> implements java.io.Serializable{
    private ReqHeader header = new ReqHeader();
    private T body;

   。。。。。。

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值