Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Migrated to Confluence 4.0

unmigrated-inline-wiki-markup
{span:style=font-size:2em;font-weight:bold} JAX-RS : Understanding the Basics {span}

...

Table of Contents

What is New in JAX-RS

...

2.0

Filters

Server

ContainerRequestFilter and ContainerResponseFilter are new server-side request and response filters which can be used to customize various properties of a given request and response.

ContainerRequestFilter annotated with a PreMatching annotation will be run before the runtime has matched a request to a specific JAX-RS root resource and method. Prematching filters can be used to affect the matching process.

The request filters without the PreMatching annotation will run after the JAX-RS resource method has been selected.

ContainerRequestFilter can be used to block a request.

The filters can be bound to individual resource methods only with the help of custom NameBindings.

Multiple request and response filters can be executed in the specific order by using javax.annotation.Priority annotations. See Priorities for more information. Request filters are sorted in the ascending order, response filters - in the descending order.

Client

ClientRequestFilter and ClientResponseFilter are new client-side request and response filters which can be used to customize various properties of a given request and response.

ClientRequestFilter can be used to block a request.

Request filters are sorted in the ascending order, response filters - in the descending order. See Priorities for more information.

Interceptors

ReaderInterceptor and WriterInterceptor can be used in addition to filters or on its own to customize requests and responses on server and client sides.

Interceptors can be useful to customize the reading/writing process and block JAX-RS MessageBodyWriter or MessageBodyReader providers.

The interceptors used on the server side can be bound to individual resource methods only with the help of custom NameBindings.

All interceptors are sorted in the ascending order. See Priorities for more information.

Dynamic Features

Dynamic Feature is a server side feature that can be used to attach request and response filters as well as reader and writer interceptors to specific resource methods. It is an alternative approach to using the NameBindings and offer a finer-grained control over the binding process.

Exceptions

Dedicated exception classes representing various HTTP error or redirect conditions have been introduced, see the 'javax.ws.rs' Package Exceptions section.

For example, instead of throwing a "new WebApplicationException(404)" one is better to do "new NotFoundException()". The finer-grained exception hierarchy allows for a finer-grained support of exception mappers. It also opens a way to check WebApplicationException and all of its subclasses when catching the HTTP exceptions on the client side.

Note that on the client side, ProcessingException can be used to catch client-related exceptions while ResponseProcessingException can be used to narrow down the client side exceptions specifically related to processing the response message.

Suspended invocations

One of the best JAX-RS 2.0 features is the support for server-side asynchronous invocations. Please see the AsyncResponse documentation which provides a very good overview of this feature.

See also this test resource.

Typically, the resource method accepting AsyncResponse will either store it and start a new thread to finish the request, the method will return and the invocation will be suspended, then eventually another thread (either the one which initiated an internal job or some other thread) will resume the suspended call. Note in this case the invocation will be suspended indefinitely until it is resumed.

Another approach is to have AsyncResponse suspended for a limited period of time only and also register a TimeoutHandler. The latter will be invoked when the invocation is resumed by the container after the timeout has expired and the handler will either complete the invocation or suspend it again till it is ready to finish it.

CompletionCallback can be registered with AsyncResponse to receive the notifications when the async response has been sent back.

ConnectionCallback is not currently supported.

This feature can help developers write very sophisticated asynchronous applications.

Please also see the page about CXF Continuations API which JAX-RS 2.0 AsyncResponse implementation is based upon and
how to configure CXFServlet.

Parameter converters

ParamConverterProvider can be used to manage the conversion of custom Objects to String and vice versa on the server and client sides, when processing JAX-RS parameters representing URI parts or headers or form elements and when a default conversion mechanism does not work. For example, java.util.Date constructor accepting a String may have to be replaced a custom ParamConverter.

Bean parameters

BeanParam can be used to get JAX-RS parameters representing URI parts or headers or form elements and also contexts injected into a single bean container.

Note the CXF extension supporting the injection of all the parameters of specific JAX-RS type (example, QueryParam("") MyBean) is different, it only allows to get all the query parameters injected, but it also does not require that bean properties are annotated with QueryParam/etc annotations.

ResourceInfo

ResourceInfo is a new JAX-RS context which can be injected into filters and interceptors and checked which resource class and method are about to be invoked.

Injection into subresources

Subresources can get JAX-RS contexts injected directly into their fields with the help of ResourceContext.

When possible, having a parent resource injecting the contexts into a given subresource instance via a setter or constructor can offer a much simpler alternative.

Updates to the matching algorithm

JAX-RS 2.0 supports a proper resource method selection in cases where multiple root resource classes have the same Path value, for example:

Code Block
java
java


h2. Filters

h3. Server

