如何手动触发对象的自定义注释验证规则?
How to trigger custom annotated validation rule of an object manually?
我需要在对象上手动或在 json 字符串到对象转换期间触发我的自定义验证器。
我的 dto 如下所示:
@NotNullable.List({
@NotNullable(enumMessage = RequiredFieldErrors.NAME_REQUIRED, fieldName = "info.personName")
//More
})
@SpecificValue.List({
@SpecificValue(enumMessage = BusinessErrors.CONFIDENTIALITY_REQUESTED, fieldName = "info.personName.confidentialityRequested", value = ConstantValue.CONFIDENTIALITY_VALUES)
//More
})
@DependentField.List({
@DependentField(
parentFieldName = "info.personDemographics.ssnUnknown",
parentFieldValue = "false",
childFieldNames = {"info.personDemographics.ssn"},
childFieldValues = {ConstantValue.SSN_PATTERN},
includeChildValues = true,
enumMessage = RequiredFieldErrors.PAYEE_SSN_MUST_BE_NUMERIC)
//More
})
public class MyClass implements Serializable {
private static final long serialVersionUID = 1L;
@SpecificValue(enumMessage = BusinessErrors.SOURCE_ID_INVALID, value = ConstantValue.SOURCE_ID)
private String sourceId;
@NotNullable(enumMessage = RequiredFieldErrors.INFO_REQUIRED)
private PersonType info;
//More
}
在上面的代码中,PersonType 是由其他对象类型组成的。再次验证这些对象。
这种方式工作正常。
@RequestMapping(value = "/api/rest/uploadefile", method = {RequestMethod.POST}
public ResponseEntity<Object> upload1(@Valid @RequestBody MyClass request, BindingResult bindingResult, HttpServletRequest request) {
if(bindingResult.hasErrors()) {
throw new FieldValidationException(Contstants.INVALID_REQUEST, errors);
}
}
我需要将 json 请求作为字符串获取。我知道@Valid @RequestPart....,适用于 multipart/mixed 类型。我想要这样的东西:
@RequestMapping(value = "/api/rest/uploadefile", method = {RequestMethod.POST}, headers = {"content-type=multipart/form-data"})
public ResponseEntity<Object> upload1(@RequestPart(value = "request", required = true) String request, @RequestPart(value = "file", required = true) List<MultipartFile> file, Errors errors) throws Exception {
ObjectMapper mapper = new ObjectMapper();
MyClass myClass = mapper.readValue(request, MyClass.class);
ValidationUtils.invokeValidator(validator1, myClass, errors);
if(errors.hasErrors()) {
throw new FieldValidationException(Contstants.INVALID_REQUEST, errors);
}
}
我尝试了 springframework 验证器和 javax jsr 验证器。他们都没有工作。我收到以下错误:
class java.lang.IllegalStateException JSR-303 validated property 'info.personName' does not have a corresponding accessor for Spring data binding - check your DataBinder's configuration (bean property versus direct field access
对于以下请求:
curl -i -X POST -myURL -H "Authorization: ABC" -F request={} -F file=@view.pdf
我的验证器实现 javax.validation.ConstraintValidator 如下:
public class DependentFieldValidator implements ConstraintValidator<DependentField, Object> {
//My code
}
您用于验证的 Errors
不是应该使用的 Errors
。
如果您使用手动创建的,它应该可以工作 Errors
:
BeanPropertyBindingResult bindingResult = new BeanPropertyBindingResult(myClass, "myClass");
ValidationUtils.invokeValidator(validator, myClass, bindingResult);
请注意 BeanPropertyBindingResult
实现了 Errors
由于我在 MyClass 或其字段上有不同类型的基于注释的验证器,我简单地使用如下:
//org.springframework.validation.SmartValidator
@Autowired
SmartValidator smartValidator
public ResponseEntity<ResponseType> generateResponseExample(@RequestPart(value = "jsonString", required = true) String jsonString, @RequestPart(value = "file", required = true) List<MultipartFile> file){
//Custom deserializer i did here but not relevant to this question, extra info
ObjectMapper mapper = new ObjectMapper();
SimpleModule module = new SimpleModule();
module.addDeserializer(String.class, new StringDeserializer());
mapper.registerModule(module);
MyClass myClass = mapper.readValue(jsonString, MyClass.class);
BeanPropertyBindingResult bindingResult = new BeanPropertyBindingResult(myClass, "myClass");
//This triggers all the annotation of class
smartValidator.validate(myClass, bindingResult, MyClass.annotationgroup1.class);
if (bindingResult.hasErrors()) {
throw new FieldValidationException("Field validation error!", bindingResult);
}
//more work..
return new ResponseEntity<>();
}
我需要在对象上手动或在 json 字符串到对象转换期间触发我的自定义验证器。
我的 dto 如下所示:
@NotNullable.List({
@NotNullable(enumMessage = RequiredFieldErrors.NAME_REQUIRED, fieldName = "info.personName")
//More
})
@SpecificValue.List({
@SpecificValue(enumMessage = BusinessErrors.CONFIDENTIALITY_REQUESTED, fieldName = "info.personName.confidentialityRequested", value = ConstantValue.CONFIDENTIALITY_VALUES)
//More
})
@DependentField.List({
@DependentField(
parentFieldName = "info.personDemographics.ssnUnknown",
parentFieldValue = "false",
childFieldNames = {"info.personDemographics.ssn"},
childFieldValues = {ConstantValue.SSN_PATTERN},
includeChildValues = true,
enumMessage = RequiredFieldErrors.PAYEE_SSN_MUST_BE_NUMERIC)
//More
})
public class MyClass implements Serializable {
private static final long serialVersionUID = 1L;
@SpecificValue(enumMessage = BusinessErrors.SOURCE_ID_INVALID, value = ConstantValue.SOURCE_ID)
private String sourceId;
@NotNullable(enumMessage = RequiredFieldErrors.INFO_REQUIRED)
private PersonType info;
//More
}
在上面的代码中,PersonType 是由其他对象类型组成的。再次验证这些对象。
这种方式工作正常。
@RequestMapping(value = "/api/rest/uploadefile", method = {RequestMethod.POST}
public ResponseEntity<Object> upload1(@Valid @RequestBody MyClass request, BindingResult bindingResult, HttpServletRequest request) {
if(bindingResult.hasErrors()) {
throw new FieldValidationException(Contstants.INVALID_REQUEST, errors);
}
}
我需要将 json 请求作为字符串获取。我知道@Valid @RequestPart....,适用于 multipart/mixed 类型。我想要这样的东西:
@RequestMapping(value = "/api/rest/uploadefile", method = {RequestMethod.POST}, headers = {"content-type=multipart/form-data"})
public ResponseEntity<Object> upload1(@RequestPart(value = "request", required = true) String request, @RequestPart(value = "file", required = true) List<MultipartFile> file, Errors errors) throws Exception {
ObjectMapper mapper = new ObjectMapper();
MyClass myClass = mapper.readValue(request, MyClass.class);
ValidationUtils.invokeValidator(validator1, myClass, errors);
if(errors.hasErrors()) {
throw new FieldValidationException(Contstants.INVALID_REQUEST, errors);
}
}
我尝试了 springframework 验证器和 javax jsr 验证器。他们都没有工作。我收到以下错误:
class java.lang.IllegalStateException JSR-303 validated property 'info.personName' does not have a corresponding accessor for Spring data binding - check your DataBinder's configuration (bean property versus direct field access
对于以下请求:
curl -i -X POST -myURL -H "Authorization: ABC" -F request={} -F file=@view.pdf
我的验证器实现 javax.validation.ConstraintValidator 如下:
public class DependentFieldValidator implements ConstraintValidator<DependentField, Object> {
//My code
}
您用于验证的 Errors
不是应该使用的 Errors
。
如果您使用手动创建的,它应该可以工作 Errors
:
BeanPropertyBindingResult bindingResult = new BeanPropertyBindingResult(myClass, "myClass");
ValidationUtils.invokeValidator(validator, myClass, bindingResult);
请注意 BeanPropertyBindingResult
实现了 Errors
由于我在 MyClass 或其字段上有不同类型的基于注释的验证器,我简单地使用如下:
//org.springframework.validation.SmartValidator
@Autowired
SmartValidator smartValidator
public ResponseEntity<ResponseType> generateResponseExample(@RequestPart(value = "jsonString", required = true) String jsonString, @RequestPart(value = "file", required = true) List<MultipartFile> file){
//Custom deserializer i did here but not relevant to this question, extra info
ObjectMapper mapper = new ObjectMapper();
SimpleModule module = new SimpleModule();
module.addDeserializer(String.class, new StringDeserializer());
mapper.registerModule(module);
MyClass myClass = mapper.readValue(jsonString, MyClass.class);
BeanPropertyBindingResult bindingResult = new BeanPropertyBindingResult(myClass, "myClass");
//This triggers all the annotation of class
smartValidator.validate(myClass, bindingResult, MyClass.annotationgroup1.class);
if (bindingResult.hasErrors()) {
throw new FieldValidationException("Field validation error!", bindingResult);
}
//more work..
return new ResponseEntity<>();
}