Return-Path: X-Original-To: archive-asf-public-internal@cust-asf2.ponee.io Delivered-To: archive-asf-public-internal@cust-asf2.ponee.io Received: from cust-asf.ponee.io (cust-asf.ponee.io [163.172.22.183]) by cust-asf2.ponee.io (Postfix) with ESMTP id 70D02200BD1 for ; Mon, 28 Nov 2016 23:47:29 +0100 (CET) Received: by cust-asf.ponee.io (Postfix) id 6F82B160B0D; Mon, 28 Nov 2016 22:47:29 +0000 (UTC) Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by cust-asf.ponee.io (Postfix) with SMTP id EB50D160B00 for ; Mon, 28 Nov 2016 23:47:27 +0100 (CET) Received: (qmail 17430 invoked by uid 500); 28 Nov 2016 22:47:27 -0000 Mailing-List: contact commits-help@cxf.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@cxf.apache.org Delivered-To: mailing list commits@cxf.apache.org Received: (qmail 17317 invoked by uid 99); 28 Nov 2016 22:47:26 -0000 Received: from pnap-us-west-generic-nat.apache.org (HELO spamd2-us-west.apache.org) (209.188.14.142) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 28 Nov 2016 22:47:26 +0000 Received: from localhost (localhost [127.0.0.1]) by spamd2-us-west.apache.org (ASF Mail Server at spamd2-us-west.apache.org) with ESMTP id 6E91B1AB72D for ; Mon, 28 Nov 2016 22:47:26 +0000 (UTC) X-Virus-Scanned: Debian amavisd-new at spamd2-us-west.apache.org X-Spam-Flag: NO X-Spam-Score: -1.198 X-Spam-Level: X-Spam-Status: No, score=-1.198 tagged_above=-999 required=6.31 tests=[KAM_ASCII_DIVIDERS=0.8, KAM_LAZY_DOMAIN_SECURITY=1, RP_MATCHES_RCVD=-2.999, URIBL_BLOCKED=0.001] autolearn=disabled Received: from mx1-lw-us.apache.org ([10.40.0.8]) by localhost (spamd2-us-west.apache.org [10.40.0.9]) (amavisd-new, port 10024) with ESMTP id BSBmzzm5DRj2 for ; Mon, 28 Nov 2016 22:47:21 +0000 (UTC) Received: from mailrelay1-us-west.apache.org (mailrelay1-us-west.apache.org [209.188.14.139]) by mx1-lw-us.apache.org (ASF Mail Server at mx1-lw-us.apache.org) with ESMTP id 397785FC81 for ; Mon, 28 Nov 2016 22:47:21 +0000 (UTC) Received: from svn01-us-west.apache.org (svn.apache.org [10.41.0.6]) by mailrelay1-us-west.apache.org (ASF Mail Server at mailrelay1-us-west.apache.org) with ESMTP id 2EEBBE01A7 for ; Mon, 28 Nov 2016 22:47:05 +0000 (UTC) Received: from svn01-us-west.apache.org (localhost [127.0.0.1]) by svn01-us-west.apache.org (ASF Mail Server at svn01-us-west.apache.org) with ESMTP id D1A5D3A0339 for ; Mon, 28 Nov 2016 22:47:04 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1001797 - in /websites/production/cxf/content: cache/docs.pageCache docs/validationfeature.html Date: Mon, 28 Nov 2016 22:47:04 -0000 To: commits@cxf.apache.org From: buildbot@apache.org X-Mailer: svnmailer-1.0.9 Message-Id: <20161128224704.D1A5D3A0339@svn01-us-west.apache.org> archived-at: Mon, 28 Nov 2016 22:47:29 -0000 Author: buildbot Date: Mon Nov 28 22:47:04 2016 New Revision: 1001797 Log: Production update by buildbot for cxf Modified: websites/production/cxf/content/cache/docs.pageCache websites/production/cxf/content/docs/validationfeature.html Modified: websites/production/cxf/content/cache/docs.pageCache ============================================================================== Binary files - no diff available. Modified: websites/production/cxf/content/docs/validationfeature.html ============================================================================== --- websites/production/cxf/content/docs/validationfeature.html (original) +++ websites/production/cxf/content/docs/validationfeature.html Mon Nov 28 22:47:04 2016 @@ -0,0 +1,362 @@ + + + + + + + + + + + + + + + + + + + + + + + + +Apache CXF -- ValidationFeature + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
   
   + + + +
+ + + + + +
+ + + +
+
+
  
  + + + + + +
