mig*_*ain 20 java rest jpa jersey bean-validation
我正在使用Spring,Jersey和Hibernate(JPA)在Java中构建REST Web服务.
现在我正在尝试在我的资源中添加对验证的支持.JSR-303(Bean验证)自然是一个合适的选择(我使用的是Hibernate Validator,它是JSR-303的参考实现).但是,我试图首先巩固一些概念.
在我看来,至少有两种可能的验证:
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"
}
}
Run Code Online (Sandbox Code Playgroud)
好吧,id的类别123可能不存在.如果我们尝试将其插入数据库,显然我们会得到一个与外键相关的异常.所以我假设我们必须验证这些问题并向客户端返回正确的消息,就像在常规属性验证中一样.
现在,我的主要问题是:
这些问题与Java有些相关,但我也希望对这些问题有一些新的看法.一些技术独立的.:)如果您可以在REST Web服务上为这些问题提供自己的解决方案,那就太棒了.
该解决方案最终成为杰克逊的子类JacksonJaxbJsonProvider,后者实现了JAX-RS MessageBodyReader和MessageBodyWriter.我被惊人的dropwizard的方法所激励.在这个提供程序中,我们需要以某种方式注入一个Validator实例(我使用Spring for Injection和Hibernate Validator来实现JSR-303).如果您使用Hibernate ORM,请不要忘记禁用实体验证,否则您将两次验证同一实体.但这可能是所期望的.
然后,在此子类中MessageBodyReader,我验证对象并InvalidEntityException使用验证器中的错误抛出自定义.我还创建了一个JAX-RS ExceptionMapper<InvalidEntityException>,它将每个映射InvalidEntityException到正确的HTTP响应中.在我的例子中,我返回了一个Bad Request和一个包含错误描述的JSON对象.
请注意,此MessageBodyReader会检查@Valid和@Validated注释.这意味着它正确支持组.这很重要,因为我们可能不希望在整个应用程序中进行相同类型的验证.一个例子是我们想要进行部分更新(PUT).或者,例如,id属性在POST请求中必须为null,但在其他任何地方都不为null.
数据完整性验证尚未完全处理.但我计划捕获数据库异常并将它们转换为我自己的域异常(比如说a DataIntegrityException),因为它似乎更有效,并且松散地耦合到我身上.
更新:
从JAX-RS 2开始,推荐的方法是使用它的Bean Validation支持.点击此处:https://jersey.java.net/documentation/latest/bean-validation.html
您现在可以使用Jersey 2.0通过JSR-303/JSR-349验证资源参数.
https://jersey.java.net/documentation/latest/bean-validation.html#d0e9301
| 归档时间: |
|
| 查看次数: |
27232 次 |
| 最近记录: |