簡體   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