文章目录
1. 权限管理功能需求
-
之前程序有关bug,即没有登录的用户,也可以通过url地址直接访问账号设置页面
-
因此,需要对用户进行权限管理,如果没有登录,有些页面是不能访问的
- 即,用户设置请求页面不能访问
- 上传头像请求不能访问
-
需要使用到拦截器,有选择的拦截一些请求
2. 使用注解的拦截器设计
设计总思路
- 之前采用配置文件指定拦截器要拦截哪些路径和方法,可以用来排除拦截静态资源
- 但对动态资源,只拦截很少的一部分请求,可以不在配置文件中写路径方法,而是采用注解方式更简便
- 即在要拦截的路径方法前标注上自定义的注解
- 拦截器类设计时,对带有注解的方法特殊拦截处理
常用自定义注解回顾
常用元注解
@Target
- 自定义注解可以作用与哪些位置,即哪些方法和属性上
@Retention
- 注解的生命周期,即保留注解的时间
- 运行期
- 编译期
@Document
- 生成文档时,是否要带上
@Inherited
- 父类有注解,子类继承时,是否继承父类的注解
使用反射读取注解
Method.getDeclaredAnnotations()
- 读取方法上的注解
Method.getAnnotation(Class annotationClass)
- 读取方法上指定类型的注解
自定义注解设计
@Target(ElementType.METHOD)
- 作用于方法上
@Retention(RetentionPolicy.RUNTIME)
- 生命周期:运行期
@Target(ElementType.METHOD) // 作用于方法上
@Retention(RetentionPolicy.RUNTIME) // 生命周期:运行期
public @interface LoginRequired {
}
自定义注解标志的请求
@自定义注解类
- LoginRequired
拦截器设计
handlerMethod.getMethod()
- 可以获取请求中的方法
method.getAnnotation(LoginRequired.class)
- 获取方法中的指定类型的注解
response.sendRedirect(str);
- 重定向到指定str的url访问路径
request.getContextPath()
- 获取请求中的项目访问路径路径上下文
@Component
public class LoginRequiredInterceptor implements HandlerInterceptor {
@Autowired
HostHolder hostHolder;
// 只需在Controller处理请求前拦截即可,一旦拦截,就不会进行下去
@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;
}
}
拦截器的配置
- 将静态资源都过滤,不拦截
- 动态资源,用注解的方式定位拦截
registry.addInterceptor(loginRequiredInterceptor)
.excludePathPatterns("/**/*.css", "/**/*.js", "/**/*.png", "/**/*.jpg", "/**/*.jpeg");
测试结果
- 访问http://localhost:8080/community/user/setting后,自动拦截,跳转到登录页面