cxf-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From conflue...@apache.org
Subject [CONF] Apache CXF Documentation > JAX-RS Basics
Date Wed, 22 Dec 2010 14:42:00 GMT
<html>
<head>
    <base href="https://cwiki.apache.org/confluence">
            <link rel="stylesheet" href="/confluence/s/1810/9/1/_/styles/combined.css?spaceKey=CXF20DOC&amp;forWysiwyg=true" type="text/css">
    </head>
<body style="background: white;" bgcolor="white" class="email-body">
<div id="pageContent">
<div id="notificationFormat">
<div class="wiki-content">
<div class="email">
    <h2><a href="https://cwiki.apache.org/confluence/display/CXF20DOC/JAX-RS+Basics">JAX-RS Basics</a></h2>
    <h4>Page <b>edited</b> by             <a href="https://cwiki.apache.org/confluence/display/~sergey_beryozkin">Sergey Beryozkin</a>
    </h4>
        <br/>
                         <h4>Changes (1)</h4>
                                 
    
<div id="page-diffs">
            <table class="diff" cellpadding="0" cellspacing="0">
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" >In such cases it&#39;s possible to override the default @Produces and/or @Consumes types supported by a given provider. It only currently works for JAXBElementProvider and JSONProvider, but any custom provider can avail of this support by simply having setter/getter pairs for either produce and/or consume types and the JAXRS runtime will use them instead. <br>See [this example|http://svn.apache.org/repos/asf/cxf/trunk/systests/jaxrs/src/test/resources/jaxrs/WEB-INF/beans.xml] on how to provide custom media types from Spring. <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;"> <br>h1. Working with HTTP headers <br> <br>h1. Advanced HTTP <br> <br>The JAX-RS specification requires support for a number of advanced HTTP features. <br> <br>JAX-RS Request context object can be used to check the preconditions expressed via headers such as If-Match, If-None-Match, If-Modified-Since and If-Unmodified-Since.  <br> <br>JAX-RS also makes it easier to work with ETag, Vary, CacheControl, Cookie and Set-Cookie headers. <br></td></tr>
        </table>
</div>                            <h4>Full Content</h4>
                    <div class="notificationGreySide">
        <span style="font-size:2em;font-weight:bold"> JAX-RS : Understanding the Basics </span>

<div>
<ul>
    <li><a href='#JAX-RSBasics-Resourceclass'>Resource class</a></li>
    <li><a href='#JAX-RSBasics-@Path'>@Path</a></li>
    <li><a href='#JAX-RSBasics-HTTPMethod'>HTTP Method</a></li>
    <li><a href='#JAX-RSBasics-Returntypes'>Return types</a></li>
    <li><a href='#JAX-RSBasics-Exceptionhandling'>Exception handling</a></li>
    <li><a href='#JAX-RSBasics-DealingwithParameters'>Dealing with Parameters</a></li>
<ul>
    <li><a href='#JAX-RSBasics-Parameterbeans'>Parameter beans</a></li>
</ul>
    <li><a href='#JAX-RSBasics-Resourcelifecycles'>Resource lifecycles</a></li>
    <li><a href='#JAX-RSBasics-Overviewoftheselectionalgorithm.'>Overview of the selection algorithm.</a></li>
<ul>
    <li><a href='#JAX-RSBasics-Selectingbetweenmultipleresourceclasses'>Selecting between multiple resource classes</a></li>
    <li><a href='#JAX-RSBasics-Selectingbetweenmultipleresourcemethods'>Selecting between multiple resource methods</a></li>
    <li><a href='#JAX-RSBasics-Resourcemethodsandmediatypes'>Resource methods and media types</a></li>
    <li><a href='#JAX-RSBasics-Customselectionbetweenmultipleresources'>Custom selection between multiple resources</a></li>
</ul>
    <li><a href='#JAX-RSBasics-Contextannotations'>Context annotations</a></li>
    <li><a href='#JAX-RSBasics-URIscalculationusingUriInfoandUriBuilder'>URIs calculation using UriInfo and UriBuilder</a></li>
    <li><a href='#JAX-RSBasics-Annotationinheritance'>Annotation inheritance</a></li>
    <li><a href='#JAX-RSBasics-Subresourcelocators.'>Sub-resource locators.</a></li>
<ul>
    <li><a href='#JAX-RSBasics-Staticresolutionofsubresources'>Static resolution of subresources</a></li>
</ul>
    <li><a href='#JAX-RSBasics-MessageBodyProviders'>Message Body Providers</a></li>
<ul>
    <li><a href='#JAX-RSBasics-CustomMessageBodyProviders'>Custom Message Body Providers</a></li>
    <li><a href='#JAX-RSBasics-Registeringcustomproviders'>Registering custom providers</a></li>
</ul>
    <li><a href='#JAX-RSBasics-Customizingmediatypesformessagebodyproviders'>Customizing media types for message body providers</a></li>
    <li><a href='#JAX-RSBasics-WorkingwithHTTPheaders'>Working with HTTP headers</a></li>
    <li><a href='#JAX-RSBasics-AdvancedHTTP'>Advanced HTTP</a></li>
</ul></div>

<h1><a name="JAX-RSBasics-Resourceclass"></a>Resource class</h1>

<p>A resource class is a Java class annotated with JAX-RS annotations to represent a Web resource. Two types of resource classes are available: root resource classes and subresource classes. A root resource class is annotated with at least a @Path annotation, while subresource classes typically have no root @Path values. A typical root resource class in JAX-RS looks like this below:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
<span class="code-keyword">package</span> demo.jaxrs.server;

java.util.HashMap;
<span class="code-keyword">import</span> java.util.Map;

<span class="code-keyword">import</span> javax.ws.rs.GET;
<span class="code-keyword">import</span> javax.ws.rs.Path;
<span class="code-keyword">import</span> javax.ws.rs.PathParam;
<span class="code-keyword">import</span> javax.ws.rs.Produces;
<span class="code-keyword">import</span> javax.ws.rs.core.Response;

@Path(<span class="code-quote">"/customerservice/"</span>)
@Produces(<span class="code-quote">"application/xml"</span>)
<span class="code-keyword">public</span> class CustomerService {

    <span class="code-keyword">public</span> CustomerService() {
    }

    @GET
    <span class="code-keyword">public</span> Customers getCustomers() {
        ......
    }

    @GET
    @Path(<span class="code-quote">"/customers/{id}"</span>)
    @Produces(<span class="code-quote">"application/json"</span>)
    <span class="code-keyword">public</span> Customer getCustomer(@PathParam(<span class="code-quote">"id"</span>) <span class="code-object">String</span> id) {
        ......
    }

    @PUT
    @Path(<span class="code-quote">"/customers/{id}"</span>)
    @Consumes(<span class="code-quote">"application/xml"</span>)
    <span class="code-keyword">public</span> Response updateCustomer(@PathParam(<span class="code-quote">"id"</span>) <span class="code-object">Long</span> id, Customer customer) {
        ......
    }

    @POST
    @Path(<span class="code-quote">"/customers"</span>)
    <span class="code-keyword">public</span> Response addCustomer(Customer customer) {
        ......
    }

    @DELETE
    @Path(<span class="code-quote">"/customers/{id}/"</span>)
    <span class="code-keyword">public</span> Response deleteCustomer(@PathParam(<span class="code-quote">"id"</span>) <span class="code-object">String</span> id) {
        ......
    }

    @Path(<span class="code-quote">"/orders/{orderId}/"</span>)
    <span class="code-keyword">public</span> Order getOrder(@PathParam(<span class="code-quote">"orderId"</span>) <span class="code-object">String</span> orderId) {
       ......
    }
}
</pre>
</div></div>

