使用拦截器
- 在方法前标注自定义注解
- 拦截所有请求,只处理带有该注解的方法
自定义注解
- 自定义注解基于元注解。
- @Target: 声明自定义的注解可以作用在什么位置?类上,还是方法上,属性上。
- @Retention: 自定义注解保留的有效时间,编译器有效还是运行时有效。
- @Document: 声明自定义注解在生成文档的时候,要不要把注解也带上去。
- @Inherited:子类继承父类,父类有这个注解,子列是否需要继承父类的注解。
- 自定义注解中@Target和@Retention是必须的,另外两个是非必须的,可以省略
获取注解
- 在运行期间通过反射实现,获取方法上有没有自己想要的注解。Method.getDeclaredAnnotations()
- 获取是否具有某种类型的注解(Method.getAnnotation(Class<T> annotationClass)
利用自定义注解的方式去使用拦截器解决检查登录状态的问题
1.定义注解:在annotation包下,创建一个LoginRequired注解
//注解只起到了一个标记的作用
@Target(ElementType.METHOD) //表示该注解用来描述方法
//只要打上了该标记,表示需要登录后才能被访问
@Retention(RetentionPolicy.RUNTIME)//表示程序运行时有效
public @interface LoginRequired {
}
2.在UserControlle之中的需要登录以后才能访问的方法上加上@LoginRequired的注解
@LoginRequired
@RequestMapping(path="/setting", method = RequestMethod.GET)
@LoginRequired
@RequestMapping(path="/header/{filename}", method = RequestMethod.GET)
3. 利用拦截器拦截带有 @LoginRequired注解的方法
- 创建一个LoginRequiredInterceptor
@Component
public class LoginRequiredInterceptor implements HandlerInterceptor {
@Autowired
private HostHolder hostHolder;
//需要在访问这个方法之前进行判断
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
Object handler) throws Exception {
//首先需要判断拦截的模板是否是一个方法
if(handler instanceof HandlerMethod){
HandlerMethod handlerMethod = (HandlerMethod) handler;
Method method = handlerMethod.getMethod();
//按照指定类型去取注解
LoginRequired loginRequired = method.getAnnotation(LoginRequired.class);
//当前方法需要登录但实际却没有登录,直接返回错误
if(loginRequired != null && hostHolder.getUser() == null){
response.sendRedirect(request.getContextPath() + "/login");
return false;
}
}
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
}
}
4. 配置拦截器
- 排除静态资源的请求,而其他的请求都拦截,对其中带有注解的方法人为地进一步判断能否通过。WebMvcConfig.java中。
- 也就是说通过在方法上加注解,来取代在配置中加路径的方式提高开发的便捷度。
@Autowired
private LoginRequiredInterceptor loginRequiredInterceptor;
registry.addInterceptor(loginRequiredInterceptor)
.excludePathPatterns("/**/*.css", "/**/*.js", "/**/*.jpg", "/**/*.jpeg", "/**/*.png");