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

如何限制Spring Boot中@RequestParam的sort_field仅为合法列名?

如何限制@RequestParam的sort_field参数为合法列名?

你的接口方法代码如下:

public ResponseEntity<Map<String, Object>> method(@PathVariable("tenant_id") Integer tenantId,
                                                 @PathVariable("asset_location_id") Integer assetLocationId,
                                                 @RequestParam(defaultValue = "") String search_keyword,
                                                 @RequestParam(defaultValue = "0") int page,
                                                 @RequestParam(defaultValue = "10") int size,
                                                 @RequestParam(defaultValue = "asset_name") String sort_field,
                                                 @RequestParam(defaultValue = "asc") String sort_dir) {}

以下是几种可行的实现方式,确保sort_field只能取合法列名:

方案一:用枚举类定义合法字段

先创建枚举类,包含所有允许的排序字段,利用Spring的参数自动转换特性实现校验:

public enum ValidSortField {
    ASSET_NAME("asset_name"),
    CREATE_TIME("create_time"),
    UPDATE_TIME("update_time")
    // 按需添加其他合法字段
    ;

    private final String fieldName;

    ValidSortField(String fieldName) {
        this.fieldName = fieldName;
    }

    public String getFieldName() {
        return fieldName;
    }

    // 可选:支持大小写不敏感匹配
    public static ValidSortField fromString(String value) {
        for (ValidSortField field : ValidSortField.values()) {
            if (field.fieldName.equalsIgnoreCase(value)) {
                return field;
            }
        }
        throw new IllegalArgumentException("非法排序字段: " + value);
    }
}

修改接口方法参数类型为枚举,非法参数会自动抛出异常:

public ResponseEntity<Map<String, Object>> method(@PathVariable("tenant_id") Integer tenantId,
                                                 @PathVariable("asset_location_id") Integer assetLocationId,
                                                 @RequestParam(defaultValue = "") String search_keyword,
                                                 @RequestParam(defaultValue = "0") int page,
                                                 @RequestParam(defaultValue = "10") int size,
                                                 @RequestParam(defaultValue = "asset_name") ValidSortField sort_field,
                                                 @RequestParam(defaultValue = "asc") String sort_dir) {
    // 获取实际字段名用于排序逻辑
    String actualSortField = sort_field.getFieldName();
    // 后续业务逻辑
}

优点:自动校验,代码可读性强,新增字段仅需修改枚举类。

方案二:手动校验合法字段集合

定义一个包含所有合法字段的常量集合,在方法开头做校验:

// 把集合定义为类常量,或放在配置类中统一管理
private static final Set<String> VALID_SORT_FIELDS = Set.of("asset_name", "create_time", "update_time");

public ResponseEntity<Map<String, Object>> method(@PathVariable("tenant_id") Integer tenantId,
                                                 @PathVariable("asset_location_id") Integer assetLocationId,
                                                 @RequestParam(defaultValue = "") String search_keyword,
                                                 @RequestParam(defaultValue = "0") int page,
                                                 @RequestParam(defaultValue = "10") int size,
                                                 @RequestParam(defaultValue = "asset_name") String sort_field,
                                                 @RequestParam(defaultValue = "asc") String sort_dir) {
    // 校验字段合法性
    if (!VALID_SORT_FIELDS.contains(sort_field)) {
        return ResponseEntity.badRequest()
                .body(Map.of("error", String.format("非法排序字段,合法字段为:%s", String.join(", ", VALID_SORT_FIELDS))));
    }
    // 后续业务逻辑
}

优点:实现简单,无需额外类,适合字段较少的场景。

方案三:自定义校验注解(多接口复用场景)

如果多个接口都需要类似的排序字段校验,可以自定义Spring校验注解:

1. 自定义注解

@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = SortFieldValidator.class)
public @interface ValidSortField {
    String message() default "非法排序字段";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
    // 指定允许的字段列表
    String[] allowedFields() default {};
}

2. 实现校验器

public class SortFieldValidator implements ConstraintValidator<ValidSortField, String> {
    private Set<String> allowedFields;

    @Override
    public void initialize(ValidSortField constraintAnnotation) {
        allowedFields = Set.of(constraintAnnotation.allowedFields());
    }

    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
        return allowedFields.contains(value);
    }
}

3. 在接口中使用

记得在控制器类上添加@Validated注解开启校验:

@RestController
@Validated
public class YourAssetController {
    public ResponseEntity<Map<String, Object>> method(@PathVariable("tenant_id") Integer tenantId,
                                                     @PathVariable("asset_location_id") Integer assetLocationId,
                                                     @RequestParam(defaultValue = "") String search_keyword,
                                                     @RequestParam(defaultValue = "0") int page,
                                                     @RequestParam(defaultValue = "10") int size,
                                                     @RequestParam(defaultValue = "asset_name") 
                                                     @ValidSortField(allowedFields = {"asset_name", "create_time"}) String sort_field,
                                                     @RequestParam(defaultValue = "asc") String sort_dir) {
        // 后续业务逻辑
    }
}

优点:复用性强,符合Spring校验规范,适合多接口统一校验场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 17:55:30