+ + + +
+

Bean Validation Feature

 

Introduction

Bean Validation 1.1 (JSR-349), an evolution of Bean Validation 1.0 (JSR-303), introduces declarative constraints (based on Java annotations) to define the expectations for:

  • properties of Java Beans
  • method and constructor parameters
  • method return values

For example:

+
public class Person {
+    @NotNull private String firstName;
+    @NotNull private String lastName;
+    @Valid @NotNull private Person boss;
+
+    public @NotNull String saveItem( @Valid @NotNull Person person, @Max( 23 ) BigDecimal age ) {
+        // ...
+    }
+}
+
+

Bean Validation API has been part of JPA 2.0 (JSR-317) and has proven to be successful and very useful, helping developers to delegate routine validation tasks to the solid, very extensible framework. It is very easy to create own constraints, including complex cross-field ones.

Dependencies

Bean Validation support in Apache CXF is implementation-independent and is built solely using Bean Validation API. The required dependencies are:

+
<dependency>
+    <groupId>javax.validation</groupId>
+    <artifactId>validation-api</artifactId>
+    <version>1.1.0.Final</version>
+</dependency>
+<dependency>
+    <groupId>javax.el</groupId>
+    <artifactId>javax.el-api</artifactId>
+    <!-- use 3.0-b02 version for Java 6 -->
+    <version>3.0.0</version>
+</dependency>
+<dependency>
+    <groupId>org.glassfish</groupId>
+    <artifactId>javax.el</artifactId>
+    <!-- use 3.0-b01 version for Java 6 -->
+    <version>3.0.0/version>
+</dependency>
+
+

A couple of API implementations is available. Please note that if no implementation is detected on the runtime class-path then the constraints validation won't have any effect.

Using Hibernate Validator as bean validation provider

http://www.hibernate.org/subprojects/validator.html

Hibernate Validator is a mature and feature-rich validation provider with the full Bean Validation 1.1 support (as of version 5.x.x which is the reference implementation for JSR 349 - Bean Validation 1.1 API). Add the following dependency:

+
<dependency>
+    <groupId>org.hibernate</groupId>
+    <artifactId>hibernate-validator</artifactId>
+    <version>5.0.2.Final</version>
+</dependency>
+
+

Hibernate Validator uses Java Expression Language 3.0 in order to provide better validation messages support.

Using Apache BVal as bean validation provider

http://bval.apache.org/

Current stable version of Apache BVal (0.5) doesn't support Bean Validation 1.1 but the upcoming 1.1.0 will have it fully implemented (at the moment 1.1.0-alpha-SNAPSHOT could be used).

+
<dependency>
+    <groupId>org.apache.bval</groupId>
+    <artifactId>bval-jsr</artifactId>
+    <version>1.1.0-alpha-SNAPSHOT</version>
+</dependency>
+
+

Common Bean Validation 1.1 Interceptors

JAX-RS and JAX-WS frontends can rely on the following common interceptors to get Bean Validation 1.1 done:

Both interceptors depend on org.apache.cxf.validation.BeanValidationProvider which abstracts away Bean Validation 1.1 API and provides useful utility methods. This provider can be directly injected into the interceptors as a 'provider' property. Injecting the provider is optional, the interceptors will create a default provider instance if it has not been injected.

CXF exception handlers can check if a caught javax.validation.ValidationException is an instance of CXF-specific ResponseConstraintViolationException in order to find whether the failure occurr ed during the return value validation or not.

The provider can be initialized with javax.validation.ParameterNameProvider or ValidationConfiguration in order to customize the way Bean Validation 1.1 implementation does its work.

Note that interceptors will only be effective if the current service object is a singleton. They will make a best effort of getting hold of a reference to the current service object, which can also be injected directly as a 'serviceObject' property.

Custom interceptors can customize the default processing (for example, see the section on Bean Validation 1.1 in JAX-RS 2.0). Typical customization is to have one of the input parameters or the response value unwrapped before it can be validated.

org.apache.cxf.validation.BeanValidationFeature can be used to register both in and out validation interceptors.

Configuration

The following snippets show how to get Bean Validation 1.1 interceptors activated for both JAX-RS and JAX-WS services using Spring:

