基于Spring Boot实现GET请求PathVariable的自定义校验
Spring Boot实现PathVariable的自定义参数校验(针对id字符规则)
我来帮你搞定这个自定义校验的需求!咱们可以借助Spring的校验框架来实现,不用在方法里写一堆if判断,代码会更优雅。具体分这几步走:
1. 创建自定义校验注解
首先咱们定义一个注解@ValidId,用来标记需要校验的PathVariable参数:
import javax.validation.Constraint; import javax.validation.Payload; import java.lang.annotation.*; @Documented @Constraint(validatedBy = IdValidator.class) @Target({ElementType.PARAMETER, ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) public @interface ValidId { String message() default "id参数只能包含小写字母(a-z)、数字(0-9)和连字符(-)"; Class<?>[] groups() default {}; Class<? extends Payload>[] payload() default {}; }
2. 实现对应的校验器
接下来写注解的实现类IdValidator,这里面写具体的校验逻辑:
import javax.validation.ConstraintValidator; import javax.validation.ConstraintValidatorContext; import java.util.regex.Pattern; public class IdValidator implements ConstraintValidator<ValidId, String> { // 定义正则规则:只允许a-z、0-9、- private static final Pattern ID_PATTERN = Pattern.compile("^[a-z0-9-]+$"); @Override public void initialize(ValidId constraintAnnotation) { // 初始化逻辑,这里不需要额外操作 } @Override public boolean isValid(String id, ConstraintValidatorContext context) { // 如果id为空,也可以根据需求调整校验逻辑,这里假设id是必填的 if (id == null || id.isBlank()) { return false; } return ID_PATTERN.matcher(id).matches(); } }
如果需要支持大写字母的话,把正则改成^[a-zA-Z0-9-]+$就可以啦。
3. 在Controller中使用自定义校验
给你的Controller加上@Validated注解(这个很重要,Spring需要它来触发参数校验),然后在@PathVariable参数上加上@ValidId:
import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.http.ResponseEntity; import org.springframework.http.HttpStatus; @RestController @Validated // 必须加这个注解才能触发参数校验 public class DataController { @Autowired DataService dataService; @RequestMapping("/data/{id}") public ResponseEntity<Data> getData(@PathVariable @ValidId String id) { Data messages = dataService.getData(id, Data.DataFormat.ALL); return new ResponseEntity<>(messages, HttpStatus.OK); } }
4. 全局处理校验异常
现在校验失败的话会抛出ConstraintViolationException,咱们可以写一个全局异常处理器来统一返回错误响应:
import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import javax.validation.ConstraintViolation; import javax.validation.ConstraintViolationException; import java.util.stream.Collectors; @ControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(ConstraintViolationException.class) public ResponseEntity<String> handleConstraintViolationException(ConstraintViolationException ex) { // 提取所有校验错误信息 String errorMessage = ex.getConstraintViolations().stream() .map(ConstraintViolation::getMessage) .collect(Collectors.joining("; ")); return new ResponseEntity<>(errorMessage, HttpStatus.BAD_REQUEST); } }
这样一来,当用户传入的id包含不符合规则的字符时,接口就会返回400状态码和咱们定义的错误信息啦,完全符合你的需求~
内容的提问来源于stack exchange,提问作者jack
相关产品推荐
相关产品推荐

