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



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

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";
}
}

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

你能指导我如何做到这一点吗?

在类中使用验证注释,但不要在请求体上使用@Valid,那么spring将不会验证您的类。

public class MyClass{
@NotNull
private Integer id;
@NotBlank
private String data;
}

自动连线验证器第一个

@Autowired
private final Validator validator;

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

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

据我所知,Validator接口是在匹配对象(由public boolean Validator.supports(Class clazz)方法确定(时立即调用的。

然而,您的目标似乎是仅在特定时间验证MyClass的对象,该对象来自持久层和服务层。

实现这一点有多种方法。

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

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

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

@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 Validation Groups特性感兴趣。

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

interface OnCreate {};
interface OnUpdate {};

然后,您所需要做的就是在实体类的字段中使用标记接口,使用Bean验证注释:

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

为了在服务类中使用这些组,您必须使用@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应用于服务类以及方法。如果您计划使用多个服务,也可以为整个服务设置组。

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

您可以注入Validator并调用validate

@Autowired
Validator validator;

然后调用validate:

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

相关内容

  • 没有找到相关文章

最新更新