一、简述
有没有想过像 @requestparam、@requestbody 这些注解的工作原理呢?为什么 form 表单、application/json 的参数能够直接封装进 bean 对象中呢?这就要说到 handlermethodargumentresolver — 方法参数解析器,该接口有两个方法:
public interface handlermethodargumentresolver { boolean supportsparameter(methodparameter parameter); object resolveargument(methodparameter parameter, modelandviewcontainer mavcontainer, nativewebrequest webrequest, webdatabinderfactory binderfactory) throws exception; }
supportsparameter 方法返回 boolean 值,表示是否启用该解析器,true 表示启用,false 表示不启用;resolveargument 方法表示方法参数的解析过程,就是你把 http 的请求参数转换为方法参数的过程,返回 object 对象,即参数的转换结果。
@requestparam 对应的参数解析器是 requestparammethodargumentresolver;@requestbody 对应的参数解析器是 requestresponsebodymethodprocessor;诸如此类的解析器,读者可自行阅读。
二、自定义参数解析器
我想在控制器方法参数中得到当前用户的登陆信息,大概是如下这个效果,只要添加了 @currentuser 注解,那么 userparam 参数中就会有当前用户的登陆信息。
@requestmapping(value = "/list", method = requestmethod.post) public responsedata<list<syswaydto>> list(@currentuser userparam userparam) { map<string, object> objectmap = maputils.convertobjtomap(userparam); return syswayservice.findwithorigindest(objectmap); }
怎么实现呢?首先我们需要有一个 @currentuser 注解:
@target(elementtype.parameter) @retention(retentionpolicy.runtime) public @interface currentuser { }
那么剩下来的工作就是 handlermethodargumentresolver 的事情了:
@slf4j public class currentuserhandlermethodargumentresolver implements handlermethodargumentresolver { /** * 用于判定是否需要处理该参数分解,返回 true 为需要,并会去调用下面的方法resolveargument。 */ @override public boolean supportsparameter(methodparameter methodparameter) { return methodparameter.getparametertype().isassignablefrom(userparam.class) && methodparameter.hasparameterannotation(currentuser.class); } /** * 真正用于处理参数分解的方法,返回的 object 就是 controller 方法上的形参对象。 */ @override public object resolveargument(methodparameter methodparameter, modelandviewcontainer modelandviewcontainer, nativewebrequest nativewebrequest, webdatabinderfactory webdatabinderfactory) throws exception { string accesstoken = nativewebrequest.getheader(gatewayheader.accesstoken); try { userparam userparam = jsonutils.readvalue(jwthelper.parsejwt(accesstoken), userparam.class); return userparam ; } catch (ioexception e) { log.error("currentuserhandlermethodargumentresolver resolveargument readvalue error.accesstoken:{}", accesstoken, e); } catch (exception e) { log.error("currentuserhandlermethodargumentresolver resolveargument error.accesstoken:{}", accesstoken, e); } return null; } }
最后,别忘了注册上自定义的参数解析器哦!
@configuration public class webconfig extends webmvcconfigureradapter { @override public void addargumentresolvers(list<handlermethodargumentresolver> argumentresolvers) { argumentresolvers.add(new currentuserhandlermethodargumentresolver()); } }
您可能感兴趣的文章:
如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!
网友评论