繁体   English   中英

我可以在 Spring Boot 中从服务中显式调用自定义验证器吗?

[英]Can I explicitly call custom validator from service in Spring Boot?

我有一个实现Validator的自定义验证器 class ,如下所示:

 public class MyCustomValidator implements Validator

我希望能够从服务中调用它的validate()方法。 这是这个方法的样子:

@Override
public void validate(Object target, Errors errors) {
     // validation goes here
     MyClass request = (MyClass) target;
     if (request.getId() == null) {
         errors.reject("content.id", "Id is missing";
     }
}

我不想在我的端点中有这个验证器,因为我需要从数据库中获取要验证的 object,然后调用它的验证,所以我需要从我的服务中进行验证。

你能指导我如何实现这一目标吗?

在 class 中使用验证注释,但不要在请求正文中使用 @Valid,然后 spring 将不会验证您的 class。

public class MyClass{

   @NotNull
   private Integer id;

   @NotBlank
   private String data;
}

自动装配验证器优先

@Autowired
private final Validator validator;

然后对于 class 在需要时有条件地使用验证器进行验证。

if(isValidate) {
    Set<ConstraintViolation<MyClass>> violations = validator.validate(myClassObj);
    if (!violations.isEmpty()) {
      throw new ConstraintViolationException(new HashSet<ConstraintViolation<?>>(violations));
    }

}

您可以注入 Validator 并调用 validate

@Autowired
Validator validator;

然后调用验证:

Set<ConstraintViolation<Driver>> violations = validator.validate(yourObjectToValidate);

据我了解,Validator 接口被称为匹配的 object(由public boolean Validator.supports(Class clazz)方法确定)。

但是,您的目标似乎是仅在特定时间验证 MyClass 的 object,从持久层到服务层。

有多种方法可以实现这一目标。

第一个也是最明显的一个是不扩展任何类,而是使用带有一些验证概念的自定义组件 function:

@Component
public class CustomValidator{
    public void validate(MyClass target) throws ValidationException {
        // validation goes here
        if (target.getId() == null) {
             throw new ValidationException("Id is missing");
        }
    }
}

并将其注入/自动连接到您的服务 object 中:

@Component
public class MyClassService{
    // will be injected in first instance of this component
    @Autowired
    private CustomValidator validator

    public MyClass get(MyClass target) {
        try {
             validator.validate(target);
             return dao.retrieve(target);
        } catch (ValidationException) {
             // handle validation error
        } catch (DataAccessException) {
             // handle dao exception
        }

    }
}

这样做的好处是您可以自己控制验证和错误处理。 不利的一面是相对较高的样板。

但是,如果您需要针对不同 CRUD 操作(或服务方法)的不同验证器,您可能对Spring 验证组功能感兴趣。

首先,为每个想要区别的操作创建一个简单的标记界面:

interface OnCreate {};
interface OnUpdate {};

然后,您需要做的就是使用Bean Validation Annotations在实体 class 的字段中使用标记接口:

public class MyClass{
    @Null(groups = OnCreate.class)
    @NotNull(groups = OnUpdate.class)
    String id;
}

为了在您的服务 Class 中使用这些组,您必须使用@Validated注释。

@Validated
@Service
public class MyService {
    @Validated(OnCreate.class)
    void validateForCreate(@Valid InputWithGroups input){
      // do something
    }

    @Validated(OnUpdate.class)
    void validateForUpdate(@Valid InputWithGroups input){
      // do something
    }
}

请注意,@Validated 应用于服务@Validated以及方法。 如果您计划使用多个服务,您还可以为整个服务设置组。

我曾经主要将内置的Jakarta Bean Validation注释与标记接口结合使用,因为它们易于使用且几乎没有样板,同时保持一定的灵活性和可调整性。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM