
本文旨在介绍如何在Spring Boot项目中,利用抽象类和继承机制,结合`javax.validation`框架,实现灵活且可扩展的请求参数验证方案。通过定义抽象的请求参数类,并让具体的请求参数类继承它,我们可以实现公共参数的统一验证,并针对不同的业务场景进行定制化的参数验证。
在实际的Web应用开发中,经常会遇到需要根据不同的业务场景,对请求参数进行不同验证的情况。如果将所有的验证逻辑都写在一个Controller方法中,会导致代码臃肿、难以维护。本文将介绍一种利用抽象类和继承机制,结合Spring Validation框架,实现灵活的请求参数验证方案。
该方案的核心思想是:
import lombok.Data;
import javax.validation.constraints.NotEmpty;
@Data
public abstract class ReportRequestDTO {
@NotEmpty(message = "foo不能为空")
private String foo;
@NotEmpty(message = "bar不能为空")
private String bar;
}在这个例子中,ReportRequestDTO是一个抽象类,包含了两个公共参数foo和bar,并使用@NotEmpty注解,表示这两个参数不能为空。message属性用于自定义验证失败时的错误信息。
import lombok.Data;
import javax.validation.constraints.NotEmpty;
@Data
public class ReportADTO extends ReportRequestDTO {
@NotEmpty(message = "foobar不能为空")
private String foobar;
}ReportADTO继承自ReportRequestDTO,并添加了一个特有的参数foobar,同样使用@NotEmpty注解进行验证。
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import javax.validation.Validator;
import org.springframework.beans.factory.annotation.Autowired;
import javax.validation.ConstraintViolation;
import java.util.Set;
import org.springframework.http.HttpStatus;
import org.springframework.web.server.ResponseStatusException;
@RestController
@RequestMapping("/reports")
@Validated
public class ReportController {
@Autowired
private Validator validator;
@GetMapping
@ResponseBody
public ResponseEntity<String> getReport(@RequestParam(value = "category") String category,
@Valid ReportRequestDTO reportRequestDTO) {
if ("A".equals(category)) {
ReportADTO reportADTO = new ReportADTO();
reportADTO.setFoo(reportRequestDTO.getFoo());
reportADTO.setBar(reportRequestDTO.getBar());
// simulate set parameter from request
reportADTO.setFoobar("test");
Set<ConstraintViolation<ReportADTO>> violations = validator.validate(reportADTO);
if (!violations.isEmpty()) {
StringBuilder sb = new StringBuilder();
for (ConstraintViolation<ReportADTO> violation : violations) {
sb.append(violation.getMessage()).append(";");
}
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, sb.toString());
}
return ResponseEntity.ok("Report A generated with: " + reportADTO.toString());
} else {
return ResponseEntity.ok("Other report");
}
}
}在这个例子中,getReport方法接收一个ReportRequestDTO类型的参数reportRequestDTO。Spring会自动根据请求参数,尝试实例化ReportADTO或其他的ReportRequestDTO子类。
注意: 这里使用 javax.validation.Validator 手动触发验证。首先,需要注入Validator接口。然后,根据不同的category,手动创建对应的DTO对象,并将请求中的公共参数设置到该对象中。最后,调用validator.validate()方法进行验证,并处理验证结果。 如果验证失败,将错误信息封装到ResponseStatusException中,并抛出,Spring会自动处理该异常,并返回相应的错误信息。
为了统一处理验证失败的异常,可以自定义一个全局异常处理类。
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 org.springframework.web.server.ResponseStatusException;
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(ResponseStatusException.class)
public ResponseEntity<String> handleValidationException(ResponseStatusException ex) {
return new ResponseEntity<>(ex.getReason(), ex.getStatus());
}
}通过以上步骤,我们实现了一个灵活且可扩展的请求参数验证方案。该方案的优点包括:
注意事项:
以上就是Spring Validation:利用抽象请求参数类实现灵活的参数验证的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号