我想在我的Spring @RequestBody
中验证端点的@RestController
。所以我创建了一个这样的方法:
@RequestMapping(value = ...)
public ResponseEntity<...> myPostMethod(@RequestBody MyBean myBean) throws Exception {
MyBean
使用自定义@Constraint
进行修饰,其各自的验证逻辑在我创建的ConstraintValidator
类上实现。此验证器的方法如下:
@Override
public boolean isValid(MyBean value, ConstraintValidatorContext context) {
所有验证逻辑发生的地方。失败时,isValid
返回false
,我可以使用context
参数以我想要的方式构建验证错误消息。此外,myPostMethod
也失败了自动(因为我不自己抛出)MethodArgumentNotValidException
我将在全局处理程序上捕获以呈现通用ResponseEntity
}。这一切都按预期工作。 问题是:我如何自定义验证错误消息,以及整个ConstraintViolationException
?我想在异常中提供更多数据(来自我的业务领域)以在响应主体json中呈现。
任何提示都会受到高度赞赏。
答案 0 :(得分:1)
我找到了答案:
public boolean isValid(MyBean value, ConstraintValidatorContext constraintValidatorContext) {
HibernateConstraintValidatorContext context = constraintValidatorContext.unwrap(HibernateConstraintValidatorContext.class);
// (...)
context.buildConstraintViolationWithTemplate( "{foo}" )
.withDynamicPayload(anyAdditionalInfo)
.addConstraintViolation();
return false;
}
答案 1 :(得分:0)
假设您要传递的其他参数称为myParam
。
首先,在Constraint接口中声明该参数的访问器;
public @interface MyConstraint {
String message();
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
String myParam() default "some.value";
}
然后在ConstraintValidator
中,您可以访问以下参数:
public class MyValidator implements ConstraintValidator<MyConstraint, String> {
private String myParam;
@Override
public void initialize(OpcoConstraint parameters) {
code = parameters.myParam();
}
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
HibernateConstraintValidatorContext hibernateContext = context.unwrap(
HibernateConstraintValidatorContext.class
);
// you can pass any object as the payload
hibernateContext.withDynamicPayload(Map.of("myParam", myParam));
}
}
如果您从异常处理程序中捕获ConstraintViolationException
并想从异常本身访问参数:
要从ConstraintViolation
中提取ConstraintViolationException
,请使用:
constraintViolationException.getConstraintViolations();
然后从ConstraintViolation
中检索动态有效载荷:
(Map) ((ConstraintViolationImpl) constraintViolation).getDynamicPayload(Map.class))