<p>Customer resource class can handle requests starting from /customerservice. When /customerservice requests are matched to this class, its getCustomers() method will be selected. updateCustomer(), deleteCustomer() and addCustomer() are used to serve POST, PUT and DELETE requests starting from /customerservice/customer, while getOrder() method delegates the handling of requests like /customerservice/orders/1 to a subresource locator Order.</p>

<p>The &#64;Produces annotation is used to specify the format of the response. When not available on the resource method, it's inherited from a class, and if it's not available on the class then it's inherited from a corresponding message body writer, if any. Default value is &#42;/&#42;, but it's recommended that some definite value is specified. The same applies to &#64;Consumes, except that it's the message body <em>readers</em> that are checked as the last resort.</p>

<p>For example, getCustomers() method inherits &#64;Produces annotation from its class, while getCustomer() method overrides it with its own value.  </p>

<h1><a name="JAX-RSBasics-@Path"></a>@Path</h1>

<p>The @Path annotation is applied to resource classes or methods. The value of @Path annotation is a relative URI path and follows the URI Template format and may include arbitrary regular expressions. When not available on the resource method, it's inherited from a class. For example:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
@Path(<span class="code-quote">"/customers/{id}"</span>)
<span class="code-keyword">public</span> class CustomerResource {

    @GET
    <span class="code-keyword">public</span> Customer getCustomer(@PathParam(<span class="code-quote">"id"</span>) <span class="code-object">Long</span> id) {
        ......
    }

    @GET
    @Path(<span class="code-quote">"/order/{orderid}"</span>)
    <span class="code-keyword">public</span> Order getOrder(@PathParam(<span class="code-quote">"id"</span>) <span class="code-object">Long</span> customerId, @PathParam(<span class="code-quote">"orderid"</span>) <span class="code-object">Long</span> orderId) {
        ......
    }

    @GET
    @Path(<span class="code-quote">"/order/{orderid}/{search:.*}"</span>)
    <span class="code-keyword">public</span> Item findItem(@PathParam(<span class="code-quote">"id"</span>) <span class="code-object">Long</span> customerId, 
                         @PathParam(<span class="code-quote">"orderid"</span>) <span class="code-object">Long</span> orderId,
                         @PathParam(<span class="code-quote">"search"</span>) <span class="code-object">String</span> searchString,
                         @PathParam(<span class="code-quote">"search"</span>) List&lt;PathSegment&gt; searchList) {
        ......
    }
}

</pre>
</div></div> 

<p>This example is similar to the one above it, but it also shows that an {id} template variable specified as part of the root &#64;Path expression is reused by resource methods and a custom regular expression is specified by a findItem() method (note that a variable name is separated by ':' from an actual expression).</p>

<p>In this example, a request like 'GET /customers/1/order/2/price/2000/weight/2' will be served by the findItem() method.<br/>
List&lt;PathSegment&gt; can be used to get to all the path segments in 'price/2000/weight/2' captured by the regular expression.</p>

<p>More information about Path annotations can be found from <a href="http://jcp.org/en/jsr/detail?id=311" class="external-link" rel="nofollow">JAX-RS spec </a> section 2.3. </p>

<h1><a name="JAX-RSBasics-HTTPMethod"></a>HTTP Method</h1>

<p>The JAX-RS specification defines a number of annotations such as @GET, @PUT, @POST and @DELETE. Using an @HttpMethod designator, one can create a custom annotation such as @Update or @Patch. For example :</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
<span class="code-keyword">package</span> org.apache.cxf.customverb;

<span class="code-keyword">import</span> java.lang.annotation.ElementType;
<span class="code-keyword">import</span> java.lang.annotation.Retention;
<span class="code-keyword">import</span> java.lang.annotation.RetentionPolicy;
<span class="code-keyword">import</span> java.lang.annotation.Target;

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@HttpMethod(<span class="code-quote">"PATCH"</span>)
<span class="code-keyword">public</span> @<span class="code-keyword">interface</span> PATCH { 
}
</pre>
</div></div>

<h1><a name="JAX-RSBasics-Returntypes"></a>Return types</h1>

<p>Either javax.ws.rs.core.Response or custom type can be returned. javax.ws.rs.core.Response can be used to set the HTTP response code, headers and entity. JAX-RS MessageBodyWriters (see below) are in charge of serializing the response entities, those which are returned directly or as part of javax.ws.rs.core.Response.</p>

<h1><a name="JAX-RSBasics-Exceptionhandling"></a>Exception handling</h1>

<p>One can either throw an unchecked WebApplicationException or return Response with a proper error code set.<br/>
The former option may be a better one when no JAX-RS types can be added to method signatures.</p>

<p>For example :</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
@Path(<span class="code-quote">"/customerservice/"</span>)
<span class="code-keyword">public</span> class CustomerService {

    
    @PUT
    @Path(<span class="code-quote">"/customers/{id}"</span>)
    <span class="code-keyword">public</span> Response updateCustomer(@PathParam(<span class="code-quote">"id"</span>) <span class="code-object">Long</span> id, Customer customer) {
        <span class="code-keyword">return</span> Response.status(errorCode).build();
    }

    @POST
    @Path(<span class="code-quote">"/customers"</span>)
    <span class="code-keyword">public</span> Customer addCustomer(Customer customer) {
        <span class="code-keyword">throw</span> <span class="code-keyword">new</span> WebApplicationException(errorCode);
    }

}
</pre>
</div></div>

<p>Yet another option is to register an ExceptionMapper provider. Ex :</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
<span class="code-keyword">public</span> BookExceptionMapper <span class="code-keyword">implements</span> ExceptionMapper&lt;BookException&gt; {
    <span class="code-keyword">public</span> Response toResponse(BookException ex) {
        <span class="code-comment">// convert to Response
</span>    }
}
</pre>
</div></div>

<p>This allows to throw a checked or runtime exception from an application code and map it to an HTTP response in a registered provider.</p>

<p>Have a look please at <a href="http://svn.apache.org/repos/asf/cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/security/SecurityExceptionMapper.java" class="external-link" rel="nofollow">this exception mapper</a> which converts Spring Security exceptions into HTTP 403 error code for another example.</p>

<p>Note that when no mappers are found for custom exceptions, they are propogated (wrapped in ServletException) to the underlying container as required by the specification. Thus one option for intercepting the exceptions is to register a custom servlet filter which will catch ServletExceptions and handle the causes. If no custom servlet filter which can handle ServletExceptions is available then most likely only 500 error status will be reported. </p>

<p>This propogation can be disabled by registering a boolean jaxrs property 'org.apache.cxf.propogate.exception' with a false value. If such property is set and no exception mapper can be found for a given exception then it will be wrapped into an xml error response by the CXF <a href="http://svn.apache.org/repos/asf/cxf/trunk/rt/bindings/xml/src/main/java/org/apache/cxf/binding/xml/interceptor/XMLFaultOutInterceptor.java" class="external-link" rel="nofollow">XMLFaultOutInterceptor</a>. </p>

