文章目录
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后,自动拦截,跳转到登录页面