+
// Interface implemented by both JAX-RS and JAX-WS services:
+@WebService(targetNamespace = "http://bookworld.com")
+@Path("/")
+public interface BookWorld {
+
+    @POST
+    @Produces("text/xml")
+    @Consumes("text/xml")
+    @Valid
+    BookWithValidation echoBook(@Valid BookWithValidation book);
+
+}
+
+@WebService(endpointInterface = "org.apache.cxf.systest.jaxrs.validation.spring.BookWorld",
+            serviceName = "BookWorld")
+public class BookWorldImpl implements BookWorld {
+
+    @Override
+    public BookWithValidation echoBook(BookWithValidation book) {
+        return book;
+    }
+}
+
+
+
+
<!-- JAX-RS and JAX-WS endpoints -->
+<jaxrs:server address="/bwrest">
+        <jaxrs:serviceBeans>
+            <ref bean="bookWorldValidation"/>
+        </jaxrs:serviceBeans>
+        <jaxrs:providers>
+            <ref bean="exceptionMapper"/>
+        </jaxrs:providers>
+        <jaxrs:features>
+            <ref bean="commonValidationFeature" />
+        </jaxrs:features>
+</jaxrs:server>
+    
+<jaxws:endpoint xmlns:s="http://bookworld.com" 
+                serviceName="s:BookWorld" 
+                endpointName="s:BookWorldPort" 
+                implementor="#bookWorldValidation" 
+                address="/bwsoap">
+    <jaxws:features>
+        <ref bean="commonValidationFeature" />
+     </jaxws:features>
+</jaxws:endpoint>                
+    
+<bean id="bookWorldValidation" class="org.apache.cxf.systest.jaxrs.validation.spring.BookWorldImpl"/>
+<bean id="commonValidationFeature" class="org.apache.cxf.validation.BeanValidationFeature"/>
+
+

Check the next section for more examples specific to JAX-RS.

Bean Validation 1.1 and JAX-RS 2.0

Server

JAX-RS 2.0 specification (Chapter 7) introduces an optional requirement to get Bean Validation 1.1 supported.

Using the common interceptors described in the previous section can be sufficient for JAX-RS 2.0 resource methods having their input parameters and response values validated.

However, if you need a response values wrapped in JAX-RS Response validated or make sure per-request service instances get validated then JAX-RS frontend specific interceptors and the invoker need to be used:

  • org.apache.cxf.jaxrs.validation.JAXRSBeanValidationInInterceptor: validates JAX-RS resource method parameters. At the moment it is nearly identical to the common BeanValidationInInterceptor which it extends. It can also be used as a JAX-RS 2.0 ContainerRequestFilter
  • org.apache.cxf.jaxrs.validation.JAXRSBeanValidationOutInterceptor: validates JAX-RS resource method return values, unwraps JAX-RS Response. It can also be used as a JAX-RS 2.0 ContainerResponseFilter
  • org.apache.cxf.jaxrs.validation.JAXRSBeanValidationFeature can be used to register both in and out validation interceptors.
  • org.apache.cxf.jaxrs.validation.JAXRSBeanValidationInvoker needs to be used for validating non-singleton service objects, see below for more information.

Note the default JAX-RS ExceptionMapper (org.apache.cxf.jaxrs.validation.ValidationExceptionMapper) which transforms javax.validation.ValidationException to corresponding HTTP status code has to be registered. Users can register the custom mappers if preferred.

org.apache.cxf.jaxrs.validation.JAXRSParameterNameProvider can be registered directly with the common Bean ValidationProvider to get the error messages customized.

JAX-RS 2.0 developers should prefer using JAX-RS frontend specific interceptors when possible to make sure JAX-RS specific fixes are picked up automatically.

Validation of non-singleton service objects

The non-singleton service objects are created in CXF JAXRSInvoker therefore its subclass org.apache.cxf.jaxrs.validation.JAXRSBeanValidationInvoker needs to be registered if these objects need to be validated.

Register it either in a jaxrs:invoker block when using Spring or Blueprint or with a "jaxrs.invoker" servlet init parameter when using CXFNonSpringJaxrsServlet.

 

Configuring Bean Validation 1.1 using JAXRSServerFactoryBean

+
JAXRSServerFactoryBean sf = new JAXRSServerFactoryBean();
+sf.setResourceClasses( ... );
+sf.setResourceProvider( ... );
+sf.setProvider(new ValidationExceptionMapper());
+sf.setInInterceptors(Arrays.< Interceptor< ? extends Message > >asList(new new JAXRSBeanValidationInInterceptor()));
+sf.setOutInterceptors(Arrays.< Interceptor< ? extends Message > >asList(new JAXRSBeanValidationOutInterceptor()));
+sf.create();
+
+