<p>One can also register a custom CXF out fault interceptor which can handle all the exceptions by writing directly to the HttpServletResponse stream or XMLStreamWriter (as XMLFaultOutInterceptor does). For example, see this <a href="http://svn.apache.org/repos/asf/cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/CustomOutFaultInterceptor.java" class="external-link" rel="nofollow">test interceptor</a>.</p>

<h1><a name="JAX-RSBasics-DealingwithParameters"></a>Dealing with Parameters</h1>

<p>PathParam annotation is used to map a given Path template variable to a method parameter.<br/>
For example :</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">

@Path(<span class="code-quote">"/customer/{id}"</span>)
<span class="code-keyword">public</span> class CustomerService {

    
    @PUT
    @Path(<span class="code-quote">"{name}"</span>)
    <span class="code-keyword">public</span> Response updateCustomer(@PathParam(<span class="code-quote">"id"</span>) <span class="code-object">Long</span> id, @PathParam(<span class="code-quote">"name"</span>) <span class="code-object">String</span> name) {
        ...
    }
}
</pre>
</div></div>

<p>In this case a template variable id available from a root class annotation is mapped to a parameter of type Long, while a name variable is mapped to a parameter of type String.</p>

<p>&#64;QueryParam, &#64;HttpHeader, &#64;MatrixParam, &#64;FormParam and &#64;CookieParam annotations are also supported.<br/>
Parameters can be of type String or of any type that have constructors accepting a String parameter or static valueOf(String s) methods. <br/>
Additionally CXF JAXRS checks for static fromString(String s) method, so types with no valueOf(String) factory methods can also be dealt with :</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">

<span class="code-keyword">public</span> <span class="code-keyword">enum</span> Gender {
   MALE,
   FEMALE;

   <span class="code-keyword">public</span> <span class="code-keyword">static</span> fromString(<span class="code-object">String</span> s) {
       <span class="code-keyword">if</span> (<span class="code-quote">"1"</span>.equals(s)) {
           <span class="code-keyword">return</span> FEMALE;
       } <span class="code-keyword">else</span> <span class="code-keyword">if</span> (<span class="code-quote">"1"</span>.equals(s)) {
           <span class="code-keyword">return</span> MALE;
       }  
       <span class="code-keyword">return</span> valueOf(s); 
   }
}

@Path(<span class="code-quote">"/{g}"</span>)
<span class="code-keyword">public</span> class Service {

    
    @PUT
    @Path(<span class="code-quote">"{id}"</span>)
    <span class="code-keyword">public</span> Response update(@PathParam(<span class="code-quote">"g"</span>) Gender g, @PathParam(<span class="code-quote">"id"</span>) UUID u) {
        ...
    }
}
</pre>
</div></div>

<p>Note that on the trunk enums with fromValue() factory methods are also supported.</p>

<p>JAX-RS PathSegment is also supported. A sequence of identically named parameters (queries, headers, etc) can be mapped to List or Set or SortedSet.  </p>

<p>CXF JAXRS supports ParameterHandler extensions which can be used to deal with method parameters annotated with one of the JAXRS parameter annotations :  </p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
<span class="code-keyword">public</span> class MapHandler <span class="code-keyword">implements</span> ParameterHandler&lt;Map&gt; {
    <span class="code-keyword">public</span> Map fromString(<span class="code-object">String</span> s) {...}
}

@Path(<span class="code-quote">"/map"</span>)
<span class="code-keyword">public</span> class Service {

    
    @PUT
    @Path(<span class="code-quote">"/{mapvalue:(.)+}"</span>)
    <span class="code-keyword">public</span> Response update(@PathParam(<span class="code-quote">"mapvalue"</span>) Map m, <span class="code-object">byte</span>[] bytes) {
        ...
    }
}
</pre>
</div></div>

<p>Note that ParameterHandlers can not be used to deal with parameters representing a message body, "byte[] byte" in this example. MessageBodyReaders have to deal with this task. That said, a given MessageBodyReader implementation can also implement ParameterHandler.</p>

<p>ParameterHandlers can be registered as providers either from Spring or programmatically.</p>

<p>All the parameters are automatically decoded. This can be disabled by using @Encoded annotation.<br/>
Parameters can have a default value set using a DefaultValue annotation :</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">

    <span class="code-keyword">public</span> Response updateCustomer(@DefaultValue(<span class="code-quote">"123"</span>) @QueryParam(<span class="code-quote">"id"</span>) <span class="code-object">Long</span> id, @PathParam(<span class="code-quote">"name"</span>) <span class="code-object">String</span> name) { ... }

</pre>
</div></div>

<p>JAX-RS mandates that only a single method parameter which is not annotated with JAXRS annotations applicable to method parameters is allowed in a resource method. For example :</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
<span class="code-keyword">public</span> Response <span class="code-keyword">do</span>(@PathParam(<span class="code-quote">"id"</span>) <span class="code-object">String</span> id, <span class="code-object">String</span> body) {
}
</pre>
</div></div>

<p>Parameters like 'String body' are expected to represent the request body/input stream. It's the job of JAX-RS MessageBodyReaders to deserialize the request body into an object of the expected type.</p>



<p>Starting from JAX-RS 0.8, it's also possible to inject all types of parameters into fields or through dedicated setters. For ex, the first code fragment in this section can be rewritten like this  :</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
@Path(<span class="code-quote">"/customer/{id}"</span>)
<span class="code-keyword">public</span> class CustomerService {

    @PathParam(<span class="code-quote">"id"</span>)
    <span class="code-keyword">private</span> <span class="code-object">Long</span> id; 
    
    <span class="code-keyword">private</span> <span class="code-object">String</span> name;

    @PathParam(<span class="code-quote">"name"</span>)
    <span class="code-keyword">public</span> setName(<span class="code-object">String</span> name) {
        <span class="code-keyword">this</span>.name = name;
    } 

    @PUT
    @Path(<span class="code-quote">"{name}"</span>)
    <span class="code-keyword">public</span> Response updateCustomer() {
        <span class="code-comment">// use id and name
</span>    }
}
</pre>
</div></div>

<h2><a name="JAX-RSBasics-Parameterbeans"></a>Parameter beans</h2>

<p>There's a CXF extension which makes it possible to inject a sequence of &#64;PathParam, &#64;QueryParam, &#64;FormParam or @MatrixParam parameters into a bean. For ex :</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">

@Path(<span class="code-quote">"/customer/{id}"</span>)
<span class="code-keyword">public</span> class CustomerService {

    
    @PUT
    @Path(<span class="code-quote">"{name}"</span>)
    <span class="code-keyword">public</span> Response updateCustomer(@PathParam("") Customer customer) {
        ...
    }

    @GET
    @Path(<span class="code-quote">"/order"</span>)
    <span class="code-keyword">public</span> Response getCustomerOrder(@PathParam(<span class="code-quote">"id"</span>) <span class="code-object">int</span> customerId, 
                                     @QueryParam("") OrderBean bean,
                                     @MatrixParam("") OrderBean bean) {
        ...
    }

    @POST
    <span class="code-keyword">public</span> Response addCustomerOrder(@PathParam(<span class="code-quote">"id"</span>) <span class="code-object">int</span> customerId,
                                     @FormParam("") OrderBean bean) {
        ...
    }
}

