小生最近写代码遇到一个小问题,一个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);
}
这样代码就优雅多了!
本文介绍了通过在Spring MVC中使用@BrokerRequestArgument注解和自定义HandlerMethodArgumentResolver实现优雅地处理API请求中需要登录状态的情况,简化了代码结构并提高了可维护性。
2419

被折叠的 条评论
为什么被折叠?