Configuring Bean Validation 1.1 using Spring bean definitions XML

Following the similar approach as for JAXRSServerFactoryBean, in case of Spring respective bean definitions should be added under <jaxrs:outInterceptors>, <jaxrs:inInterceptors> and <jaxrs:providers> sections, f.e.:

+
<jaxrs:server address="/">
+    <jaxrs:inInterceptors>
+        <ref bean="validationInInterceptor" />
+    </jaxrs:inInterceptors>
+        
+    <jaxrs:outInterceptors>
+        <ref bean="validationOutInterceptor" />
+    </jaxrs:outInterceptors>
+        
+    <jaxrs:serviceBeans>
+    ...
+    </jaxrs:serviceBeans>
+        
+    <jaxrs:providers>
+        <ref bean="exceptionMapper"/>
+    </jaxrs:providers>
+</jaxrs:server>
+
+<bean id="exceptionMapper" class="org.apache.cxf.jaxrs.validation.ValidationExceptionMapper"/>
+<bean id="validationProvider" class="org.apache.cxf.validation.BeanValidationProvider" />
+
+<bean id="validationInInterceptor" class="org.apache.cxf.jaxrs.validation.JAXRSBeanValidationInInterceptor">
+    <property name="provider" ref="validationProvider" />
+</bean>
+
+<bean id="validationOutInterceptor" class="org.apache.cxf.jaxrs.validation.JAXRSBeanValidationOutInterceptor">
+    <property name="provider" ref="validationProvider" />
+</bean>   
+
+

Validation Exceptions and HTTP status codes

As per JAX-RS 2.0 specification, any input parameter validation violation is mapped to HTTP status code 400 Bad Request and any return value validation violation (or internal validation violation) is mapped to HTTP status code 500 Internal Server Error. This is essentially what org.apache.cxf.jaxrs.validation.ValidationExceptionMapper does.

The details of validation exceptions are not currently included into the response but only logged. Application developers are encouraged to register custom exception mappers if reporting the validation error details is required.

Client Prox ies

CXF 3.1.9 introduces an org.apache.cxf.jaxrs.client.validation.JAXRSClientBeanValidationFeature which can be used to validate the request parameters of a JAX-RS proxy method.

Customizing Validation Provider

org.apache.cxf.validation.BeanValidationProvider is a wrapper around javax.validation.ValidationFactory and used by CXF validation interceptors.

It is created if it has not been injected. However if one needs to customize javax.validation.ValidationFactory then a custom BeanValidationProvider instance can be injected via the 'provider' property into

the bean validation interceptors.BeanValidationProvider has the default constructor, the one accepting javax.validat ion.ParameterNameProvider, etc, see the source for more details.

For example, one can customize the way parameters can be described on the JAX-RS path by injecting JAXRSParameterNameProvider into BeanValidationProvider.

Examples

The following examples show JAX-RS resource methods being validated but predefined or custom Bean Validation 1.1 constraints can be applied to JAX-WS service methods exactly the same way.

Validating simple input parameters

+
@POST
+@Path("/books")
+public Response addBook(
+        @NotNull @Pattern(regexp = "\\d+") @FormParam("id") String id,
+        @NotNull @Size(min = 1, max = 50) @FormParam("name") String name) {
+    // do some work
+    return Response.created().build();
+}
+
+

Validating complex input parameters

+
@POST
+@Path("/books")
+public Response addBook( @Valid Book book ) {
+    // do some work
+    return Response.created().build();
+}
+
+

This example assumes that class Book has validation constraints defined:

+
public class Book {
+    @NotNull @Pattern(regexp = "\\d+") private String id;
+    @NotNull @Size(min = 1, max = 50) private String name;
+
+    // ...
+}
+
+

Validating return values (non-Response)

+
@GET
+@Path("/books/{bookId}")
+@Override    
+@NotNull @Valid
+public Book getBook(@PathParam("bookId") String id) {
+    return new Book( id );     
+}
+
+

This example assumes that class Book has validation constraints defined (as in example above).

Validating return values (Response)

+
@GET
+@Path("/books/{bookId}")
+@Valid @NotNull
+public Response getBookResponse(@PathParam("bookId") String id) {
+    return Response.ok( new Book( id ) ).build();
+}
+
+

Bean Validation and Schema Validation

Web service developers often rely on the schema-based validation.

Bean validation can be used as an alternative form of validation.

However it can also complement the schema-based validation in cases where the current schema is not very strict.

+
+ +
+
 
   + +   
   
+ + + + + + +