<span class="code-keyword">public</span> class Customer {
   <span class="code-keyword">public</span> void setId(<span class="code-object">Long</span> id) {...}
   <span class="code-keyword">public</span> void setName(<span class="code-object">String</span> s) {...}  
}

<span class="code-keyword">public</span> class OrderBean {
   <span class="code-keyword">public</span> void setId(<span class="code-object">Long</span> id) {...}
   <span class="code-keyword">public</span> void setWeight(<span class="code-object">int</span> w) {...}  
}



</pre>
</div></div>

<p>Note that there's a single @PathParam with an empty value in updateCustomer() - this is an extension bit. The value for a template variable 'id' is injected into Customer.setId(Long id), while the value for 'name' is injected into Customer.setName(String s). The setter methods should have a single parameter, the conversion from the actual value to the parameter instance follows the same procedure as outlined above.</p>

<p>Similarly, in getCustomerOrder(), OrderBean can be injected with corresponding values from a query string like ?id=1&amp;weight=2 or from matrix parameters set as part of one of the path segments : /customer/1/order;id=1;weight=2. Likewise, in addCustomerOrder(), FormParam("") can capture all the values submitted from an HTML form and inject them into OrderBean.</p>

<p>Nested beans are also supported, which among other things, makes it possible to formulate advanced search queries. For example, given the following bean definitions :</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
class Name {
    <span class="code-object">String</span> first;
    <span class="code-object">String</span> last;
}

class Address {
    <span class="code-object">String</span> city;
    <span class="code-object">String</span> state;
}

class Person {
    Name legalName;
    Address homeAddr;
    <span class="code-object">String</span> race;
    <span class="code-object">String</span> sex;
    Date birthDate;
}

class MyService
{
    @GET
    @Path(<span class="code-quote">"/getPerson"</span>)
    Person getPerson(@QueryParam("") Person person);
} 
</pre>
</div></div>

<p>a query like</p>

<p>&gt; /getPerson?sex=M&amp;legalName.first=John&amp;legalName.last=Doe&amp;homeAddr.city=Reno&amp;homeAddr.state=NV </p>

<p>will result in a Person bean being properly initialized and all the search criteria being captured and easily accessible. Note more enhancements are being planned in this area.</p>

<h1><a name="JAX-RSBasics-Resourcelifecycles"></a>Resource lifecycles</h1>

<p>The scopes which are supported by default are Singleton and Prototype(per-request).<br/>
Note that JAXRS MessageBodyWriter and MessageBodyReader providers are always singletons. </p>

<p>Classes with prototype scopes can get JAXRS contexts or parameters injected at the construction time :</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
@Path(<span class="code-quote">"/"</span>)
<span class="code-keyword">public</span> class PerRequestResourceClass {

   <span class="code-keyword">public</span> PerRequestResourceClass(@Context HttpHeaders headers, @QueryParam(<span class="code-quote">"id"</span>) <span class="code-object">Long</span> id) {}
}
</pre>
</div></div> 

<p>Classes with singleton scopes can only have contexts injected at the construction time and it is only a CXFNonSpringJaxrsServlet which can do it. In most cases you can have contexts injected as bean properties straight after the construction time </p>

<p>See the "Lifecycle management" section for more details.</p>

<h1><a name="JAX-RSBasics-Overviewoftheselectionalgorithm."></a>Overview of the selection algorithm.</h1>

<p>The JAX-RS Selection algorithm is used to select root resource classes, resource methods and subresource locators.</p>

<h2><a name="JAX-RSBasics-Selectingbetweenmultipleresourceclasses"></a>Selecting between multiple resource classes</h2>

<p>When multiple resource classes match a given URI request, the following algorithm is used :<br/>
1. Prefer the resource class which has more literal characters in its &#64;Path annotation.</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
@Path(<span class="code-quote">"/bar/{id}"</span>)
<span class="code-keyword">public</span> class Test1 {}
@Path(<span class="code-quote">"/bar/{id}/baz"</span>)
<span class="code-keyword">public</span> class Test2 {}
@Path(<span class="code-quote">"/foo"</span>)
<span class="code-keyword">public</span> class Test3 {}
@Path(<span class="code-quote">"/foo/"</span>)
<span class="code-keyword">public</span> class Test4 {}
</pre>
</div></div> 

<p>Both classes match /bar/1/baz requests but Test2 will be selected as it has 9 Path literal characters compared to 5 in Test1. Similarly, Test4 wins against Test3 when a /foo/ request arrives. </p>

<p>2. Prefer the resource class which has more capturing groups in its &#64;Path annotation.</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
@Path(<span class="code-quote">"/bar/{id}/"</span>)
<span class="code-keyword">public</span> class Test1 {}
@Path(<span class="code-quote">"/bar/{id}/{id2}"</span>)
<span class="code-keyword">public</span> class Test2 {}
</pre>
</div></div>

<p>Both classes match /bar/1/2 requests and both have the same number of literal characters but Test2 will be selected as it has 2 Path capturing groups (id and id1) as opposed to 1 in Test1. </p>

<p>3. Prefer the resource class which has more capturing groups with arbitrary regular expressions in its &#64;Path annotation.</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
@Path(<span class="code-quote">"/bar/{id:.+}/baz/{id2}"</span>)
<span class="code-keyword">public</span> class Test1 {}
@Path(<span class="code-quote">"/bar/{id}/{bar}/{id2}"</span>)
<span class="code-keyword">public</span> class Test2 {}
</pre>
</div></div>

<p>Both classes match /bar/1/baz/2 requests and both have the same number of literal characters and capturing groups but Test1 will be selected as it has 1 Path capturing groups with the arbitrary regular expression (id) as opposed to 0 in Test2. </p>

<h2><a name="JAX-RSBasics-Selectingbetweenmultipleresourcemethods"></a>Selecting between multiple resource methods</h2>

<p>Once the resource class has been selected, the next step is to choose a resource method. If multiple methods can be matched then the same rules which are used for selecting resource classes are applied. Additionally, one more rule is used.</p>

<p>4. Prefer a resource method to a subresource locator method</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
@Path(<span class="code-quote">"/"</span>)
<span class="code-keyword">public</span> class Test1 {

 @Path(<span class="code-quote">"/bar"</span>)
 @GET
 <span class="code-keyword">public</span> Order getOrder() {...}

 @Path(<span class="code-quote">"/bar"</span>)
 <span class="code-keyword">public</span> Order getOrderFromSubresource() {...}
}

<span class="code-keyword">public</span> class Order {

 @Path(<span class="code-quote">"/"</span>)
 @GET
 <span class="code-keyword">public</span> Order getOrder() { <span class="code-keyword">return</span> <span class="code-keyword">this</span>; }

}
</pre>
</div></div>

<p>Both getOrderFromSubresource() and getOrder() methods can be used to serve a /bar request. However, getOrder() wins. </p>

<h2><a name="JAX-RSBasics-Resourcemethodsandmediatypes"></a>Resource methods and media types</h2>

