小编典典

如何在REST Web服务中处理资源验证?

java

我正在使用Spring,Jersey和Hibernate(JPA)在Java中构建REST Web服务。

现在,我正在尝试在资源中添加对验证的支持。JSR-303(Bean验证)自然是一个合适的选择(我使用的是Hibernate
Validator,它是JSR-303的参考实现)。但是,我尝试首先合并一些概念。

在我看来,至少有两种可能的验证:

  • 定期验证字段 ,例如,检查属性是否为null,检查String属性是否为有效的电子邮件,检查Integer属性是否大于10,等等。这可以按预期工作。我已经注册了JAX-RS ExceptionMapper,它将映射javax.validation.ConstraintViolationException到正确的HTTP响应。
  • 数据完整性验证

我将通过一个示例来解释“数据完整性验证”的确切含义。当两个或多个资源之间存在关系时,会发生这种情况。想象两个资源:a Product和a
Category。A Product Category。当客户端将要Product创建的表示发送到服务器(POST
HTTP请求)时,它必须通知Category产品。当然,客户必须事先知道类别。想象一下JSON:

{
   "quantity": "10",
   "state": "PRODUCED",
   "category": {
      "id": "123"
   }
}

好吧,ID类别123可能不存在。如果我们尝试将其插入数据库,显然会得到与外键相关的异常。因此,我认为我们必须验证这些问题并向客户端返回正确的消息,就像常规的属性验证一样。


现在,我的主要问题是:

  1. 现在,我正在通过JPA与Bean验证的集成在数据访问级别执行验证。应在验证完成 前/后的序列化过程前/后数据库操作两者
  2. 如何处理 数据完整性验证手动吗?(即显式咨询数据库以检查数据完整性)还是我们还是应该尝试将其插入然后捕获数据库(或DAO)异常?Bean验证与这种验证无关,对吗?
  3. 如果您有使用JAX-RS / REST和Bean验证的经验,请告诉我,我们将很高兴。使用群组?

这些问题在某种程度上与Java有关,但我也希望对这些问题有一些新的认识。 一些技术独立的。:)如果您可以在REST
Web服务上为这些问题提供自己的解决方案,那就太好了。


阅读 215

收藏
2020-11-13

共1个答案

小编典典

该解决方案最终归为JacksonJaxbJsonProvider实现了JAX-RS
MessageBodyReader和的Jackson’s的子类MessageBodyWriter。惊人的Dropwizard的方法使我受到启发。在此提供程序中,我们需要以某种方式注入Validator实例(我将Spring用于注入,将Hibernate
Validator用于JSR-303实现)。如果您使用Hibernate ORM,请不要忘记禁用实体验证,否则您将两次验证同一实体。不过,这可能是所需要的。

然后,在这个子类中MessageBodyReader,我验证对象并抛出一个InvalidEntityException来自验证器的错误的自定义。我还创建了一个JAX-
RS
ExceptionMapper<InvalidEntityException>,该映射将每个映射InvalidEntityException到正确的HTTP响应中。在我的情况下,我返回了错误请求和包含错误描述的JSON对象。

请注意,此MessageBodyReader会检查@Valid@Validated注释。这意味着它正确支持组。这很重要,因为我们可能不想在整个应用程序中进行相同的验证。例如,当我们要进行部分更新(PUT)时。或者,例如,id属性在POST请求中必须为null,但在其他所有地方都不为null。

数据完整性验证尚未完全处理。但是我正计划捕获数据库异常并将它们转换为我自己的域异常(例如DataIntegrityException),因为它看起来效率更高且与我无关。


更新:

从JAX-RS
2开始,推荐的方法是使用其Bean验证支持。在这里检查:https : //jersey.java.net/documentation/latest/bean-
validation.html

2020-11-13