私有方法上的 Javax 验证不会被触发
Javax validation on private method does not get triggered
假设我有一个非常简单的 Book
模型,我想验证它的标题不是空白。
public class Book {
@NotBlank
public String title;
}
在服务层,我像这样执行验证(使用 Hibernate 验证器 quarkus-hibernate-validator
):
public class BookService {
public void validateBook(@Valid Book book) {
// your business logic here
}
}
我的资源是:
@Path("/books")
public class BookResource {
@Inject
BookService bookService;
@Path("/service-method-validation")
@POST
public String tryServiceMethodValidation(Book book) {
try {
bookService.validateBook(book);
return "Book is valid! It was validated by service method validation.";
} catch (ConstraintViolationException e) {
return "Book invalid";
}
}
@Path("/private-method-validation")
@POST
public String tryMethodValidation(MessedTitleBook book) {
try {
Book book = translate_title(book);
method(book);
return "Book is valid! It was validated by method validation.";
} catch (ConstraintViolationException e) {
return "Book invalid";
}
}
private void method(@Valid Book book) {
// your method logic here
}
}
当我在 /service-method-validation
上 post 一个 Book
时,一切都按预期工作,我的 book
被服务方法检查是否有违规行为。
现在假设我有第二个端点 (/method-validation
),它接收另一个 object、MessedTitleBook
,(把它想象成书名中也嵌入了作者) 我需要对其进行翻译以删除作者,然后将该书传递给私有方法以执行某些操作。在私有方法中,我需要检查翻译的书是否有效,但 @Valid
注释似乎不适用于私有方法。
问题:
@Valid
是否适用于私有方法?如果没有,请提供我学习的资源。
- 有没有一种无需手动验证即可自动实现验证的方法,即注入
validator
并执行 validator.validate(book)
?
编辑
我忘了提及将方法范围从 private 更改为 public 可以使验证工作。
我不能保证这是您使用的库的 100% 正确答案,但我会继续并假设它的工作方式与 Spring 处理此类验证的方式类似。
对问题 1 的简短回答:不,它不起作用。
这种验证的处理方式通常是通过 AOP 代理实例的概念,它围绕着您的实际对象实例并拦截对其进行的所有调用,并且能够向其中添加额外的逻辑在将调用传递给 actual 对象实例之前执行,如验证参数。
这意味着 AOP 代理实例将(并且应该)只能处理 class.
的 public 接口
想一想,一旦调用“成功”到实际的实现实例,您的实例就会在该实例内部“内部”调用私有方法。这样 AOP 代理就无法拦截该调用以添加您想要的逻辑。
我认为在大量使用 Java 反射的帮助下,可能仍然有一些方法可以实现它,但我建议不要这样做,并使用注入的 validator
实例代替。
或者,正如您在示例中所描述的,一种处理 public 接口验证的验证器服务。
这里有一个关于 Javax Validation api 的指南,javax 验证将在任何具有 @Valid
注释的参数的 public 方法上自动调用。
虽然它非常灵活,因为您可以选择使用此验证或您已经找到的手动验证。
可以编写自定义验证器而不是使用注释来进行更复杂的验证。
至于您的问题,您已经知道它适用于 public 方法。
Javax 验证与 Jax-RS 集成,它允许您使用 @Valid
注释来注释您的 rest 方法参数,它会自动生成一个 400 响应,其中包含模型中错误的详细摘要。
Here 这也是一个 quarkus 指南。
假设我有一个非常简单的 Book
模型,我想验证它的标题不是空白。
public class Book {
@NotBlank
public String title;
}
在服务层,我像这样执行验证(使用 Hibernate 验证器 quarkus-hibernate-validator
):
public class BookService {
public void validateBook(@Valid Book book) {
// your business logic here
}
}
我的资源是:
@Path("/books")
public class BookResource {
@Inject
BookService bookService;
@Path("/service-method-validation")
@POST
public String tryServiceMethodValidation(Book book) {
try {
bookService.validateBook(book);
return "Book is valid! It was validated by service method validation.";
} catch (ConstraintViolationException e) {
return "Book invalid";
}
}
@Path("/private-method-validation")
@POST
public String tryMethodValidation(MessedTitleBook book) {
try {
Book book = translate_title(book);
method(book);
return "Book is valid! It was validated by method validation.";
} catch (ConstraintViolationException e) {
return "Book invalid";
}
}
private void method(@Valid Book book) {
// your method logic here
}
}
当我在 /service-method-validation
上 post 一个 Book
时,一切都按预期工作,我的 book
被服务方法检查是否有违规行为。
现在假设我有第二个端点 (/method-validation
),它接收另一个 object、MessedTitleBook
,(把它想象成书名中也嵌入了作者) 我需要对其进行翻译以删除作者,然后将该书传递给私有方法以执行某些操作。在私有方法中,我需要检查翻译的书是否有效,但 @Valid
注释似乎不适用于私有方法。
问题:
@Valid
是否适用于私有方法?如果没有,请提供我学习的资源。- 有没有一种无需手动验证即可自动实现验证的方法,即注入
validator
并执行validator.validate(book)
?
编辑
我忘了提及将方法范围从 private 更改为 public 可以使验证工作。
我不能保证这是您使用的库的 100% 正确答案,但我会继续并假设它的工作方式与 Spring 处理此类验证的方式类似。
对问题 1 的简短回答:不,它不起作用。
这种验证的处理方式通常是通过 AOP 代理实例的概念,它围绕着您的实际对象实例并拦截对其进行的所有调用,并且能够向其中添加额外的逻辑在将调用传递给 actual 对象实例之前执行,如验证参数。 这意味着 AOP 代理实例将(并且应该)只能处理 class.
的 public 接口想一想,一旦调用“成功”到实际的实现实例,您的实例就会在该实例内部“内部”调用私有方法。这样 AOP 代理就无法拦截该调用以添加您想要的逻辑。
我认为在大量使用 Java 反射的帮助下,可能仍然有一些方法可以实现它,但我建议不要这样做,并使用注入的 validator
实例代替。
或者,正如您在示例中所描述的,一种处理 public 接口验证的验证器服务。
这里有一个关于 Javax Validation api 的指南,javax 验证将在任何具有 @Valid
注释的参数的 public 方法上自动调用。
虽然它非常灵活,因为您可以选择使用此验证或您已经找到的手动验证。
可以编写自定义验证器而不是使用注释来进行更复杂的验证。
至于您的问题,您已经知道它适用于 public 方法。
Javax 验证与 Jax-RS 集成,它允许您使用 @Valid
注释来注释您的 rest 方法参数,它会自动生成一个 400 响应,其中包含模型中错误的详细摘要。
Here 这也是一个 quarkus 指南。