【问题标题】:Custom validation for 2 request params in SpringSpring中2个请求参数的自定义验证
【发布时间】:2021-04-16 19:32:48
【问题描述】:
有没有办法自定义验证 Spring 中进入端点的 2 个请求参数?我希望能够使用我的自定义函数来验证它们。诸如在请求参数或这些参数所在的函数上添加注释并强制这些参数由另一个自定义编写的函数验证。
我需要同时获取两个参数,因为一个参数的验证输出取决于另一个参数的值。
我已经搜索并找到了一些带有自定义约束注释的解决方案,但从我所阅读的内容来看,它似乎并没有解决我的问题。
【问题讨论】:
标签:
java
spring
spring-boot
validation
kotlin
【解决方案1】:
如前所述,使用valiktor 是最佳选择。我也在我们的产品中使用过它,它就像一个魅力。
下面是一个 sn-p 示例,说明如何使用它来比较同一类的两个属性。
fun isValid(myObj: Myobj): Boolean {
validate(myObj) {
validate(MyObj::prop1).isGreaterThanOrEqualTo(myobj.prop2)
}
如果验证失败,Valiktor 会抛出异常并显示正确的消息。如果您愿意,它还允许您创建自定义异常消息。
现在您需要做的就是为您的 requestBody 创建一个类并使用 isValid() 方法显式检查您的条件,或者将其移至 init 块并隐式执行。
与JSR380 相比,Valiktor 有大量的验证,与 Valiktor 相比,创建自定义验证有点混乱。
【解决方案2】:
如果您要使用请求参数来创建 POJO,那么您可以简单地使用 Javax Validation API。
public class User {
private static final long serialVersionUID = 1167460040423268808L;
@NotBlank(message = "ID cannot be to empty/null")
private int id;
@NotBlank(message = "Group ID cannot be to empty/null")
private String role;
@NotBlank(message = "Email cannot be to empty/null")
private String email;
@NotNull(message = "Password cannot be to null")
private String password;
}
验证 -
@PostMapping("/new")
public String save(@ModelAttribute @Validated User user, BindingResult bindingResult, ModelMap modelMap) throws UnknownHostException {
if (!bindingResult.hasErrors()) {
// Proceed with business logic
} else {
Set<ConstraintViolation<User>> violations = validator.validate(user);
List<String> messages = new ArrayList<>();
if (!violations.isEmpty()) {
violations.stream().forEach(staffConstraintViolation -> messages.add(staffConstraintViolation.getMessageTemplate()));
modelMap.addAttribute("errors", messages);
Collections.sort(messages);
}
return "new~user";
}
}
【解决方案4】:
valiktor 是一个非常好的验证库。
你可以这样做:
data class ValidatorClass(val field1: Int, val field2: Int) {
init {
validate(this) {
validate(ValidatorClass::field1).isPositive()
validate(ValidatorClass::field2).isGreaterThan(field1)
}
}
}
不需要请求参数:
@RequestMapping(path = ["/path"])
fun fooEndPoint(@RequestParam("field1", required = false) field1: Int,
@RequestParam("field2", required = false) field2: Int) {
ValidatorClass(field1, field2) //it will throw an exception if validation fail
}
您可以使用try-catch 或使用 valiktor 定义的ExceptionHandler 来处理异常。
使用 valiktor,您可以根据其他字段验证字段。您可以创建一个 kotlin 文件,在其中编写用于验证请求中的字段的所有类,并以同样的方式在 @RequestBody 模型中使用 valiktor 来验证它。