【无标题】

【无标题】,第1张

【无标题】

springboot 自定义注解
    • 一、注解的基本元素
      • 修饰符
      • 元注解
    • 二、实战
      • 1、新建注解类
      • 2、注解类的解析
      • 3、配置拦截器并放开swagger
      • 4、编写接口验证

一、注解的基本元素 修饰符

访问修饰符必须为public,不写默认为pubic;
关键字:@interface;
注解名称:自定义注解的名称,就是注解名称
注解类型元素:注解中内容,根据需要标志参数

元注解

@Target、@Retention、@Inherited、@documented 这四个注解就是元注解,元注解的作用就是负责注解其他注解。Java5.0定义了4个标准的元注解类型,它们被用来提供对其它 注解类型作标志 *** 作(可以理解为最小的注解,基础注解)

@Target:用于描述注解的使用范围,该注解可以使用在什么地方

Target类型描述ElementType.TYPE应用于类、接口(包括注解类型)、枚举ElementType.FIELD应用于属性(包括枚举中的常量)ElementType.METHOD应用于方法ElementType.PARAMETER应用于方法的形参ElementType.CONSTRUCTOR应用于构造函数ElementType.LOCAL_VARIABLE应用于局部变量ElementType.ANNOTATION_TYPE应用于注解类型ElementType.PACKAGE应用于包

备注:例如@Target(ElementType.METHOD),标志的注解使用在方法上,但是我们在这个注解标志在类上,就会报错

@Retention:表明该注解的生命周期

生命周期类型描述RetentionPolicy.SOURCE编译时被丢弃,不包含在类文件中RetentionPolicy.CLASSJVM加载时被丢弃,包含在类文件中,默认值RetentionPolicy.RUNTIME由JVM 加载,包含在类文件中,在运行时可以被获取到

@Inherited:是一个标记注解,@Inherited阐述了某个被标注的类型是被继承的。如果一个使用了@Inherited修饰的annotation类型被用于一个class,则这个annotation将被用于该class的子类。

@documented:表明该注解标记的元素可以被Javadoc 或类似的工具文档化

二、实战

自定义注解校验用户是否有admin/manager角色

1、新建注解类
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@documented
public @interface RoleAuthorize {
    String[] value() default {};
}
2、注解类的解析
@Component
@Slf4j
public class RoleInterceptor extends HandlerInterceptorAdapter {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {

        RoleAuthorize permission = handler.getClass().getAnnotation(RoleAuthorize.class);

        if(handler.getClass().isAssignableFrom(HandlerMethod.class)){

            RoleAuthorize methodAnnotation =
                    ((HandlerMethod) handler).getMethodAnnotation(RoleAuthorize.class);
            if (methodAnnotation != null) {
                permission = methodAnnotation;
            }
        }
        // 如果没有添加权限注解则直接跳过允许访问
        if (permission == null){
            return true;
        }
        // 获取注解中的值
        String[] validateRoles = permission.value();
        // 校验是否含有对应的角色,编写自己的校验规则
        for (String role : validateRoles) {
            if ("admin".equals(role) || "manager".equals(role)){
                return true;
            }
        }
        throw new AccessDeniedException("没有权限访问当前接口");
    }
}
3、配置拦截器并放开swagger

我采用的是swagger测试访问的

@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter {

    @Autowired
    private RoleInterceptor roleInterceptor;

    
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        String[] swaggerExcludes=new String[]{"/swagger-resources/**", "/webjars/**", "/v2/**", "/swagger-ui.html/**"};
        registry.addInterceptor(roleInterceptor)
                .excludePathPatterns(swaggerExcludes)
                .addPathPatterns("/**");
        super.addInterceptors(registry);
        
    }

}

拦截器的第二种实现

注意:继承WebMvcConfigurerAdapter虽然可以实现,但是在springboot2中已经过时,可以采用以下这种方式:继承:WebMvcConfigurationSupport

@Configuration
public class WebMvcConfig extends WebMvcConfigurationSupport {

    @Autowired
    private RoleInterceptor roleInterceptor;
    
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(roleInterceptor)
                .addPathPatterns("/**")
//                .excludePathPatterns("/user/login")
                .excludePathPatterns("/swagger-resources/**", "/webjars/**", "/v2/**", "/swagger-ui.html/**");
    }
    @Override
    protected void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("swagger-ui.html")
                .addResourceLocations("classpath:/meta-INF/resources/");
        registry.addResourceHandler("/webjars/**")
                .addResourceLocations("classpath:/meta-INF/resources/webjars/");
    }
}

4、编写接口验证
@RestController
@Slf4j
public class StudentController {

    @Autowired
    private StudentService studentService;

    @GetMapping("students")
    @RoleAuthorize(value = {"admin"})
    public CommonResult listStudents(@RequestParam("userName") String userName) throws InterruptedException {
        return CommonResult.build(200, "ok", studentService.getStudent(userName));
    }

    @GetMapping("list")
    @RoleAuthorize(value = {"test"})
    public CommonResult lists() throws InterruptedException {
        return CommonResult.build(200, "ok", studentService.getStudent(null));
    }
}

5、启动类

@SpringBootApplication
@EnableSwagger2 // 注入swagger
public class PlatformTestApp {

    public static void main(String[] args) {
        SpringApplication.run(PlatformTestApp.class,args);
    }

    // SpringBoot Swagger去掉basic-error-controller
    @Bean
    public Docket demoApi() {
        return new Docket(documentationType.SWAGGER_2)
                .select()
                .apis(RequestHandlerSelectors.any())
                .paths(PathSelectors.regex("(?!/error.*).*"))
                .build();
    }
}

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5694425.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存