<p>Consider this resource class with 2 resource methods :</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
@Path(<span class="code-quote">"/"</span>)
<span class="code-keyword">public</span> class Test1 {

 @Path(<span class="code-quote">"/bar"</span>)
 @POST 
 @Consumes(<span class="code-quote">"application/json"</span>)
 @Produces(<span class="code-quote">"application/json"</span>)
 <span class="code-keyword">public</span> Order addOrderJSON(OrderDetails details) {...}

 @Path(<span class="code-quote">"/bar"</span>)
 @POST
 @Consumes(<span class="code-quote">"application/xml"</span>)
 @Produces(<span class="code-quote">"application/xml"</span>)
 <span class="code-keyword">public</span> Order getOrderXML(OrderDetails details) {...}
 
}
</pre>
</div></div>

<p>Both methods match /bar requests. If in a given request both Content-Type and Accept are set to application/xml then <br/>
getOrderXML will be selected. If both Content-Type and Accept are set to application/json then <br/>
getOrderJSON will be chosen instead.</p>

<p>For this specific example, in both cases either JAXB or JSON message body readers and writers will be selected to deserialize the input stream into OrderDetails and serialize Order into the output stream. Message body providers can have @Produces and @Consumes set too, and they have to match those on a chosen resource method.  </p>

<p>The above code can be replaced with this one :</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
@Path(<span class="code-quote">"/"</span>)
<span class="code-keyword">public</span> class Test1 {

 @Path(<span class="code-quote">"/bar"</span>)
 @POST 
 @Consumes({<span class="code-quote">"application/json"</span>, <span class="code-quote">"application/xml"</span>})
 @Produces({<span class="code-quote">"application/json"</span>, <span class="code-quote">"application/xml"</span>})
 <span class="code-keyword">public</span> Order addOrder(OrderDetails details) {...}

}
</pre>
</div></div>


<p>TODO : more info</p>


<h2><a name="JAX-RSBasics-Customselectionbetweenmultipleresources"></a>Custom selection between multiple resources</h2>

<p>The JAX-RS selection algorithm has been designed with a lot of attention being paid to various possible cases, as far as the selection between multiple matching resource classes or methods is concerned. </p>

<p>However, in some cases, the users have reported the algorithm being somewhat restrictive in the way multiple resource classes are selected. For example, by default, after a given resource class has been matched and if this class has no matching resource method, then the algorithm stops executing, without attempting to check the remaining matching resource classes.</p>

<p>Starting from CXF 2.2.5 it is possible to register a custom <a href="http://svn.apache.org/repos/asf/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/ResourceComparator.java" class="external-link" rel="nofollow">ResourceComparator</a> implementation using a jaxrs:server/resourceComparator element. </p>

<p>Custom implementations can check the names of the resource classes or methods being compared  and given the current request URI they can make sure that the required class or method is chosen by returning either -1 or 1, as needed. If 0 is returned then the runtime will proceed with executing the default selection algorithm. At the moment the easiest way to get to the details such as the current request URI is to create an instance of the CXF JAXRS UriInfoImpl using a constructor accepting a Message.</p>

<p>Note that by the time a custom ResourceComparator is called the provided resource classes or methods have already been successfully matched by the runtime.</p>


<h1><a name="JAX-RSBasics-Contextannotations"></a>Context annotations</h1>

<p>A number of context types can be injected as parameters, in fields or through dedicated methods.<br/>
UriInfo, SecurityContext, HttpHeaders, Providers, Request, ContextResolver, Servlet types (HttpServletRequest, HttpServletResponse, ServletContext, ServletConfig) can be injected.</p>

<p>A CXF-specific composite context interface, <a href="http://svn.apache.org/repos/asf/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/MessageContext.java" class="external-link" rel="nofollow">MessageContext</a> is also supported which makes it easier to deal with all the supported JAX-RS contexts (and indeed with the future ones) and also lets check the current message's properties.</p>

<p>Example :</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
@Path(<span class="code-quote">"/customer"</span>)
<span class="code-keyword">public</span> class CustomerService {
    
    @Context 
    <span class="code-keyword">private</span> org.apache.cxf.jaxrs.ext.MessageContext mc; 
    @Context 
    <span class="code-keyword">private</span> ServletContext sc;
    <span class="code-keyword">private</span> UriInfo ui;
    
    @Context
    <span class="code-keyword">public</span> void setUriInfo(UriInfo ui) {
        <span class="code-keyword">this</span>.ui = ui;
    }

    @PUT
    <span class="code-keyword">public</span> Response updateCustomer(@Context HttpHeaders h, Customer c) {
        mc.getHttpHeaders();
    }
}

</pre>
</div></div>

<p>Note that all types of supported JAX-RS providers such as MessageBodyWriter, MessageBodyReader, ExceptionMapper and ContextResolver, as well as the list of body providers which can be provided by Providers can have contexts injected too. The only exception is that no parameter level injection is supported for providers due to methods of JAXRS providers being fixed.</p>

<p>Note that Providers and ContextResolver are likely to be of interest to message body providers rather than to the actual application code. You can also inject all the context types into @Resource annotated fields.</p>

<h1><a name="JAX-RSBasics-URIscalculationusingUriInfoandUriBuilder"></a>URIs calculation using UriInfo and UriBuilder</h1>

<p>Mapping of particular URI to service that returns some resource is straightforward using @Path annotation. However RESTful services are often connected: one service returns data that is used as key in another service. Listing entities and accessing particular entity is typical example:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
@Path(<span class="code-quote">"/customers"</span>)
<span class="code-keyword">public</span> class CustomerService {

    @GET
    <span class="code-keyword">public</span> Customers getCustomers() {
        ......
    }

    @GET
    @Path(<span class="code-quote">"/{id}"</span>)
    <span class="code-keyword">public</span> Customer getCustomer(@PathParam(<span class="code-quote">"id"</span>) <span class="code-object">String</span> id) {
        ......
    }

}
</pre>
</div></div>

<p>For this service we can assume that returned list is brief of customers exposing only basic attributes and more details is returned referring to second URL, using customer id as key. Something like this:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
GET http:<span class="code-comment">//foobar.com/api/customers
</span>
&lt;customers&gt;
    &lt;customer id=<span class="code-quote">"1005"</span>&gt;John Doe&lt;/customer&gt;
    &lt;customer id=<span class="code-quote">"1006"</span>&gt;Jane Doe&lt;/customer&gt;
    ...
&lt;/customers&gt;
    
GET http:<span class="code-comment">//foobar.com/api/customers/1005
</span>
&lt;customer id=<span class="code-quote">"1005"</span>&gt;
    &lt;first-name&gt;John&lt;/first-name&gt;
    &lt;last-name&gt;Doe&lt;/last-name&gt;
    ...
&lt;/customer&gt;
</pre>
</div></div>

<p>How does client of this service know how to get from list of customers to given customer? Trivial approach is to expect client to compute proper URI. Wouldn't be better to ease flow through services attaching full URLs that can be used directly? This way client is more decoupled from service itself (that may evolve changing URLs). This way want get something like this:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
GET http:<span class="code-comment">//foobar.com/api/customers
</span>
&lt;customers-list&gt;
    &lt;customer id=<span class="code-quote">"1005"</span> url=<span class="code-quote">"http:<span class="code-comment">//foobar.com/api/customers/1005"</span>&gt;John Doe&lt;/customer&gt;
</span>    &lt;customer id=<span class="code-quote">"1006"</span> url=<span class="code-quote">"http:<span class="code-comment">//foobar.com/api/customers/1006"</span>&gt;Jane Doe&lt;/customer&gt;
</span>    ...
&lt;/customers-list&gt;
</pre>
</div></div>

