Java 如何手动触发对象的自定义带注释的验证规则?

Java 如何手动触发对象的自定义带注释的验证规则?,java,spring-boot,bean-validation,Java,Spring Boot,Bean Validation,我需要手动或在json字符串到对象转换期间触发对象上的自定义验证器 我的dto如下所示: @NotNullable.List({ @NotNullable(enumMessage = RequiredFieldErrors.NAME_REQUIRED, fieldName = "info.personName") //More }) @SpecificValue.List({ @SpecificValue(enumMessage = BusinessErrors.CONFIDE

我需要手动或在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
}
public class DependentFieldValidator implements ConstraintValidator<DependentField, Object> {
 //My code
}
//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<>();
}
在上面的代码中,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);
    }
}
应以下要求:

curl -i -X POST -myURL -H "Authorization: ABC" -F request={} -F file=@view.pdf
我的验证器实现javax.validation.ConstraintValidator,如下所示:

@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
}
public class DependentFieldValidator implements ConstraintValidator<DependentField, Object> {
 //My code
}
//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<>();
}
公共类DependentFieldValidator实现ConstraintValidator{
//我的代码
}

用于验证的
错误
不是应该使用的
错误

如果您将使用手动创建的
错误
,它应该可以工作:

BeanPropertyBindingResult bindingResult = new BeanPropertyBindingResult(myClass, "myClass");
ValidationUtils.invokeValidator(validator, myClass, bindingResult);

请注意,实现了
错误

,因为我在MyClass或其字段上有不同类型的基于注释的验证器,所以我只使用如下方法:

@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
}
public class DependentFieldValidator implements ConstraintValidator<DependentField, Object> {
 //My code
}
//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<>();
}
//org.springframework.validation.SmartValidator
@自动连线
智能验证器智能验证器
public ResponseEntity generateResponseExample(@RequestPart(value=“jsonString”,required=true)字符串jsonString,@RequestPart(value=“file”,required=true)列表文件){
//自定义反序列化器我在这里做了,但与这个问题无关,额外信息
ObjectMapper mapper=新的ObjectMapper();
SimpleModule=新的SimpleModule();
addDeserializer(String.class,新的StringDeserializer());
映射器注册表模块(模块);
MyClass MyClass=mapper.readValue(jsonString,MyClass.class);
BeanPropertyBindingResult bindingResult=新的BeanPropertyBindingResult(myClass,“myClass”);
//这将触发类的所有注释
smartValidator.validate(myClass、bindingResult、myClass.annotationgroup1.class);
if(bindingResult.hasErrors()){
抛出新的FieldValidationException(“字段验证错误!”,bindingResult);
}
//更多的工作。。
返回新的ResponseEntity();
}