自定义注解实现拦截器判断用户状态
前后端分离的开发模式越来越常见,前端发送的所有后台请求,都用ajax实现,这使得耦合降低,同时也提升开发速率。在一些情况下请求需要判断用户是否登陆或者属于其他状态,这时候我们可以使用自定义注解实现拦截器功能,判断请求的状态。
判断请求的状态,可以通过判断请求头来实现。
自定义注解
@Target(ElementType.METHOD)//指该注解只能使用在方法上
@Retention(RetentionPolicy.RUNTIME)//运行时触发该注解
@Documented//我感觉这没啥用处,写上就是了
public @interface HeaderCheck {
}
定义拦截器,并绑定注解的逻辑关系
@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new HeaderInteceptor()).addPathPatterns("/*");
}
}
class HeaderInteceptor extends HandlerInterceptorAdapter{
Logger log = LoggerFactory.getLogger(HeaderInteceptor.class);
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 1、Class.isAssignableFrom()作用与instanceof相似,
// Class.isAssignableFrom(判断一个类Class1和另一个类(参数)Class2是否相同或是另一个类的子类或接口
// instanceof是用来判断一个对象实例是否是一个类或接口的或其子类子接口的实例
// 2、HandlerMethod及子类主要用于封装方法调用相关信息
if(handler.getClass().isAssignableFrom(HandlerMethod.class)) {
//获得注解对象
HeaderCheck headerCheck = ((HandlerMethod) handler).getMethodAnnotation(HeaderCheck.class);
// 所以会拦截所有的方法,这里需要判断方法是否被我们自定义的这个注释修饰
if ( headerCheck == null) {
log.info("headerCheck == null");
return true;
}
String userid = (String)request.getHeader("Authorization");
if (userid!=null){
//判断userid是否存在登陆
//可以用redis,用户量少可以直接用HashMap,每次进行用户登陆,将用户id放入缓存中
//判断userid是否在缓存就行
}
return false;
}
return true;
}
}
定义拦截器,并绑定注解其实就是拦截所有的http请求,判断这个请求对应的方法,是否存在定义的注解,无则直接放行,有则判断他的请求头会否存在特定的参数和值。
注解使用
@RequestMapping("header")
@ResponseBody
@HeaderCheck
public String hello(){
//
}
前端设置请求头
$.ajax({
url: "http://localhost:8080/header",
dataType: 'json',
type: 'GET',
beforeSend: function (xhr) {
xhr.setRequestHeader("Authorization", xhr.getResponseHeader("Authorization"));
},
success:function (json){
//
}
});
这样,我们就可以在指定controller层的需要判断用户状态的的方法上加入注解,实现身份验证的功能。