上文介绍了切面的方法注入token,注意这里参数声明的是token类,用String声明token,切面的before方法无法捕捉(不知为何),这里继续前文,通过增加修改参数绑定类来实现。
Controller的参数绑定于HandlerMethodArgumentResolver负责绑定,我们只需要增加一个处理类,即可处理我们自己定义的参数。首先增加一个处理类
<mvc:annotation-driven>
<mvc:argument-resolvers>
<bean class="com.hendiaome.test.resolver.TokenResolver"></bean>
</mvc:argument-resolvers>
</mvc:annotation-driven>
需要知道resolve是一个集合,处理时调用集合的resolve类来进行参数的支持与否和绑定就ok了。
处理类
public class TokenResolver implements HandlerMethodArgumentResolver{
@Override
public boolean supportsParameter(MethodParameter parameter) {
//此次直接用string接受token
String tokenClass = parameter.getParameterType().getName();
//参数的名字就是token
String tokenParamName = parameter.getParameterName();
if (String.class.getName().equals(tokenClass) && "token".equals(tokenParamName)) {
return true;
}
return false;
}
@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
//后续为释放token做准备,只释放参数声明的controller方法
Token.threadLocal.set(true);
return Token.getTokenAndLock();
}
}
controller类更加简单
@RequestMapping("/test")
@ResponseBody
public String test(String token) {
System.out.println(token);
//拿着token去做自己的业务处理去吧
return "OK";
}
这样token的获取加锁就完成了,头疼的问题是什么是否释放并解锁,不想再用切面了,想想spring mvc的原理,从dispatcher入手,再分配完处理完请求后执行我们的释放方法。
首先在web.xml中声明我们的类,不适用spring mvc默认的类
<servlet>
<description>spring mvc servlet</description>
<servlet-name>DispatcherServlet</servlet-name>
<servlet-class>com.hendiaome.test.resolver.TokenDispatcher</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:config/spring-mvc.xml
</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
public class TokenDispatcher extends DispatcherServlet {
@Override
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
try {
//执行父类的分配方法
super.doDispatch(request, response);
} catch (Exception e) {
throw e;
} finally {
//完毕后释放我们的锁
if (Token.threadLocal.get()) {
Token.releaseTokenAndUnlock();
}
}
}
}
这样就完成了,感觉还是这种方法好一点,第一篇有一个缺陷(未解决)。
参考文献http://blog.csdn.net/joeyon1985/article/details/49904681