You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Quarkus带参数注解拦截器问题:无法接收自定义角色参数

解决Quarkus拦截器无法获取方法自定义角色参数的问题

核心问题分析

你遇到的问题根源有两个:

  1. CDI拦截器绑定的参数匹配机制:默认情况下,带参数的拦截器绑定注解会把参数值作为匹配条件——只有目标方法/类上的注解参数和拦截器类上的完全一致时,才会触发拦截。
  2. 错误的注解参数获取方式:当前代码从拦截器类本身获取@RolesRequired的参数,而不是从被拦截的目标方法/类上提取。

解决方案

步骤1:修改@RolesRequired注解,标记参数为非绑定匹配

给注解的rolesRequired参数添加@Nonbinding,让CDI在匹配拦截器时忽略该参数的值,只要目标有@RolesRequired注解就触发拦截:

import jakarta.annotation.Priority
import jakarta.interceptor.*
import jakarta.ws.rs.core.HttpHeaders
import java.lang.annotation.Inherited

@Target(AnnotationTarget.FUNCTION, AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME)
@InterceptorBinding
@Inherited
annotation class RolesRequired(
    @Nonbinding  // 添加该注解,忽略参数匹配条件
    val rolesRequired: Array<String> = []  // 设置默认值,避免必填报错
)

步骤2:调整拦截器类的绑定与参数获取逻辑

拦截器类上的@RolesRequired使用空参数即可(满足IDE绑定要求),同时修改逻辑从被拦截的目标方法/类上提取注解参数:

@Interceptor
@RolesRequired()  // 空参数即可,参数值不再影响拦截匹配
@Priority(Interceptor.Priority.PLATFORM_BEFORE + 1)
class RolesRequiredInterceptor(
    private val header: HttpHeaders
) {
    @AroundInvoke
    fun intercept(context: InvocationContext): Any? {
        println("[check-role]")
        // 优先从方法上获取注解,方法无注解则从类上获取
        val rolesAnnotation = context.method.getAnnotation(RolesRequired::class.java)
            ?: context.target.javaClass.getAnnotation(RolesRequired::class.java)
        
        val rolesRequired = rolesAnnotation?.rolesRequired ?: emptyArray()
        println("[roles]: ${rolesRequired.size} - ${rolesRequired.joinToString(", ")}")
        
        // TODO 在这里实现角色校验逻辑,比如从请求头提取用户角色进行比对
        return context.proceed()
    }
}

步骤3:验证业务方法

现在不管业务方法上的@RolesRequired参数是什么,拦截器都会触发并获取对应参数:

@RolesRequired(rolesRequired = ["role1"])
fun login(input: LoginData): LoginResponse {...}

@RolesRequired(rolesRequired = ["role2"])
fun login(input: LoginData): LoginResponse {...}

@RolesRequired(rolesRequired = ["role2", "role1"])
fun login(input: LoginData): LoginResponse {...}

调用第一个方法时,拦截器会输出:

[check-role]
[roles]: 1 - role1

关键原理说明

  • @Nonbinding:标记注解参数为非绑定条件,CDI仅检查目标是否存在该注解,不再校验参数值是否匹配。
  • InvocationContext:通过该上下文对象可获取被拦截的方法、目标类信息,从而动态提取目标上的注解参数,满足自定义角色的需求。

内容的提问来源于stack exchange,提问作者Prixii

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 22:12:06