<p>The problem is how to compute URIs when paths come from @Path annotations. It complicates when we consider paths with templates (variables) on multiple levels or sub-resources introducing dynamic routing to different URIs.</p>

<p>The core part of solution is to use injected <a href="https://jsr311.dev.java.net/nonav/javadoc/javax/ws/rs/core/UriInfo.html" class="external-link" rel="nofollow">UriInfo</a> object. Method "getCustomers" has to have UriInfo object injected. This helper object allows to extract some useful information about current URI context, but what's more important, allow to get <a href="https://jsr311.dev.java.net/nonav/javadoc/javax/ws/rs/core/UriBuilder.html" class="external-link" rel="nofollow">UriBuilder</a> object. UriBuilder has multiple appender methods that extends final URI it can build; in our case to current URI we can append path in multiple ways, providing it as string (which we actually want to avoid here) or providing resource (class or method) to extract @Path value. Finally UriBuilder that is composed of paths with templates (variables) must have variables bound to values to render URI. This case in action looks like this:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
@Path(<span class="code-quote">"/customers"</span>)
<span class="code-keyword">public</span> class CustomerService {

    @GET
    <span class="code-keyword">public</span> Customers getCustomers(@Context UriInfo ui) {
        ......
        <span class="code-comment">// builder starts with current URI and has appended path of getCustomer method
</span>        UriBuilder ub = ui.getAbsolutePathBuilder().path(<span class="code-keyword">this</span>.getClass(), <span class="code-quote">"getCustomer"</span>);
        <span class="code-keyword">for</span> (Customer customer: customers) {
            <span class="code-comment">// builder has {id} variable that must be filled in <span class="code-keyword">for</span> each customer
</span>            URI uri = ub.build(customer.getId());
            c.setUrl(uri);
        }
        <span class="code-keyword">return</span> customers;
    }

    @GET
    @Path(<span class="code-quote">"/{id}"</span>)
    <span class="code-keyword">public</span> Customer getCustomer(@PathParam(<span class="code-quote">"id"</span>) <span class="code-object">String</span> id) {
        ......
    }

}
</pre>
</div></div>


<h1><a name="JAX-RSBasics-Annotationinheritance"></a>Annotation inheritance</h1>

<p>Most of the JAX-RS annotations can be inherited from either an interface or a superclass. For example :</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">

<span class="code-keyword">public</span> <span class="code-keyword">interface</span> CustomerService {

    @PUT
    @Path(<span class="code-quote">"/customers/{id}"</span>)
    Response updateCustomer(@PathParam(<span class="code-quote">"id"</span>) <span class="code-object">Long</span> id, Customer customer);

    @POST
    @Path(<span class="code-quote">"/customers"</span>)
    Customer addCustomer(Customer customer);

}

@Path(<span class="code-quote">"/customerservice/"</span>)
<span class="code-keyword">public</span> class Customers <span class="code-keyword">implements</span> CustomerService {

    
    <span class="code-keyword">public</span> Response updateCustomer(<span class="code-object">Long</span> id, Customer customer) {
        <span class="code-keyword">return</span> Response.status(errorCode).build();
    }

    <span class="code-keyword">public</span> Customer addCustomer(Customer customer) {
        <span class="code-keyword">throw</span> <span class="code-keyword">new</span> WebApplicationException(errorCode);
    }

}
</pre>
</div></div>

<p>Similarly, annotations can be inherited from super-classes. In CXF, the resource class can also inherit the class-level annotations from either one of its implemented interfaces or its superclass.    </p>


<h1><a name="JAX-RSBasics-Subresourcelocators."></a>Sub-resource locators.</h1>

<p>A method of a resource class that is annotated with @Path becomes a sub-resource locator when no annotation with an HttpMethod designator like @GET is present. Sub-resource locators are used to further resolve the object that will handle the request. They can delegate to other sub-resource locators, including themselves. </p>

<p>In the example below, getOrder method is a sub-resource locator:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
@Path(<span class="code-quote">"/customerservice/"</span>)
<span class="code-keyword">public</span> class CustomerService {

    @Path(<span class="code-quote">"/orders/{orderId}/"</span>)
    <span class="code-keyword">public</span> Order getOrder(@PathParam(<span class="code-quote">"orderId"</span>) <span class="code-object">String</span> orderId) {
       ......
    }
}

@XmlRootElement(name = <span class="code-quote">"Order"</span>)
<span class="code-keyword">public</span> class Order {
    <span class="code-keyword">private</span> <span class="code-object">long</span> id;
    <span class="code-keyword">private</span> Items items;

    <span class="code-keyword">public</span> Order() {
    }

    <span class="code-keyword">public</span> <span class="code-object">long</span> getId() {
        <span class="code-keyword">return</span> id;
    }


    @GET
    @Path(<span class="code-quote">"products/{productId}/"</span>)
    <span class="code-keyword">public</span> Product getProduct(@PathParam(<span class="code-quote">"productId"</span>)<span class="code-object">int</span> productId) {
       ......
    }

    @Path(<span class="code-quote">"products/{productId}/items"</span>)
    <span class="code-keyword">public</span> Order getItems(@PathParam(<span class="code-quote">"productId"</span>) <span class="code-object">int</span> productId) {
       <span class="code-keyword">return</span> <span class="code-keyword">this</span>;
    }

    @GET
    <span class="code-keyword">public</span> Items getItems() {
       ......
    }

}
</pre>
</div></div>
<p>A HTTP GET request to <a href="http://localhost:9000/customerservice/orders/223/products/323" class="external-link" rel="nofollow">http://localhost:9000/customerservice/orders/223/products/323</a> is dispatched to getOrder method first. If the Order resource whose id is 223 is found, the Order 223 will be used to further resolve Product resource. Eventually, a Product 323 that belongs to Order 223 is returned.<br/>
The request to <a href="http://localhost:9000/customerservice/orders/223/products/323/items" class="external-link" rel="nofollow">http://localhost:9000/customerservice/orders/223/products/323/items</a> will be delivered to getItems() method which in turn will delegate to an overloaded getItems().</p>

<p>Note that a subresource class like Order is often has no root &#64;Path annotations which means that they're delegated to dynamically at runtime, in other words, they can not be invoked upon before one of the root resource classes is invoked first. A root resource class (which has a root @\Path annotation) can become a subresource too if one of its subresource locator methods delegates to it, similarly to Order.getItems() above.   </p>


<p>Note that a given subresource can be represented as an interface or some base class resolved to an actual class at runtime. In this case any resource methods which have to be invoked on an actual subresource instance are discovered dynamically at runtime :  </p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
@Path(<span class="code-quote">"/customerservice/"</span>)
<span class="code-keyword">public</span> class CustomerService {

    @Path(<span class="code-quote">"/orders/{orderId}/"</span>)
    <span class="code-keyword">public</span> Order getOrder(@PathParam(<span class="code-quote">"orderId"</span>) <span class="code-object">String</span> orderId) {
       ......
    }
}

<span class="code-keyword">public</span> <span class="code-keyword">interface</span> Order {
    @GET
    @Path(<span class="code-quote">"products/{productId}/"</span>)
    Product getProduct(@PathParam(<span class="code-quote">"productId"</span>)<span class="code-object">int</span> productId);
}