[ContainerRequestFilter|https://jax-rs-spec.java.net/nonav/2.0/apidocs/javax/ws/rs/container/ContainerRequestFilter.html] and [ContainerResponseFilter|https://jax-rs-spec.java.net/nonav/2.0/apidocs/javax/ws/rs/container/ContainerResponseFilter.html] are new server-side request and response filters which can be used to customize various properties of a given request and response.

ContainerRequestFilter annotated with a [PreMatching|https://jax-rs-spec.java.net/nonav/2.0/apidocs/javax/ws/rs/container/PreMatching.html] annotation will be run before the runtime has matched a request to a specific JAX-RS root resource and method. Prematching filters can be used to affect the matching process.  

The request filters without the PreMatching annotation will run after the JAX-RS resource method has been selected. 

ContainerRequestFilter can be used to [block|https://jax-rs-spec.java.net/nonav/2.0/apidocs/javax/ws/rs/container/ContainerRequestContext.html#abortWith(javax.ws.rs.core.Response)] a request.

The filters can be bound to individual resource methods only with the help of custom [NameBinding|https://jax-rs-spec.java.net/nonav/2.0/apidocs/javax/ws/rs/NameBinding.html]s.

Multiple request and response filters can be executed in the specific order by using javax.annotation.Priority annotations. See [Priorities|https://jax-rs-spec.java.net/nonav/2.0/apidocs/javax/ws/rs/Priorities.html] for more information. Request filters are sorted in the ascending order, response filters - in the descending order.  

h3. Client

[ClientRequestFilter|https://jax-rs-spec.java.net/nonav/2.0/apidocs/javax/ws/rs/client/ClientRequestFilter.html] and [ClientResponseFilter|https://jax-rs-spec.java.net/nonav/2.0/apidocs/javax/ws/rs/client/ClientResponseFilter.html] are new client-side request and response filters which can be used to customize various properties of a given request and response.

ClientRequestFilter can be used to [block|https://jax-rs-spec.java.net/nonav/2.0/apidocs/javax/ws/rs/client/ClientRequestContext.html#abortWith(javax.ws.rs.core.Response)] a request.

Request filters are sorted in the ascending order, response filters - in the descending order. See [Priorities|https://jax-rs-spec.java.net/nonav/2.0/apidocs/javax/ws/rs/Priorities.html] for more information.

h2. Interceptors

[ReaderInterceptor|https://jax-rs-spec.java.net/nonav/2.0/apidocs/javax/ws/rs/ext/ReaderInterceptor.html] and [WriterInterceptor|https://jax-rs-spec.java.net/nonav/2.0/apidocs/javax/ws/rs/ext/WriterInterceptor.html] can be used in addition to filters or on its own to customize requests and responses on server and client sides. 

Interceptors can be useful to customize the reading/writing process and block JAX-RS MessageBodyWriter or MessageBodyReader providers. 

The interceptors used on the server side can be bound to individual resource methods only with the help of custom [NameBinding|https://jax-rs-spec.java.net/nonav/2.0/apidocs/javax/ws/rs/NameBinding.html]s.

All interceptors are sorted in the ascending order. See [Priorities|https://jax-rs-spec.java.net/nonav/2.0/apidocs/javax/ws/rs/Priorities.html] for more information.

h2. Dynamic Features

[Dynamic Feature|https://jax-rs-spec.java.net/nonav/2.0/apidocs/javax/ws/rs/container/DynamicFeature.html] is a server side feature that can be used to attach request and response filters as well as reader and writer interceptors to specific resource methods. It is an alternative approach to using the NameBindings and offer a finer-grained control over the binding process.   

h2. Exceptions

Dedicated exception classes representing various HTTP error or redirect conditions have been introduced, see the 'javax.ws.rs' Package [Exceptions section|https://jax-rs-spec.java.net/nonav/2.0/apidocs/javax/ws/rs/package-frame.html].

For example, instead of throwing a "new WebApplicationException(404)" one is better to do "new NotFoundException()". The finer-grained exception hierarchy allows for a finer-grained support of exception mappers. It also opens a way to check WebApplicationException and all of its subclasses when catching the HTTP exceptions on the client side.

Note that on the client side, ProcessingException can be used to catch client-related exceptions while ResponseProcessingException can be used to narrow down the client side exceptions specifically related to processing the response message.    

h2. Suspended invocations

One of the best JAX-RS 2.0 features is the support for server-side asynchronous invocations. Please see the [AsyncResponse|https://jax-rs-spec.java.net/nonav/2.0/apidocs/javax/ws/rs/container/AsyncResponse.html] documentation which provides a very good overview of this feature.

See also this [test resource|http://svn.apache.org/repos/asf/cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookContinuationStore.java].

Typically, the resource method accepting AsyncResponse will either store it and start a new thread to finish the request, the method will return and the invocation will be suspended, then eventually another thread (either the one which initiated an internal job or some other thread) will resume the suspended call. Note in this case the invocation will be suspended indefinitely until it is resumed.

Another approach is to have AsyncResponse suspended for a limited period of time only and also register a [TimeoutHandler|https://jax-rs-spec.java.net/nonav/2.0/apidocs/javax/ws/rs/container/TimeoutHandler.html]. The latter will be invoked when the invocation is resumed by the container after the timeout has expired and the handler will either complete the invocation or suspend it again till it is ready to finish it.

[CompletionCallback|https://jax-rs-spec.java.net/nonav/2.0/apidocs/javax/ws/rs/container/CompletionCallback.html] can be registered with AsyncResponse to receive the notifications when the async response has been sent back.

[ConnectionCallback|https://jax-rs-spec.java.net/nonav/2.0/apidocs/javax/ws/rs/container/ConnectionCallback.html] is not currently supported.

This feature can help developers write very sophisticated asynchronous applications.   

Please also see the page about CXF [Continuations] API which JAX-RS 2.0 AsyncResponse implementation is based upon and 
[how to configure|http://cxf.apache.org/docs/servlet-transport.html] CXFServlet.

h2. Parameter converters

[ParamConverterProvider|https://jax-rs-spec.java.net/nonav/2.0/apidocs/javax/ws/rs/ext/ParamConverterProvider.html] can be used to manage the conversion of custom Objects to String and vice versa on the server and client sides, when processing JAX-RS parameters representing URI parts or headers or form elements and when a default conversion mechanism does not work. For example, java.util.Date constructor accepting a String may have to be replaced a custom ParamConverter.  

h2. Bean parameters

[BeanParam|https://jax-rs-spec.java.net/nonav/2.0/apidocs/javax/ws/rs/BeanParam.html] can be used to get JAX-RS parameters representing URI parts or headers or form elements and also contexts injected into a single bean container. 

Note the CXF extension supporting the injection of all the parameters of specific JAX-RS type (example, QueryParam("") MyBean) is different, it only allows to get all the query parameters injected, but it also does not require that bean properties are annotated with QueryParam/etc annotations.

h2. ResourceInfo

[ResourceInfo|https://jax-rs-spec.java.net/nonav/2.0/apidocs/javax/ws/rs/container/ResourceInfo.html] is a new JAX-RS context which can be injected into filters and interceptors and checked which resource class and method are about to be invoked.

h2. Injection into subresources

Subresources can get JAX-RS contexts injected directly into their fields with the help of [ResourceContext|https://jax-rs-spec.java.net/nonav/2.0/apidocs/javax/ws/rs/container/ResourceContext.html]. 

When possible, having a parent resource injecting the contexts into a given subresource instance via a setter or constructor can offer a much simpler alternative.

h2. Updates to the matching algorithm

JAX-RS 2.0 supports a proper resource method selection in cases where multiple root resource classes have the same Path value, for example:

{code:java}
@Path("/")
public class Root1 {
   @Path("/1")
   @GET 
   public Response get() {...}
}

@Path("/")
public class Root2 {
   @Path("/2")
   @GET 
   public Response get() {...}
}
{code}

In

...

JAX-RS

...

1.1

...

a

...

request

...

with

...

URI

...

such

...

as

...

"/1"

...

is

...

not

...

guaranteed

...

to

...

be

...

matched

...

and

...

in

...

CXF

...

2.7.x

...

or

...

earlier

...

the

...

use

...

of

...

CXF

...

specific

...

ResourceComparator

...

is

...

required

...

to

...

ensure

...

Root1

...

and

...

its

...

get()

...

method

...

gets

...

selected.

...

In

...

CXF

...

3.0.0

...

Root1

...

get()

...

will

...

always

...

be

...

correctly

...

selected.

...

Note

...

ResourceComparator

...

may

...

still

...

be

...

of

...

help

...

in

...

some

...

cases

...

even

...

in

...

CXF

...

3.0.0.

...

Link is a utility class for building HTTP links as HTTP Link headers or application data links.
UriInfo, UriBuilder, Response and ResponseBuilder classes have been enhanced to support Link.

Client API

JAX-RS 2.0 Client API has been completely implemented in CXF 3.0.0,

...

please

...

see

...

the

...

Client

...

API

...

page

...

for

...

more

...

information.

...

Resource

...

class

...

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:

Code Block
java
java

{code:java}
package demo.jaxrs.server;

import java.util.HashMap;
import java.util.Map;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Response;

@Path("/customerservice/")
@Produces("application/xml")
public class CustomerService {

    public CustomerService() {
    }

    @GET
    public Customers getCustomers() {
        ......
    }

    @GET
    @Path("/customers/{id}")
    @Produces("application/json")
    public Customer getCustomer(@PathParam("id") String id) {
        ......
    }

    @PUT
    @Path("/customers/{id}")
    @Consumes("application/xml")
    public Response updateCustomer(@PathParam("id") Long id, Customer customer) {
        ......
    }

    @POST
    @Path("/customers")
    public Response addCustomer(Customer customer) {
        ......
    }

    @DELETE
    @Path("/customers/{id}/")
    public Response deleteCustomer(@PathParam("id") String id) {
        ......
    }

    @Path("/orders/{orderId}/")
    public Order getOrder(@PathParam("orderId") String orderId) {
       ......
    }
}
{code}

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.

...

The

...

@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

...

*/

...

*,

...

but

...

it's

...

recommended

...

that

...

some

...

definite

...

value

...

is

...

specified.

...

The

...

same

...

applies

...

to

...

@Consumes,

...

except

...

that

...

it's

...

the

...

message

...

body

...

readers

...

that

...

are

...

checked

...

as

...

the

...

last

...

resort.

...

For

...

example,

...

getCustomers()

...

method

...

inherits

...

@Produces

...

annotation

...

from

...

its

...

class,

...

while

...

getCustomer()

...

method

...

overrides

...

it

...

with

...

its

...

own

...

value.

@Path

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:

Code Block
java
java
  

h1. @Path

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:

{code:java}
@Path("/customers/{id}")
public class CustomerResource {

    @GET
    public Customer getCustomer(@PathParam("id") Long id) {
        ......
    }

    @GET
    @Path("/order/{orderid}")
    public Order getOrder(@PathParam("id") Long customerId, @PathParam("orderid") Long orderId) {
        ......
    }

    @GET
    @Path("/order/{orderid}/{search:.*}")
    public Item findItem(@PathParam("id") Long customerId, 
                         @PathParam("orderid") Long orderId,
                         @PathParam("search") String searchString,
                         @PathParam("search") List<PathSegment> searchList) {
        ......
    }
}

{code} 

This example is similar to the one above it, but it also shows that an \{id\} template variable specified as part of the root \@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).

In this example, a request like 'GET 

This example is similar to the one above it, but it also shows that an {id} template variable specified as part of the root @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).

In this example, a request like 'GET /customers/1/order/2/price/2000/weight/2'

...

will

...

be

...

served

...

by

...

the

...

findItem()

...

method.

...


List<PathSegment>

...

can

...

be

...

used

...

to

...

get

...

to

...

all

...

the

...

path

...

segments

...

in

...

'price/2000/weight/2'

...

captured

...

by

...

the

...

regular

...

expression.

...

More

...

information

...

about

...

Path

...

annotations

...

can

...

be

...

found

...

from

...

JAX-RS

...

spec

...

section

...

2.3.

...

HTTP Method

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

...

:

Code Block
java
java


{code:java}
package org.apache.cxf.customverb;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@HttpMethod("PATCH")
public @interface PATCH { 
}
{code}

h1. Return types

Either 

Return types

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.

...

Exception

...

handling

...

One

...

can

...

either

...

throw

...

an

...

unchecked

...

WebApplicationException

...

or

...

return

...

Response

...

with

...

a

...

proper

...

error

...

code

...

set.

...


The

...

former

...

option

...

may

...

be

...

a

...

better

...

one

...

when

...

no

...

JAX-RS

...

types

...

can

...

be

...

added

...

to

...

method

...

signatures.

...

For

...

example

...

:

Code Block
java
java


{code:java}
@Path("/customerservice/")
public class CustomerService {

    
    @PUT
    @Path("/customers/{id}")
    public Response updateCustomer(@PathParam("id") Long id, Customer customer) {
        return Response.status(errorCode).build();
    }

    @POST
    @Path("/customers")
    public Customer addCustomer(Customer customer) {
        throw new WebApplicationException(errorCode);
    }

}
{code}

Yet

...

another

...

option

...

is

...

to

...

register

...

an

...

ExceptionMapper

...

provider.

...

Ex

...

:

Code Block
java
java


{code:java}
public BookExceptionMapper implements ExceptionMapper<BookException> {
    public Response toResponse(BookException ex) {
        // convert to Response
    }
}
{code}

This

...

allows

...

for

...

throwing

...

a

...

checked

...

or

...

runtime

...

exception

...

from

...

an

...

application

...

code

...

and

...

map

...

it

...

to

...

an

...

HTTP

...

response

...

in

...

a

...

registered

...

provider.

...

Have

...

a

...

look

...

please

...

at

...

this

...

exception

...

mapper

...

which

...

converts

...

Spring

...

Security

...

exceptions

...

into

...

HTTP

...

403

...

error

...

code

...

for

...

another

...

example.

...

Note

...

that

...

when

...

no

...

mappers

...

are

...

found

...

for

...

custom

...

exceptions,

...

they

...

are

...

propagated

...

to

...

the

...

underlying

...

container

...

as

...

required

...

by

...

the

...

specification

...

where

...

they

...

will

...

typically

...

be

...

wrapped

...

in

...

ServlerException,

...

eventually

...

resulting

...

in

...

HTTP

...

500

...

status

...

being

...

returned

...

by

...

default.

...

Thus

...

one

...

option

...

for

...

intercepting

...

the

...

exceptions

...

is

...

to

...

register

...

a

...

custom

...

servlet

...

filter

...

which

...

will

...

catch

...

ServletExceptions

...

and

...

handle

...

the

...

causes.

...

This

...

propagation

...

can

...

be

...

disabled

...

by

...

registering

...

a

...

boolean

...

jaxrs

...

property

...

'org.apache.cxf.propagate.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 XMLFaultOutInterceptor.

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 test interceptor.

Mapping exceptions thrown from CXF interceptors

Starting from CXF 2.7.8 it is also possible to use registered ExceptionMappers to map the exceptions thrown from CXF server in interceptors which are registered after JAXRSInInterceptor (Phase.UNMARSHAL) and out interceptors registered before JAXRSOutInterceptor (Phase.MARSHAL).
In earlier CXF versions such exceptions are only possible to handle with CXF fault in interceptors.

In order to get the exceptions thrown from CXF in interceptors mapped, set a "map.cxf.interceptor.fault"

...

contextual

...

property

...

to

...

true

...

-

...

needed

...

in

...

CXF

...

2.7.8

...

to

...

ensure

...

existing

...

in

...

fault

...

interceptors

...

are

...

not

...

affected;

...

the

...

mapping

...

is

...

done

...

by

...

default

...

starting

...

from

...

CXF

...

3.0.0.

...

In

...

order

...

to

...

get

...

the

...

exceptions

...

thrown

...

from

...

CXF

...

out

...

interceptors

...

mapped,

...

add

...

org.apache.cxf.jaxrs.interceptor.JAXRSOutExceptionMapperInterceptor

...

to

...

the

...

list

...

of

...

out

...

interceptors.

...

Customizing

...

default

...

WebApplicationException

...

mapper

...

CXF

...

ships

...

a

...

WebApplicationException

...

mapper,

...

org.apache.cxf.jaxrs.impl.WebApplicationExceptionMapper.

...

By

...

default

...

it

...

logs

...

a

...

stack

...

trace

...

at

...

a

...

warning

...

level

...

and

...

returns

...

Response

...

available

...

in

...

the

...

captured

...

exception.

...


It

...

can

...

be

...

configured

...

to

...

log

...

a

...

stack

...

trace

...

at

...

a

...

trace

...

level,

...

by

...

setting

...

a

...

'printStackTrace'

...

property

...

to

...

'false'.

...

Alternatively,

...

if

...

org.apache.cxf.logging.FaultListener

...

is

...

registered

...

(as

...

a

...

contextual

...

property)

...

and

...

indicates

...

that

...

it

...

handled

...

a

...

given

...

exception,

...

then

...

no

...

more

...

logging

...

is

...

done.

...

A

...

simple

...

text

...

error

...

message

...

can

...

also

...

be

...

optionally

...

reported,

...

by

...

setting

...

an

...

'addMessageToResponse'

...

property

...

to

...

'true'.

...


Note

...

that

...

the

...

custom

...

WebApplicationException

...

mapper,

...

if

...

registered,

...

will

...

be

...

preferred

...

to

...

the

...

default

...

one.

...

Dealing

...

with

...

Parameters

...

PathParam

...

annotation

...

is

...

used

...

to

...

map

...

a

...

given

...

Path

...

template

...

variable

...

to

...

a

...

method

...

parameter.

...


For

...

example

...

:

Code Block
java
java


{code:java}

@Path("/customer/{id}")
public class CustomerService {

    
    @PUT
    @Path("{name}")
    public Response updateCustomer(@PathParam("id") Long id, @PathParam("name") String name) {
        ...
    }
}
{code}

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.

...

@QueryParam,

...

@HttpHeader,

...

@MatrixParam,

...

@FormParam

...

and

...

@CookieParam

...

annotations

...

are

...

also

...

supported.

...


Parameters

...

can

...

be

...

of

...

type

...

String

...

or

...

of

...

any

...

type

...

that

...

have

...

constructors

...

accepting

...

a

...

String

...

parameter

...

or

...

static

...

valueOf(String

...

s)

...

methods.

...


Additionally

...

CXF

...

JAXRS

...

checks

...

for

...

static

...

fromString(String

...

s)

...

method,

...

so

...

types

...

with

...

no

...

valueOf(String)

...

factory

...

methods

...

can

...

also

...

be

...

dealt

...

with:

Code Block
java
java


{code:java}

public enum Gender {
   MALE,
   FEMALE;

   public static Gender fromString(String s) {
       if ("1".equals(s)) {
           return FEMALE;
       } else if ("1".equals(s)) {
           return MALE;
       }  
       return valueOf(s); 
   }
}

@Path("/{g}")
public class Service {

    
    @PUT
    @Path("{id}")
    public Response update(@PathParam("g") Gender g, @PathParam("id") UUID u) {
        ...
    }
}
{code}
  
Note that on the trunk enums with 

Note that on the trunk enums with fromValue()

...

factory

...

methods

...

are

...

also

...

supported.

...

JAX-RS

...

PathSegment

...

is

...

also

...

supported.

...

A

...

sequence

...

of

...

identically

...

named

...

parameters

...

(queries,

...

headers,

...

etc)

...

can

...

be

...

mapped

...

to

...

List

...

or

...

Set

...

or SortedSet.

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

Code Block
java
java
 SortedSet.  

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

{code:java}
public class MapHandler implements ParameterHandler<Map> {
    public Map fromString(String s) {...}
}

@Path("/map")
public class Service {

    
    @PUT
    @Path("/{mapvalue:(.)+}")
    public Response update(@PathParam("mapvalue") Map m, byte[] bytes) {
        ...
    }
}
{code}

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.

...

ParameterHandlers

...

can

...

be

...

registered

...

as

...

providers

...

either

...

from

...

Spring

...

or

...

programmatically.

...


Note

...

that

...

by

...

default

...

the

...

handlers

...

are

...

checked

...

last

...

after

...

all

...

the

...

other

...

options

...

recommended

...

by

...

the

...

JAX-RS

...

specification

...

have

...

been

...

tried.

...


Starting

...

from

...

CXF

...

2.5.3

...

the

...

handlers

...

will

...

always

...

be

...

checked

...

first

...

for

...

java.util.Date

...

and

...

java.util.Locale

...

parameters.

...

Additionally,

...

a

...

"check.parameter.handlers.first"

...

contextual

...

property

...

can

...

be

...

used

...

to

...

get

...

the

...

handlers

...

checked

...

first

...

when

...

the

...

parameters

...

of

...

other

...

types

...

are

...

processed.

...

All

...

the

...

parameters

...

are

...

automatically

...

decoded.

...

This

...

can

...

be

...

disabled

...

by

...

using

...

@Encoded

...

annotation.

...


Parameters

...

can

...

have

...

a

...

default

...

value

...

set

...

using

...

a

...

DefaultValue

...

annotation

...

:

Code Block
java
java


{code:java}

    public Response updateCustomer(@DefaultValue("123") @QueryParam("id") Long id, @PathParam("name") String name) { ... }

{code}

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

...

:

Code Block
java
java


{code:java}
public Response do(@PathParam("id") String id, String body) {
}
{code}

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.

...

It's

...

also

...

possible

...

to

...

inject

...

all

...

types

...

of

...

parameters

...

into

...

fields

...

or

...

through

...

dedicated

...

setters.

...

For

...

example,

...

the

...

first

...

code

...

fragment

...

in

...

this

...

section

...

can

...

be

...

rewritten

...

like

...

this:

Code Block
java
java


{code:java}
@Path("/customer/{id}")
public class CustomerService {

    @PathParam("id")
    private Long id; 
    
    private String name;

    @PathParam("name")
    public setName(String name) {
        this.name = name;
    } 

    @PUT
    @Path("{name}")
    public Response updateCustomer() {
        // use id and name
    }
}
{code}

h2. Parameter beans

Parameter beans

There's

...

a

...

CXF

...

extension

...

which

...

makes

...

it

...

possible

...

to

...

inject

...

a

...

sequence

...

of

...

@PathParam,

...

@QueryParam,

...

@FormParam

...

or

...

@MatrixParam

...

parameters

...

into

...

a

...

bean.

...

For

...

example:

Code Block
java
java

 
{code:java}

@Path("/customer/{id}")
public class CustomerService {

    
    @PUT
    @Path("{name}")
    public Response updateCustomer(@PathParam("") Customer customer) {
        ...
    }

    @GET
    @Path("/order")
    public Response getCustomerOrder(@PathParam("id") int customerId, 
                                     @QueryParam("") OrderBean bean,
                                     @MatrixParam("") OrderBean bean) {
        ...
    }

    @POST
    public Response addCustomerOrder(@PathParam("id") int customerId,
                                     @FormParam("") OrderBean bean) {
        ...
    }
}

public class Customer {
   public void setId(Long id) {...}
   public void setName(String s) {...}  
}

public class OrderBean {
   public void setId(Long id) {...}
   public void setWeight(int w) {...}  
}



{code}

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.

...

Similarly,

...

in

...

getCustomerOrder(),

...

OrderBean

...

can

...

be

...

injected

...

with

...

corresponding

...

values

...

from

...

a

...

query

...

string

...

like

...

?id=1&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.

...

Nested

...

beans

...

are

...

also

...

supported,

...

which

...

among

...

other

...

things,

...

makes

...

it

...

possible

...

to

...

formulate

...

advanced

...

search

...

queries.

...

For

...

example,

...

given

...

the

...

following

...

bean

...

definitions:

Code Block
java
java


{code:java}
class Name {
    String first;
    String last;
}

class Address {
    String city;
    String state;
}

class Person {
    Name legalName;
    Address homeAddr;
    String race;
    String sex;
    Date birthDate;
}

class MyService
{
    @GET
    @Path("/getPerson")
    Person getPerson(@QueryParam("") Person person);
} 
{code}

a

...

query

...

like

...

>

...

/getPerson?sex=M&legalName.first=John&legalName.last=Doe&homeAddr.city=Reno&homeAddr.state=NV

...

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.

...

Resource

...

lifecycles

...

The

...

scopes

...

which

...

are

...

supported

...

by

...

default

...

are

...

Singleton

...

and

...

Prototype(per-request).

...


Note

...

that

...

JAXRS

...

MessageBodyWriter

...

and

...

MessageBodyReader

...

providers

...

are

...

always

...

singletons.

...

Classes

...

with

...

prototype

...

scopes

...

can

...

get

...

JAXRS

...

contexts

...

or

...

parameters

...

injected

...

at

...

construction

...

time:

Code Block
java
java


{code:java}
@Path("/")
public class PerRequestResourceClass {

   public PerRequestResourceClass(@Context HttpHeaders headers, @QueryParam("id") Long id) {}
}
{code} 

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 right after construction time.

See the "Lifecycle management" section for more details.

h1. Overview of the selection algorithm.

The JAX-RS Selection algorithm is used to select root resource classes, resource methods and subresource locators.
 
h2. Selecting between multiple resource classes

When multiple resource classes match a given URI request, the following algorithm is used :
1. Prefer the resource class which has more literal characters in its \@Path annotation.
{code:java}

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 right after construction time.

See the "Lifecycle management" section for more details.

Overview of the selection algorithm.

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

Selecting between multiple resource classes

When multiple resource classes match a given URI request, the following algorithm is used :
1. Prefer the resource class which has more literal characters in its @Path annotation.

Code Block
java
java
@Path("/bar/{id}")
public class Test1 {}
@Path("/bar/{id}/baz")
public class Test2 {}
@Path("/foo")
public class Test3 {}
@Path("/foo/")
public class Test4 {}
{code} 

Both classes match 

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.

...

2.

...

Prefer

...

the

...

resource

...

class

...

which

...

has

...

more

...

capturing

...

groups

...

in

...

its

...

@Path

...

annotation.

Code Block
java
java


{code:java}
@Path("/bar/{id}/")
public class Test1 {}
@Path("/bar/{id}/{id2}")
public class Test2 {}
{code}

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.

...

3.

...

Prefer

...

the

...

resource

...

class

...

which

...

has

...

more

...

capturing

...

groups

...

with

...

arbitrary

...

regular

...

expressions

...

in

...

its

...

@Path

...

annotation.

Code Block
java
java


{code:java}
@Path("/bar/{id:.+}/baz/{id2}")
public class Test1 {}
@Path("/bar/{id}/bar/{id2}")
public class Test2 {}
{code}

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.

Selecting between multiple resource methods

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.

4. Prefer a resource method to a subresource locator method

Code Block
java
java
 

h2. Selecting between multiple resource methods

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.

4. Prefer a resource method to a subresource locator method

{code:java}
@Path("/")
public class Test1 {

 @Path("/bar")
 @GET
 public Order getOrder() {...}

 @Path("/bar")
 public Order getOrderFromSubresource() {...}
}

public class Order {

 @Path("/")
 @GET
 public Order getOrder() { return this; }

}
{code}
 
Both 

Both getOrderFromSubresource()

...

and

...

getOrder()

...

methods

...

can

...

be

...

used

...

to

...

serve

...

a

...

/bar

...

request.

...

However,

...

getOrder()

...

wins.

Resource methods and media types

Consider this resource class with 2 resource methods :

Code Block
java
java
 

h2. Resource methods and media types

Consider this resource class with 2 resource methods :

{code:java}
@Path("/")
public class Test1 {

 @Path("/bar")
 @POST 
 @Consumes("application/json")
 @Produces("application/json")
 public Order addOrderJSON(OrderDetails details) {...}

 @Path("/bar")
 @POST
 @Consumes("application/xml")
 @Produces("application/xml")
 public Order getOrderXML(OrderDetails details) {...}
 
}
{code}

Both

...

methods

...

match

...

/bar

...

requests.

...

If

...

in

...

a

...

given

...

request

...

both

...

Content-Type

...

and

...

Accept

...

are

...

set

...

to

...

application/xml

...

then

...

getOrderXML

...

will

...

be

...

selected.

...

If

...

both

...

Content-Type

...

and

...

Accept

...

are

...

set

...

to

...

application/json

...

then

...

getOrderJSON

...

will

...

be

...

chosen

...

instead.

...

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.

...

The

...

above

...

code

...

can

...

be

...

replaced

...

with

...

this

...

one

...

:

Code Block
java
java


{code:java}
@Path("/")
public class Test1 {

 @Path("/bar")
 @POST 
 @Consumes({"application/json", "application/xml"})
 @Produces({"application/json", "application/xml"})
 public Order addOrder(OrderDetails details) {...}

}
{code}

}
h2. 

Custom

...

selection

...

between

...

multiple

...

resources

...

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.

...

However,

...

in

...

some

...

cases,

...

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.

...

Starting

...

from

...

CXF

...

2.2

...

.5 it is possible to register a custom ResourceComparator implementation using a jaxrs:server/jaxrs:resourceComparator

...

element,

...

example:

Code Block
xml
xml

{code:xml}
<!-- JAX-RS endpoint declaration fragment -->
<jaxrs:server address="/">
<!-- Usual elements, like serviceBeans or providers, etc -->

<!-- Custom ResourceComparator -->
<jaxrs:resourceComparator>
   <bean class="org.custom.CustomResourceComparator"/>
</jaxrs:resourceComparator>
</jaxrs:server>

{code}

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.

...

Note

...

that

...

by

...

the

...

time

...

a

...

custom

...

ResourceComparator

...

is

...

called

...

the

...

provided

...

resource

...

classes

...

or

...

methods

...

have

...

already

...

been

...

successfully

...

matched

...

by

...

the

...

runtime.

...

For

...

example,

...

the

...

optional

...

HTTP

...

request

...

and

...

URI

...

parameters

...

(query,

...

matrix,

...

headers,

...

cookies)

...

and

...

form

...

parameters

...

do

...

not

...

affect

...

the

...

selection

...

algorithm.

...


A

...

custom

...

ResourceComparator

...

can

...

be

...

used

...

when

...

this

...

limitation

...

is

...

considered

...

to

...

be

...

problematic.

...

For

...

example,

...

the

...

following

...

shows

...

one

...

such

...

implementation:

Code Block
java
java


{code:java}

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.ws.rs.core.MultivaluedMap;

import org.apache.cxf.jaxrs.ext.ResourceComparator;
import org.apache.cxf.jaxrs.model.ClassResourceInfo;
import org.apache.cxf.jaxrs.model.OperationResourceInfo;
import org.apache.cxf.jaxrs.model.OperationResourceInfoComparator;
import org.apache.cxf.jaxrs.model.Parameter;
import org.apache.cxf.jaxrs.util.JAXRSUtils;
import org.apache.cxf.message.Message;

public class QueryResourceInfoComperator extends OperationResourceInfoComparator implements
         ResourceComparator {

     public QueryResourceInfoComperator() {
         super(null, null);
     }

     @Override
     public int compare(ClassResourceInfo cri1, ClassResourceInfo cri2, Message message) {
         // Leave Class selection to CXF
         return 0;
     }

     @Override
     public int compare(OperationResourceInfo oper1, OperationResourceInfo oper2, Message message) {

         // Check if CXF can make a decision
         int cxfResult = super.compare(oper1, oper2);
         if (cxfResult != 0)
             return cxfResult;

         int op1Counter = getMatchingRate(oper1, message);
         int op2Counter = getMatchingRate(oper2, message);

         return op1Counter == op2Counter
                 ? 0
                 : op1Counter<  op2Counter
                         ? 1
                         : -1;
     }

     /**
      * This method calculates a number indicating a good or bad match between
      * values provided within the request and expected method parameters. A
      * higher number means a better match.
      *
      * @param operation
      *            The operation to be rated, based on contained parameterInfo
      *            values.
      * @param message
      *            A message containing query from user request
      * @return A positive or negative number, indicating a good match between
      *         query and method
      */
     protected int getMatchingRate(OperationResourceInfo operation, Message message) {

         List<Parameter>  params = operation.getParameters();
         if (params == null || params.size() == 0)
             return 0;

         // Get Request QueryParams
         Set<String>  qParams = getParams((String) message.get(Message.QUERY_STRING));

         int rate = 0;
         for (Parameter p : params) {
             switch (p.getType()) {
             case QUERY:
                 if (qParams.contains(p.getName()))
                     rate += 2;
                 else if (p.getDefaultValue() == null)
                     rate -= 1;
                 break;
             // optionally support other parameter types such as headers, etc
             // case HEADER:
             //  break;
             default:
                 break;
             }
         }
         return rate;
     }

     /**
      * @param query
      *            URL Query Example: 'key=value&key2=value2'
      * @return A Set of all keys, contained within query.
      */
     protected Set<String>  getParams(String query) {
         Set<String>  params = new HashSet<String>();
         if (query == null || query.length() == 0)
             return params;

         MultivaluedMap<String, String> allQueries =
             JAXRSUtils.getStructuredParams(query, "&", false, false);
         return allQueries.keySet();
     }
} 
{code}

Now

...

consider

...

this

...

code:

Code Block
java
java


{code:java}
@Path("/paramTest")
public class MySimpleService {

      @GET
      public String getFoo(@QueryParam("foo") String foo){
          return "foo:" + foo;
      }

      @GET
      public String getFooBar(@QueryParam("foo") String foo,
@QueryParam("bar") String bar){
          return "foo:" + foo + " bar:" + bar;
      }

  
} 
{code} 

Using the custom comparator will lead to 

Using the custom comparator will lead to getFoo()

...

method

...

accepting

...

a

...

single

...

query

...

parameter

...

selected

...

when

...

a

...

request

...

URI

...

has

...

only

...

one

...

query

...

parameter,

...

and

...

getFoo()

...

method

...

accepting

...

multiple

...

query

...

parameters

...

selected

...

when

...

a

...

request

...

URI

...

has

...

at

...

least

...

two

...

query

...

parameters.

...

Further

...

customizations

...

may

...

also

...

be

...

possible.

Context annotations

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

A CXF-specific composite context interface, MessageContext is also supported which makes it easier to deal with all the supported JAX-RS contexts (and indeed with future ones) and also lets us check the current message's properties.

Example:

Code Block
java
java
   

h1. Context annotations

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

A CXF-specific composite context interface, [MessageContext|http://svn.apache.org/repos/asf/cxf/trunk/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/ext/MessageContext.java] is also supported which makes it easier to deal with all the supported JAX-RS contexts (and indeed with future ones) and also lets us check the current message's properties.

Example:

{code:java}
@Path("/customer")
public class CustomerService {
    
    @Context 
    private org.apache.cxf.jaxrs.ext.MessageContext mc; 
    @Context 
    private ServletContext sc;
    private UriInfo ui;
    
    @Context
    public void setUriInfo(UriInfo ui) {
        this.ui = ui;
    }

    @PUT
    public Response updateCustomer(@Context HttpHeaders h, Customer c) {
        mc.getHttpHeaders();
    }
}

{code}

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.

...

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.

...

Custom

...

Contexts

...

Registering

...

a

...

custom

...

ContextProvider

...

implementation

...

such

...

as

...

SearchContextProvider

...

lets

...

attach

...

Context

...

annotations

...

to

...

arbitrary

...

classes

...

which

...

can

...

be

...

helpful

...

when

...

some

...

of

...

the

...

information

...

representing

...

the

...

current

...

request

...

needs

...

to

...

be

...

optimized

...

or

...

specialized,

...

example:

Code Block
java
java


{code:java}
package resources;
import org.apache.cxf.jaxrs.ext.search.SearchContext;
@Path("/")
public class RootResource {
    @Context
    private  SearchContext sc;
    // the rest of the code
}
{code} 

and

{code:xml}

and

Code Block
xml
xml
<jaxrs:server>
  <serviceBeans>
    <bean class="resources.RootResource"/>
  </serviceBeans>
  <jaxrs:providers>
    <bean class="org.apache.cxf.jaxrs.ext.search.SearchContextProvider"/>
  </jaxrs:providers>
</jaxrs:server>
{code}

Custom

...

Context

...

implementations

...

may

...

get

...

all

...

the

...

information

...

about

...

the

...

HTTP

...

request

...

from

...

the

...

current

...

CXF

...

message.

URI calculation using UriInfo and UriBuilder

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

Code Block
java
java



h1. URI calculation using UriInfo and UriBuilder

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

{code:java}
@Path("/customers")
public class CustomerService {

    @GET
    public Customers getCustomers() {
        ......
    }

    @GET
    @Path("/{id}")
    public Customer getCustomer(@PathParam("id") String id) {
        ......
    }

}
{code}

For

...

this

...

service

...

we

...

can

...

assume

...

that

...

the

...

returned

...

list

...

of

...

customers

...

exposes

...

only

...

basic

...

attributes

...

and

...

more

...

details

...

is

...

returned

...

using

...

the

...

second

...

method

...

which

...

uses

...

the

...

customer

...

id

...

as

...

the

...

key.

...

Something

...

like

...

this:

{
Code Block
}
GET http://foobar.com/api/customers

<customers>
    <customer id="1005">John Doe</customer>
    <customer id="1006">Jane Doe</customer>
    ...
</customers>
    
GET http://foobar.com/api/customers/1005

<customer id="1005">
    <first-name>John</first-name>
    <last-name>Doe</last-name>
    ...
</customer>
{code}

How

...

does

...

a

...

client

...

of

...

this

...

service

...

know

...

how

...

to

...

get

...

from

...

list

...

of

...

customers

...

to

...

given

...

customer?

...

A

...

trivial

...

approach

...

would

...

be

...

to

...

expect

...

the

...

client

...

to

...

compute

...

the

...

proper

...

URI.

...

But

...

wouldn't

...

it

...

be

...

better

...

to

...

have

...

the

...

services

...

provide

...

full

...

URIs

...

in

...

the

...

response

...

that

...

can

...

be

...

used

...

directly?

...

This

...

way

...

the

...

client

...

would

...

be

...

more

...

decoupled

...

from

...

the

...

service

...

itself

...

(which

...

may

...

change

...

URI

...

format

...

over

...

time).

...

A

...

client

...

could

...

be

...

provided

...

the

...

following

...

on

...

response,

...

for

...

example:

{
Code Block
}
GET http://foobar.com/api/customers

<customers-list>
    <customer id="1005" url="http://foobar.com/api/customers/1005">John Doe</customer>
    <customer id="1006" url="http://foobar.com/api/customers/1006">Jane Doe</customer>
    ...
</customers-list>
{code}

The

...

problem

...

for

...

the

...

service

...

is

...

how

...

to

...

determine

...

these

...

URIs

...

when

...

the

...

paths

...

come

...

from

...

@Path

...

annotations.

...

It

...

gets

...

more

...

complicated

...

as

...

we

...

consider

...

paths

...

with

...

templates

...

(variables)

...

on

...

multiple

...

levels

...

or

...

sub-resources

...

introducing

...

dynamic

...

routing

...

to

...

different

...

URIs.

...

The

...

core

...

part

...

of

...

the

...

solution

...

is

...

to

...

inject

...

the

...

UriInfo

...

object

...

into

...

method

...

"getCustomers".

...

This

...

helper

...

object

...

allows

...

for

...

extracting

...

useful

...

information

...

about

...

the

...

current

...

URI

...

context,

...

but

...

more

...

importantly

...

allows

...

for

...

getting

...

the

...

UriBuilder

...

object.

...

UriBuilder

...

has

...

multiple

...

appender

...

methods

...

for

...

building

...

the

...

URI

...

for

...

each

...

object;

...

in

...

our

...

case

...

to

...

the

...

stem

...

URI

...

we

...

can

...

append

...

path

...

in

...

multiple

...

ways,

...

providing

...

it

...

as

...

a

...

string

...

(which

...

we

...

actually

...

want

...

to

...

avoid

...

here)

...

or

...

a

...

resource

...

(class

...

or

...

method)

...

to

...

extract

...

the

...

@Path

...

value.

...

Finally

...

UriBuilder

...

must

...

have

...

values

...

bound

...

to

...

its

...

template

...

variables

...

to

...

render

...

the

...

actual

...

URI.

...

This

...

case

...

in

...

action

...

looks

...

like

...

this:

Code Block
java
java


{code:java}
@Path("/customers")
public class CustomerService {

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

    @GET
    @Path("/{id}")
    public Customer getCustomer(@PathParam("id") String id) {
        ......
    }

}
{code}


h1. Annotation inheritance

Most of the 

Annotation inheritance

Most of the JAX-RS

...

annotations

...

can

...

be

...

inherited

...

from

...

either

...

an

...

interface

...

or

...

a

...

superclass.

...

For

...

example:

Code Block
java
java


{code:java}

public interface CustomerService {

    @PUT
    @Path("/customers/{id}")
    Response updateCustomer(@PathParam("id") Long id, Customer customer);

    @POST
    @Path("/customers")
    Customer addCustomer(Customer customer);

}

@Path("/customerservice/")
public class Customers implements CustomerService {

    
    public Response updateCustomer(Long id, Customer customer) {
        return Response.status(errorCode).build();
    }

    public Customer addCustomer(Customer customer) {
        throw new WebApplicationException(errorCode);
    }

}
{code}

Similarly,

...

annotations

...

can

...

be

...

inherited

...

from

...

super-classes.

...

In

...

CXF,

...

the

...

resource

...

class

...

will

...

inherit

...

the

...

class-level

...

annotations

...

from

...

both

...

its

...

implemented

...

interfaces

...

and

...

any

...

class

...

it

...

extends.

...

Sub-resource

...

locators.

...

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.

...

In

...

the

...

example

...

below,

...

getOrder

...

method

...

is

...

a

...

sub-resource

...

locator:

Code Block
java
java

{code:java}
@Path("/customerservice/")
public class CustomerService {

    @Path("/orders/{orderId}/")
    public Order getOrder(@PathParam("orderId") String orderId) {
       ......
    }
}

@XmlRootElement(name = "Order")
public class Order {
    private long id;
    private Items items;

    public Order() {
    }

    public long getId() {
        return id;
    }


    @GET
    @Path("products/{productId}/")
    public Product getProduct(@PathParam("productId")int productId) {
       ......
    }

    @Path("products/{productId}/items")
    public Order getItems(@PathParam("productId") int productId) {
       return this;
    }

    @GET
    public Items getItems() {
       ......
    }

}
{code}

A

...

HTTP

...

GET

...

request

...

to

...

http://localhost:9000/customerservice/orders/223/products/323

...

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

...

will

...

be

...

returned.

...

Similarly,

...

the

...

request

...

to

...

http://localhost:9000/customerservice/orders/223/products/323/items

...

will

...

be

...

delivered

...

to

...

the

...

getItems(productId)

...

method.

...

Note

...

that

...

a

...

subresource

...

class

...

like

...

Order

...

often

...

has

...

no

...

root

...

@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,

...

similar

...

to

...

Order.getItems(productId)

...

above.

...

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:

Code Block
java
java
  

{code:java}
@Path("/customerservice/")
public class CustomerService {

    @Path("/orders/{orderId}/")
    public Order getOrder(@PathParam("orderId") String orderId) {
       ......
    }
}

public interface Order {
    @GET
    @Path("products/{productId}/")
    Product getProduct(@PathParam("productId")int productId);
}

@XmlRootElement(name = "Order")
public class OrderImpl implements Order {
    
    public Product getProduct(int productId) {
       ......
    }
}

@XmlRootElement(name = "Order")
public class OrderImpl2 implements Order {
    
    // overrides JAXRS annotations
    @GET
    @Path("theproducts/{productId}/")
    Product getProduct(@PathParam("id")int productId) {...}
}

{code}

h2. Static resolution of subresources

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.

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

Static resolution of subresources

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.

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 :

Code Block
xml
xml
 method then you may want to disable the dynamic resolution :


{code:xml}
<beans>
<jaxrs:server staticSubresourceResolution="true">
<!-- more configuration -->
</jaxrs:server>
</beans>
{code}

Note

...

-

...

starting

...

from

...

CXF

...

2.7.2

...

the

...

injection

...

of

...

JAX-RS

...

contexts

...

and

...

parameters

...

will

...

also

...

be

...

supported

...

if

...

this

...

property

...

has

...

been

...

enabled.

...

Message

...

Body

...

Providers

...

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.

...


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.

...

See

...

also

...

the

...

"Support

...

for

...

data

...

bindings"

...

section

...

below.

...

Custom

...

Message

...

Body

...

Providers

It's

...

likely

...

that

...

a

...

given

...

application

...

may

...

need

...

to

...

deal

...

with

...

types

...

that

...

are

...

not

...

supported

...

by

...

default.

...

Alternatively,

...

developers

...

may

...

want

...

to

...

provide

...

a

...

more

...

efficient

...

implementation

...

for

...

handling

...

default

...

types

...

such

...

as

...

InputStream.

...

Here's

...

an

...

example

...

of

...

a

...

custom

...

MessageBodyReader

...

for

...

InputStream:

Code Block
java
java


{code:java}

@Consumes("application/octet-stream")
@Provider
public class InputStreamProvider implements MessageBodyReader<InputStream> {

    
    public boolean isReadable(Class<InputStream> type, Type genericType, Annotation[] annotations, MediaType mt) {
        return InputStream.class.isAssignableFrom(type);
    }

    public InputStream readFrom(Class<InputStream> clazz, Type t, Annotation[] a, MediaType mt, 
                         MultivaluedMap<String, String> headers, InputStream is) 
        throws IOException {
        return new FilterInputStream(is) {
             @Override
             public int read(byte[] b) throws IOException {
                 // filter out some bytes
             }              
        }     
    }
}

{code}

and

...

here's

...

an

...

example

...

of

...

a

...

custom

...

MessageBodyWriter

...

for

...

Long

...

objects:

Code Block
java
java


{code:java}

@Produces("text/plain")
@Provider
public class LongProvider implements MessageBodyWriter<Long> {

    public long getSize(Long l, Class<?> type, Type genericType, Annotation[] annotations, MediaType mt) {
        return -1;
    }

    public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mt) {
        return long.class.isAssignableFrom(type) || Long.class.isAssignableFrom(type);
    }

    public void writeTo(Long l, Class<?> clazz, Type type, Annotation[] a, 
                        MediaType mt, MultivaluedMap<String, Object> headers, OutputStream os) 
        throws IOException {
        os.write(l.toString().getBytes());
        
    }

{code}

CXF

...

ships

...

some

...

custom

...

providers

...

too,

...

for

...

dealing

...

with

...

Atom

...

(based

...

on

...

Apache

...

Abdera)

...

and

...

XMLObjects.

...

CXF

...

also

...

supports

...

primitive

...

types

...

and

...

their

...

Number

...

friends

...

when

...

text/plain

...

media

...

type

...

is

...

used,

...

either

...

on

...

input

...

or

...

output.

Registering custom providers

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.

One can easily register a provider either from Spring configuration or programmatically:

Code Block
xml
xml
   

h2. Registering custom providers  


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. 


One can easily register a provider either from Spring configuration or programmatically:

{code:xml}

<beans>
<jaxrs:server id="customerService" address="/">
    <jaxrs:serviceBeans>
      <bean class="org.CustomerService" />
    </jaxrs:serviceBeans>

    <jaxrs:providers>
      <ref bean="isProvider" />
      <ref bean="longProvider" />
    </jaxrs:providers>
    <bean id="isProvider" class="com.bar.providers.InputStreamProvider"/>
    <bean id="longProvider" class="com.bar.providers.LongProvider"/>
</jaxrs:server>
</beans>
{code}

Note

...

that

...

instead

...

of

...

the

...

older

...

<jaxrs:entityProviders>

...

it's

...

now

...

<jaxrs:providers>.

...

JAX-RS

...

supports

...

different

...

types

...

of

...

providers

...

and

...

having

...

a

...

single

...

<jaxrs:providers>

...

container

...

is

...

in

...

line

...

with

...

the

...

way

...

other

...

JAX-RS

...

implementations

...

discover

...

providers

...

by

...

checking

...

for

...

@Provider

...

annotations

...

only.

...

See

...

below

...

for

...

a

...

more

...

complete

...

beans.xml

...

definition.

...

While

...

having

...

@Provider-annotated

...

providers

...

automatically

...

registered

...

is

...

a

...

handy

...

feature

...

indeed,

...

sometimes

...

it

...

might

...

actually

...

be

...

problematic.

...

For

...

example,

...

in

...

a

...

large

...

project

...

user

...

providers

...

from

...

different

...

libraries

...

might

...

clash.

...

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:

Code Block
xml
xml


{code:xml}

<beans>
<jaxrs:server id="customerService1" address="/1">
   <bean id="serviceBean" class="org.CustomerService" /> 

   <jaxrs:serviceBeans>
      <ref bean="serviceBean"/>
   </jaxrs:serviceBeans>

   <jaxrs:providers>
      <bean class="com.bar.providers.InputStreamProvider"/>
   </jaxrs:providers>
</jaxrs:server>
<jaxrs:server id="customerService2" address="/2">
    <jaxrs:serviceBeans>
      <ref bean="serviceBean"/>
    </jaxrs:serviceBeans>

    <jaxrs:providers>
      <bean id="isProvider" class="baz.foo.jaxrsproviders.InputStreamProvider"/>
    </jaxrs:providers>
</jaxrs:server>

<jaxrs:server id="customerService3" address="/3">
    <jaxrs:serviceBeans>
      <ref bean="serviceBean"/>
    </jaxrs:serviceBeans>

    <jaxrs:providers>
      <ref bean="isProvider"/>
    </jaxrs:providers>
</jaxrs:server>


<bean id="isProvider" class="com.bar.providers.InputStreamProvider">
   <property name="limit" value="5"/>
</bean>

</beans>
{code}

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.

...

Customizing media types for message body providers

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<Foo> 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 @Produces annotation in a MessageBodyWriter<Foo> implementation. The same applies if a method accepts a custom type Foo, but this time the value of @Consumes in MessageBodyReader<Foo> will be matched against a request's ContentType value.

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.

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.
See this example on how to provide custom media types from Spring.

Advanced HTTP

The JAX-RS specification requires support for a number of advanced HTTP features.

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.

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