如何限制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
相关产品推荐
相关产品推荐

