小生最近写代码遇到一个小问题,一个controller有8个api,不过有7个api依赖登录api记录的session。如果session存在,则需要从session中获取clientId和password,否则退出到登录页面。
最开始我是在BaseController 中定义了一个公用的设置clientId和password的方法,后来发现这样很不优雅。于是想到了拦截器,但是拦截器针对每个方法都会调用,而且定位待处理的参数也不方便。最后我想到
HandlerMethodArgumentResolver 加注解的方式。下面贴出代码片段。
@Target(ElementType.PARAMETER) @Retention(RetentionPolicy.RUNTIME) public @interface BrokerRequestArgument { }
public class BrokerRequestResolver implements HandlerMethodArgumentResolver { @Override public boolean supportsParameter(MethodParameter parameter) { return parameter.getParameterAnnotation(BrokerRequestArgument.class) != null; } @Override public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception { String token = webRequest.getHeader("X-token"); LoginUserModel loginUserModel = (LoginUserModel) webRequest.getAttribute(token, RequestAttributes.SCOPE_SESSION); Object obj = BeanUtils.instantiate(parameter.getParameterType()); BeanWrapper wrapper = PropertyAccessorFactory .forBeanPropertyAccess(obj); Field[] fields = parameter.getParameterType().getDeclaredFields(); Map<String, Field> fieldMap = Maps.newHashMap(); for (Field field : fields) { fieldMap.put(field.getName(), field); } for (Iterator<String> paramNames = webRequest.getParameterNames(); paramNames.hasNext(); ) { String paramName = paramNames.next(); Object o = webRequest.getParameter(paramName) ; wrapper.setPropertyValue(paramName,o); } wrapper.setPropertyValue("clientId",loginUserModel.getClientId()); wrapper.setPropertyValue("password",loginUserModel.getPassword()); return obj; } }
<mvc:annotation-driven> <mvc:argument-resolvers> <bean class=" cn.xxx.xxx.web.resolver.BrokerRequestResolver" lazy-init="false"/> </mvc:argument-resolvers> </mvc:annotation-driven>
@RequestMapping(value = "/his_trade_entrusts", method = RequestMethod.GET) @ResponseBody public String hisEntrustQry(HttpServletRequest request, PagingQueryRequest brokerRequest) { setClientIdAndPassword(request,brokerRequest); BrokerResponse brokerResponse = guojinTradeService.hisEntrustQry(brokerRequest); return pagingResponse(brokerResponse); } //变成了 @RequestMapping(value = "/his_trade_entrusts", method = RequestMethod.GET) @ResponseBody public String hisEntrustQry( @BrokerRequestArgument PagingQueryRequest brokerRequest) { BrokerResponse brokerResponse = guojinTradeService.hisEntrustQry(brokerRequest); return pagingResponse(brokerResponse); }
这样代码就优雅多了!