@XmlRootElement(name = <span class="code-quote">"Order"</span>)
<span class="code-keyword">public</span> class OrderImpl <span class="code-keyword">implements</span> Order {
    
    <span class="code-keyword">public</span> Product getProduct(<span class="code-object">int</span> productId) {
       ......
    }
}

@XmlRootElement(name = <span class="code-quote">"Order"</span>)
<span class="code-keyword">public</span> class OrderImpl2 <span class="code-keyword">implements</span> Order {
    
    <span class="code-comment">// overrides JAXRS annotations
</span>    @GET
    @Path(<span class="code-quote">"theproducts/{productId}/"</span>)
    Product getProduct(@PathParam(<span class="code-quote">"id"</span>)<span class="code-object">int</span> productId) {...}
}

</pre>
</div></div>

<h2><a name="JAX-RSBasics-Staticresolutionofsubresources"></a>Static resolution of subresources</h2>

<p>By default, subresources are resolved dynamically at runtime. This is a slower procedure, partly due to the fact that a concrete subresource implementation may introduce some JAXRS annotations in addition to those which might be available at the interface typed by a subresource locator method and different to those available on another subresource instance implementing the same interface.</p>

<p>If you know that all the JAXRS annotations are available on a given subresource type (or one of its superclasses or interfaces) returned by a subresource locator method then you may want to disable the dynamic resolution :</p>


<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml">
<span class="code-tag">&lt;beans&gt;</span>
<span class="code-tag">&lt;jaxrs:server staticSubresourceResolution=<span class="code-quote">"true"</span>&gt;</span>
<span class="code-tag"><span class="code-comment">&lt;!-- more configuration --&gt;</span></span>
<span class="code-tag">&lt;/jaxrs:server&gt;</span>
<span class="code-tag">&lt;/beans&gt;</span>
</pre>
</div></div>


<h1><a name="JAX-RSBasics-MessageBodyProviders"></a>Message Body Providers</h1>

<p>JAX-RS relies on MessageBodyReader and MessageBodyWriter implementations to serialize and de-serialize Java types. JAX-RS requires that certain types has to be supported out of the box. <br/>
By default, CXF supports String, byte[], InputStream, Reader, File, JAXP Source, JAX-RS StreamingOutput, JAXB-annotated types with application/xml, text/xml and application/json formats as well as JAXBElement (see below). JAX-RS MultivaluedMap is also supported for form contents. </p>

<p>See also a "Support for data bindings" section below.</p>

<h2><a name="JAX-RSBasics-CustomMessageBodyProviders"></a>Custom Message Body Providers          </h2>

<p>It's likely that a given application may need to deal with types which are not supported by default.<br/>
Alternatively, developers may want to provide a more efficient support for handling default types such as InputStream.</p>

<p>Here's an example of a custom MessageBodyReader for InputStream :</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">

@Consumes(<span class="code-quote">"application/octet-stream"</span>)
@Provider
<span class="code-keyword">public</span> class InputStreamProvider <span class="code-keyword">implements</span> MessageBodyReader&lt;InputStream&gt; {

    
    <span class="code-keyword">public</span> <span class="code-object">boolean</span> isReadable(<span class="code-object">Class</span>&lt;InputStream&gt; type, Type genericType, Annotation[] annotations, MediaType mt) {
        <span class="code-keyword">return</span> InputStream.class.isAssignableFrom(type);
    }

    <span class="code-keyword">public</span> InputStream readFrom(<span class="code-object">Class</span>&lt;InputStream&gt; clazz, Type t, Annotation[] a, MediaType mt, 
                         MultivaluedMap&lt;<span class="code-object">String</span>, <span class="code-object">String</span>&gt; headers, InputStream is) 
        <span class="code-keyword">throws</span> IOException {
        <span class="code-keyword">return</span> <span class="code-keyword">new</span> FilterInputStream(is) {
             @Override
             <span class="code-keyword">public</span> <span class="code-object">int</span> read(<span class="code-object">byte</span>[] b) <span class="code-keyword">throws</span> IOException {
                 <span class="code-comment">// filter out some bytes
</span>             }              
        }     
    }
}

</pre>
</div></div>

<p>and here's an example of a custom MessageBodyWriter for Long :</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">

