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

Spring Java:不使用过滤器,自定义注解校验请求参数(不改控制器签名)

实现自定义注解校验请求查询参数(不修改控制器方法签名)

针对你的需求,我们可以通过自定义注解+Spring AOP的方式,在不修改原有控制器方法签名的前提下,检查请求中是否包含指定查询参数。以下是具体实现步骤:


1. 定义自定义注解

创建一个标记在控制器方法上的注解,用来指定需要检查的查询参数名:

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface CheckQueryParamPresent {
    // 指定要检查的查询参数名称
    String value();
}

2. 实现注解的切面逻辑

通过Spring AOP的环绕通知,拦截标记了注解的控制器方法,从请求上下文获取查询参数并校验:

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ResponseStatusException;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

@Aspect
@Component
@Order(1) // 确保切面在其他逻辑前执行
public class QueryParamValidationAspect {

    @Around("@annotation(checkAnnotation)")
    public Object validateQueryParam(ProceedingJoinPoint joinPoint, CheckQueryParamPresent checkAnnotation) throws Throwable {
        // 从Reactor上下文获取当前请求的ServerWebExchange
        return Mono.deferContextual(contextView -> {
            ServerWebExchange exchange = contextView.get(ServerWebExchange.class);
            String requiredParam = checkAnnotation.value();
            
            // 检查请求查询参数中是否包含目标参数
            boolean paramExists = exchange.getRequest().getQueryParams().containsKey(requiredParam);
            
            if (!paramExists) {
                // 参数不存在时抛出异常,可根据业务需求改为返回自定义响应
                return Mono.error(new ResponseStatusException(HttpStatus.BAD_REQUEST, "缺少必要查询参数: " + requiredParam));
            }
            
            // 参数存在,继续执行原控制器方法
            try {
                return Mono.justOrEmpty(joinPoint.proceed());
            } catch (Throwable throwable) {
                return Mono.error(throwable);
            }
        });
    }
}

3. 在控制器方法上添加注解

直接在原有控制器方法上标记自定义注解,指定要检查的objectName参数:

@PutMapping(path = Constants.ControllerEndPoint)
@CheckQueryParamPresent(ApiConstants.objectName) // 标记需要检查的参数名
public Mono<ResponseEntity<Void>> controllerMethod(
        @RequestParam(name = "objectId") String objectId,
        @RequestBody Flux<DataBuffer> objectData) {
    // 原业务逻辑保持不变
    return Mono.just(ResponseEntity.ok().build());
}

注意事项

  • 确保项目中引入了Spring AOP依赖(Spring Boot项目可直接使用spring-boot-starter-aop)
  • 异常处理可根据业务需求调整:比如返回自定义错误响应体,而非直接抛出ResponseStatusException
  • 如果需要检查多个参数,可修改注解的value为数组类型(String[] value()),并在切面中循环校验每个参数

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 09:25:36