@ProduceMime(<span class="code-quote">"text/plain"</span>)
@Provider
<span class="code-keyword">public</span> class LongProvider <span class="code-keyword">implements</span> MessageBodyWriter&lt;<span class="code-object">Long</span>&gt; {

    <span class="code-keyword">public</span> <span class="code-object">long</span> getSize(<span class="code-object">Long</span> l, <span class="code-object">Class</span>&lt;?&gt; type, Type genericType, Annotation[] annotations, MediaType mt) {
        <span class="code-keyword">return</span> -1;
    }

    <span class="code-keyword">public</span> <span class="code-object">boolean</span> isWriteable(<span class="code-object">Class</span>&lt;?&gt; type, Type genericType, Annotation[] annotations, MediaType mt) {
        <span class="code-keyword">return</span> <span class="code-object">long</span>.class.isAssignableFrom(type) || <span class="code-object">Long</span>.class.isAssignableFrom(type);
    }

    <span class="code-keyword">public</span> void writeTo(<span class="code-object">Long</span> l, <span class="code-object">Class</span>&lt;?&gt; clazz, Type type, Annotation[] a, 
                        MediaType mt, MultivaluedMap&lt;<span class="code-object">String</span>, <span class="code-object">Object</span>&gt; headers, OutputStream os) 
        <span class="code-keyword">throws</span> IOException {
        os.write(l.toString().getBytes());
        
    }

</pre>
</div></div>

<p>CXF ships some custom providers too. These are providers for dealing with Atom (based on Apache Abdera) and XMLObjects.<br/>
CXF also supports primitive types and their Number friends when text/plain media type is used, either on input or output.   </p>

<h2><a name="JAX-RSBasics-Registeringcustomproviders"></a>Registering custom providers  </h2>


<p>Putting @Provider annotation on the provider class is something that should lead to your provider being registered with the runtime. CXF does not support this feature yet. </p>


<p>One can easily register a provider either from the Spring configuration or programmatically :   </p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml">

<span class="code-tag">&lt;beans&gt;</span>
<span class="code-tag">&lt;jaxrs:server id=<span class="code-quote">"customerService"</span> address=<span class="code-quote">"/"</span>&gt;</span>
    <span class="code-tag">&lt;jaxrs:serviceBeans&gt;</span>
      <span class="code-tag">&lt;bean class=<span class="code-quote">"org.CustomerService"</span> /&gt;</span>
    <span class="code-tag">&lt;/jaxrs:serviceBeans&gt;</span>

    <span class="code-tag">&lt;jaxrs:providers&gt;</span>
      <span class="code-tag">&lt;ref bean=<span class="code-quote">"isProvider"</span> /&gt;</span>
      <span class="code-tag">&lt;ref bean=<span class="code-quote">"longProvider"</span> /&gt;</span>
    <span class="code-tag">&lt;/jaxrs:providers&gt;</span>
    <span class="code-tag">&lt;bean id=<span class="code-quote">"isProvider"</span> class=<span class="code-quote">"com.bar.providers.InputStreamProvider"</span>/&gt;</span>
    <span class="code-tag">&lt;bean id=<span class="code-quote">"longProvider"</span> class=<span class="code-quote">"com.bar.providers.LongProvider"</span>/&gt;</span>
<span class="code-tag">&lt;/jaxrs:server&gt;</span>
<span class="code-tag">&lt;/beans&gt;</span>
</pre>
</div></div>

<p>Note that instead of the older &lt;jaxrs:entityProviders&gt; it's now &lt;jaxrs:providers&gt;. JAX-RS supports different types of providers and having a single &lt;jaxrs:providers&gt; container is in line with the way other JAX-RS implementations discover providers by checking for @Provider annotations only. </p>

<p>See below a more complete beans.xml definition.</p>

<p>While having @Provider-annotated providers automatically registered is a handy feature indeed, sometimes it might actually be problematic. For ex, in a large project user providers from different libraries might clash. </p>

<p>When using the custom configuration (as shown above) provider instances of different types (handling the same format of request/response bodies) or differently configured instances of the same type can be registered with a different jaxrs:server instance. Yet another requirement might be to have only a given jaxrs:server endpoint among multiple available ones to handle requests with a given media type :</p>

<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-xml">

<span class="code-tag">&lt;beans&gt;</span>
<span class="code-tag">&lt;jaxrs:server id=<span class="code-quote">"customerService1"</span> address=<span class="code-quote">"/1"</span>&gt;</span>
   <span class="code-tag">&lt;bean id=<span class="code-quote">"serviceBean"</span> class=<span class="code-quote">"org.CustomerService"</span> /&gt;</span> 

   <span class="code-tag">&lt;jaxrs:serviceBeans&gt;</span>
      <span class="code-tag">&lt;ref bean=<span class="code-quote">"serviceBean"</span>/&gt;</span>
   <span class="code-tag">&lt;/jaxrs:serviceBeans&gt;</span>

   <span class="code-tag">&lt;jaxrs:providers&gt;</span>
      <span class="code-tag">&lt;bean class=<span class="code-quote">"com.bar.providers.InputStreamProvider"</span>/&gt;</span>
   <span class="code-tag">&lt;/jaxrs:providers&gt;</span>
<span class="code-tag">&lt;/jaxrs:server&gt;</span>
<span class="code-tag">&lt;jaxrs:server id=<span class="code-quote">"customerService2"</span> address=<span class="code-quote">"/2"</span>&gt;</span>
    <span class="code-tag">&lt;jaxrs:serviceBeans&gt;</span>
      <span class="code-tag">&lt;ref bean=<span class="code-quote">"serviceBean"</span>/&gt;</span>
    <span class="code-tag">&lt;/jaxrs:serviceBeans&gt;</span>

    <span class="code-tag">&lt;jaxrs:providers&gt;</span>
      <span class="code-tag">&lt;bean id=<span class="code-quote">"isProvider"</span> class=<span class="code-quote">"baz.foo.jaxrsproviders.InputStreamProvider"</span>/&gt;</span>
    <span class="code-tag">&lt;/jaxrs:providers&gt;</span>
<span class="code-tag">&lt;/jaxrs:server&gt;</span>

<span class="code-tag">&lt;jaxrs:server id=<span class="code-quote">"customerService3"</span> address=<span class="code-quote">"/3"</span>&gt;</span>
    <span class="code-tag">&lt;jaxrs:serviceBeans&gt;</span>
      <span class="code-tag">&lt;ref bean=<span class="code-quote">"serviceBean"</span>/&gt;</span>
    <span class="code-tag">&lt;/jaxrs:serviceBeans&gt;</span>

    <span class="code-tag">&lt;jaxrs:providers&gt;</span>
      <span class="code-tag">&lt;ref bean=<span class="code-quote">"isProvider"</span>/&gt;</span>
    <span class="code-tag">&lt;/jaxrs:providers&gt;</span>
<span class="code-tag">&lt;/jaxrs:server&gt;</span>


<span class="code-tag">&lt;bean id=<span class="code-quote">"isProvider"</span> class=<span class="code-quote">"com.bar.providers.InputStreamProvider"</span>&gt;</span>
   <span class="code-tag">&lt;property name=<span class="code-quote">"limit"</span> value=<span class="code-quote">"5"</span>/&gt;</span>
<span class="code-tag">&lt;/bean&gt;</span>

<span class="code-tag">&lt;/beans&gt;</span>
</pre>
</div></div>

<p>In this example a single service bean can be accessed through 3 different paths, /1, /2 and /3. InputStream provider is available on all the 3 paths. com.bar.providers.InputStreamProvider is used in 2 cases, while a special InputStream handler baz.foo.jaxrsproviders.InputStreamProvider from another library is also involved in one case.</p>


<h1><a name="JAX-RSBasics-Customizingmediatypesformessagebodyproviders"></a>Customizing media types for message body providers</h1>

<p>As explained above, message body providers can play a major part in affecting the way target resource methods are matched. If a method returns a custom type Foo and a MessageBodyWriter&lt;Foo&gt; is available then it will be used only if one of the media types specified in a given request's HTTP Accept header matches or intersects with one of the media types specified by &#64;Produces annotation in a MessageBodyWriter&lt;Foo&gt; implementation. The same applies if a method accepts a custom type Foo, but this time the value of &#64;Consumes in MessageBodyReader&lt;Foo&gt; will be matched against a request's ContentType value.    </p>

<p>Sometimes users would like to experiment with media types different to those statically supported by a given message body reader/writer. For example, application/xml might seem a bit too general in some cases and people may want to try some custom/xml type and still use a default JAXB provider. </p>

<p>In such cases it's possible to override the default @Produces and/or @Consumes types supported by a given provider. It only currently works for JAXBElementProvider and JSONProvider, but any custom provider can avail of this support by simply having setter/getter pairs for either produce and/or consume types and the JAXRS runtime will use them instead.<br/>
See <a href="http://svn.apache.org/repos/asf/cxf/trunk/systests/jaxrs/src/test/resources/jaxrs/WEB-INF/beans.xml" class="external-link" rel="nofollow">this example</a> on how to provide custom media types from Spring.</p>

<h1><a name="JAX-RSBasics-WorkingwithHTTPheaders"></a>Working with HTTP headers</h1>

<h1><a name="JAX-RSBasics-AdvancedHTTP"></a>Advanced HTTP</h1>

<p>The JAX-RS specification requires support for a number of advanced HTTP features.</p>

<p>JAX-RS Request context object can be used to check the preconditions expressed via headers such as If-Match, If-None-Match, If-Modified-Since and If-Unmodified-Since. </p>

<p>JAX-RS also makes it easier to work with ETag, Vary, CacheControl, Cookie and Set-Cookie headers.</p>

    </div>
        <div id="commentsSection" class="wiki-content pageSection">
        <div style="float: right;">
            <a href="https://cwiki.apache.org/confluence/users/viewnotifications.action" class="grey">Change Notification Preferences</a>
        </div>
        <a href="https://cwiki.apache.org/confluence/display/CXF20DOC/JAX-RS+Basics">View Online</a>
        |
        <a href="https://cwiki.apache.org/confluence/pages/diffpagesbyversion.action?pageId=24190796&revisedVersion=2&originalVersion=1">View Changes</a>
                |
        <a href="https://cwiki.apache.org/confluence/display/CXF20DOC/JAX-RS+Basics?showComments=true&amp;showCommentArea=true#addcomment">Add Comment</a>
            </div>
</div>
</div>
</div>
</div>
</body>
</html>

Mime
View raw message