Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.


{span:style=
Span
Wiki Markup
style
font-size:2em;font-weight:bold
} JAX-RS : Data Bindings



Table of Contents

JAXB support

The request and response can be marshalled and unmarshalled to/from a Java object using JAXB.

There are a number of ways to tell to the JAXB provider how objects can be serialized. The simplest way is to mark a given type with @XmlRootElement annotation.

For example:

Code Block
java
java
 Bindings {span}

{toc}

h1. JAXB support

The request and response can be marshalled and unmarshalled to/from Java object using JAXB. 

There's a number of ways to tell to the JAXB provider how objects can be serialized. The simplest way is to mark a given type with @XmlRootElement annotation. 


For example:
{code:java}
@XmlRootElement(name = "Customer")
public class Customer {
    private String name;
    private long id;

    public Customer() {
    }

    public void setName(String n) {
        name = n;
    }

    public String getName() {
        return name;
    }

    public void setId(long i) {
        id = i;
    }

    public long getId() {
        return id;
    }
}
{code}

In

...

the

...

example

...

below,

...

the

...

Customer

...

object

...

returned

...

by

...

getCustomer

...

is

...

marshalled using

...

the JAXB

...

data

...

binding:

Code Block
java
java

{code:java}
@Path("/customerservice/")
public class CustomerService {
    @GET
    @Path("/customers/{customerId}/")
    public Customer getCustomer(@PathParam("customerId") String id) {
        ....
    }
}
{code}

The

...

wire

...

representation

...

of

...

the Customer

...

object

...

is:

Code Block
xml
xml

{code:xml}
<Customer>
    <id>123</id>
    <name>John</name>
</Customer>
{code}

The

...

simplest

...

way

...

to

...

work

...

with

...

collections

...

is

...

to

...

define

...

a

...

type

...

representing

...

a

...

collection.

...

For

...

example:

Code Block


{code}
@XmlRootElement(name = "Customers")
public class Customers {
    private Collection<Customer> customers;

    public Collection<Customer> getCustomer() {
        return customers;
    }

    public void setCustomer(Collection<Customer> c) {
        this.customers = c;
    }
}
@Path("/customerservice/")
public class CustomerService {
    @GET
    @Path("/customers/")
    public Customers getCustomers() {
        ....
    }
}
{code}

Alternatively to using @XmlRootElement and Collection wrappers, one can provide an Object factory which will tell JAXB how to marshal a given type (in case of Collections - its template type). Another option is to return/accept a JAXBElement directly from/in a given method.

Another option is to register one or more JAX-RS 

As an alternative to using @XmlRootElement and Collection wrappers, one can provide an Object factory which will tell JAXB how to marshal a given type (in case of Collections - its template type). Another option is to return/accept a JAXBElement directly from/in a given method.

Another option is to register one or more JAX-RS ContextResolver providers capable of creating JAXBContexts for a number of different types. The default JAXBElementProvider will check these resolvers first before attempting to create a JAXBContext on its own.

Finally, JAXBProvider provides support for serializing response types and deserializing parameters of methods annotated with @XmlJavaTypeAdapter annotations.

Configuring the JAXB provider

The default JAXB provider can be configured in a number of ways. For example, here's how to configure marshal properties :

Code Block
xml
xml
ContextResolver providers capable of creating JAXBContexts for a number of different types. The default JAXBElementProvider will check these resolvers first before attempting to create a JAXBContext on its own.   

Finally, JAXBProvider provides a support for serializing response types and deserializing parameters of methods annotated with @XmlJavaTypeAdapter annotations.     

h2. Configuring JAXB provider

The default JAXB provider can be configured in a number of ways. For example, here's how to set up marshall properties :

{code:xml}
<beans xmlns:util="http://www.springframework.org/schema/util">
    <bean id="jaxbProvider" class="org.apache.cxf.jaxrs.provider.JAXBElementProvider">
<property name="marshallerProperties"        <property name="marshallerProperties" ref="propertiesMap"/>
    </bean>
    <util:map id="propertiesMap">
        <entry key="jaxb.formatted.output">
            <value type="java.lang.Boolean">true</value>
        </entry>
    </util:map>
/<beans>
{code}

Individual

...

marshal

...

properties

...

can

...

be

...

injected

...

as

...

simple

...

properties.

...

At

...

the

...

moment,

...

Marshaller.JAXB_SCHEMA_LOCATION

...

can

...

be

...

injected

...

as

...

the "schemaLocation"

...

property.

...

Schema

...

validation

...

can

...

be

...

enabled

...

and

...

custom

...

@Consume

...

and

...

@Produce

...

media

...

types

...

can

...

be

...

injected,

...

see

...

this

...

example and the "Customizing media types for message body providers" and "Schema Validation" sections for more information.

One issue which one may need to be aware of it is that an exception may occur during the JAXB serialization process, after some content has already been processed and written to the output stream. By default, the output goes directly to the output HTTP stream so if an exception occurs midway through the process then the output will likely be malformed. If you set 'enableBuffering' property to 'true' then a JAXB provider will write to the efficient CXF CachedOutputStream instead and if an exception occurs then no text which has already been written will make it to the outside world and it will be only this exception that will be reported to the client.

When enabling buffering, you can also control how the data being serialized will be buffered. By default, an instance of CXF CachedOutputStream will be used. If you set an "enableStreaming" property on the JAXBElementProvider then it will be a CXF CachingXMLEventWriter that will cache the serialization events.

If you would like your own custom provider to write to a cached stream then you can either set an "org.apache.cxf.output.buffering"

...

property

...

to

...

'true'

...

on

...

a

...

jaxrs

...

endpoint

...

or

...

"enableBuffering"

...

property

...

on

...

the

...

provider.

...

If

...

this

...

provider

...

deals

...

with

...

XML

...

and

...

has

...

a

...

"getEnableStreaming"

...

method

...

returning

...

'true'

...

then

...

CachingXMLEventWriter

...

will

...

be

...

used,

...

in

...

all

...

other

...

cases

...

CachedOutputStream

...

will

...

be

...

used.

...

Please

...

note

...

that

...

if

...

you

...

don't

...

have

...

wrapper

...

types

...

for

...

your

...

methods

...

and

...

the

...

classloader

...

you

...

are

...

using

...

does

...

not

...

allow

...

you

...

to

...

call

...

defineClass(),

...

you

...

may

...

need

...

to

...

set

...

'-Dcom.sun.xml.bind.v2.bytecode.ClassTailor.noOptimize'

...

JAXB

...

Marshaller,

...

Unmarshaller

...

and

...

context

...

properties

...

can

...

be

...

configured

...

for

...

both

...

JAXB

...

and

...

JSON

...

providers.

...

Both

...

providers

...

can

...

also

...

be

...

configured

...

to

...

skip

...

the

...

isReadable()

...

and

...

isWriteable()

...

checks

...

to

...

do

...

with

...

asserting

...

that

...

a

...

given

...

instance

...

is

...

likely

...

to

...

be

...

successfully

...

read/written

...

by

...

setting

...

a

...

'skipChecks'

...

property

...

to

...

true.

...

This

...

can

...

be

...

useful

...

when

...

it

...

is

...

known

...

that

...

only

...

valid

...

JAXB

...

instances

...

are

...

read

...

or

...

written.

...

Starting

...

from

...

CXF

...

2.4.3

...

it

...

is

...

possible

...

to

...

have

...

specific

...

prefixes

...

associated

...

with

...

XML

...

namespaces.

...

This

...

might

...

be

...

needed

...

to

...

make

...

legacy

...

consumers

...

able

...

to

...

consume

...

the

...

resulting

...

XML.

...

Use

...

a

...

"namespacePrefixes"

...

map

...

property

...

(namespace

...

is

...

a

...

key,

...

corresponding

...

prefix

...

is

...

a

...

value).

...

JAXB and Moxy

For JAXBElementProvider to support Moxy a custom Moxy-aware JAX-RS ContextProvider implementation needs to be registered in jaxrs:providers.

...

For

...

example:

{
Code Block
java
java
import javax.xml.bind.JAXBContext;:java}
import javax.xml.bind.JAXBContextJAXBException;
import javax.ws.rs.ext.ContextResolver;
import org.eclipse.persistence.jaxb.JAXBContextFactory;

public class MoxyJaxbContextResolved implements ContextResolver<JAXBContext> {

  org.eclipse.persistence.jaxb.JAXBContextFactory factory = new JAXBContextFactory();

  public JAXBContext getContext(Class<?> cls) {
      try {
          return factoryJAXBContextFactory.createContext(new Class[] {cls}, null);
      } catch (JAXBException ex) {
          throw new RuntimeException(ex);
      }
{code  }

}

Alternatively,

...

add

...

a

...

"jaxb.properties"

...

file

...

with

...

the

...

entry

...

"javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory"

...

to

...

a

...

package

...

where

...

the JAXB

...

beans

...

are

...

located.

...

If

...

Moxy

...

is

...

used

...

to

...

handle

...

beans

...

without

...

JAXB

...

annotations

...

then

...

setting

...

a

...

'skipJaxbChecks'

...

property

...

on

...

JAXBElementProvider

...

to

...

'true'

...

will

...

be

...

needed.

...

Use

...

JAXBElementProvider

...

"namespaceMapperPropertyName"

...

and

...

"xmlPiPropertyName"

...

properties

...

if

...

you

...

need

...

to

...

customize

...

namespace

...

prefixes

...

or

...

add

...

XML

...

processing

...

instructions

...

with

...

Moxy.

...

JSONProvider

...

will

...

also

...

recognize

...

"namespaceMapperPropertyName"

...

in

...

cases

...

when

...

the

...

namespaces

...

are

...

not

...

ignored.

...

JSON support

The following code returns a Customer object that is marshaled to JSON format:

Code Block
 support

Following code returns a Customer object that is marshaled to JSON format:
{code}
@Path("/customerservice/")
public class CustomerService {
    @Produces("application/json")
    @GET
    @Path("/customers/{customerId}/")
    public Customer getCustomer(@PathParam("customerId") String id) {
        ....
    }
{code}

h2. 

Jettison

...

Configuring

...

JSON provider

The default JSON provider relies on Jettison 1.4.0 and it expects the types it deals with to follow the same techniques as described above in the JAXB support section for them to be handled properly.

The default JSON provider can be configured in a number of ways. For example, here's how to set up namespace-to-prefix mappings :

Code Block
xml
xml
 provider

Default JSON provider relies on Jettison 1.3 and it expects the types it deals with to follow the same techniques as described above in the JAXB support section for them to be handled properly. 

The default JSON provider can be configured in a number of ways. For example, here's how to set up namespace-to-prefix mappings :

{code:xml}
<beans xmlns:util="http://www.springframework.org/schema/util">
    <bean id="jaxbProvider" class="org.apache.cxf.jaxrs.provider.json.JSONProvider">
        <property name="namespaceMap" ref="jsonNamespaceMap"/>
    </bean>
    <util:map id="jsonNamespaceMap" map-class="java.util.Hashtable">
        <entry key="http://www.example.org/books" value="b"/>
    </util:map>
/<beans>
{code}

*Note* that starting from CXF 

Note that starting from CXF 2.3.0

...

it

...

may

...

not

...

be

...

needed

...

to

...

set

...

up

...

a

...

custom

...

namespace

...

map

...

on

...

the

...

write

...

side

...

with

...

JSONProvider

...

making

...

a

...

'best'

...

effort

...

to

...

retrieve

...

them

...

during

...

the

...

JAXB

...

Marshaller

...

calls.

...

Starting

...

from

...

CXF

...

2.6.1

...

and

...

2.5.4

...

setting

...

the

...

namespace

...

maps

...

will

...

additionally

...

configure

...

a

...

Marshaller

...

namespace

...

mapper.

...

Schema

...

validation

...

can

...

be

...

enabled

...

and

...

custom

...

@Consume

...

and

...

@Produce

...

media

...

types

...

can

...

be

...

injected,

...

see

...

this

...

example

...

and

...

"Customizing

...

media

...

types

...

for

...

message

...

body

...

providers"

...

and

...

"Schema

...

Validation"

...

sections

...

for

...

more

...

information.

Note that JSONProvider is Jettison based and supports only JAXB annotated beans. You should use Jackson provider to process POJOs without JAXB annotations.

Dealing with Jettison array serialization issues

By default, Jettison wrongly serializes List objects containing a single value only. To work around this issue, one needs to enable a 'serializeAsArray' feature on a JSONProvider, with the additional option of specifying the individual fields which needs to be processed accordingly using an 'arrayKeys' property. Please see this example for more information.

Note that 'serializeAsArray' and 'arrayKeys' can be combined to produce so called natural convention sequences. For example, given the following two class definitions :

Code Block
java
java
 

h3. Dealing with JSON array serialization issues 

There is a well known problem in the JSON community which shows itself in the wrong serialization of List objects containing a single value only. To work around this issue, one needs to enable a 'serializeAsArray' feature on a JSONProvider, with the additional option of specifying the individual fields which needs to be processed accordingly using an 'arrayKeys' property. Please see [this example|http://svn.apache.org/repos/asf/cxf/trunk/systests/jaxrs/src/test/resources/jaxrs/WEB-INF/beans.xml] for more information. 

Note that 'serializeAsArray' and 'arrayKeys' can be combined to produce so called natural convention sequences. For example, given the following two class definitions :

{code:java}
@XmlRootElement()
@XmlType(name = "", propOrder = {"title", "comments" })
public static class Post {
    private String title;
    private List<Comment> comments = new ArrayList<Comment>ArrayList<>();
    public void setTitle(String title) {
        this.title = title;
    }
    public String getTitle() {
        return title;
    }
    public void setComments(List<Comment> comments) {
        this.comments = comments;
    }
    public List<Comment> getComments() {
        return comments;
    }
}
   
public static class Comment {
     private String title;

     public void setTitle(String title) {
        this.title = title;
     }

     public String getTitle() {
         return title;
     }
} 
{code}

an

...

instance

...

of

...

Post

...

class

...

can

...

be

...

serialized

...

like

...

this

...

if

...

a

...

JSONProvider

...

has

...

had

...

its

...

'serializeAsArray'

...

property

...

set

...

to

...

'true'

...

and

...

'arrayKeys'

...

list

...

property

...

set

...

to

...

contain

...

'comments'

...

value

...

:

...

>

...

{"post":

...

{"title":"post","comments":

...

[

...

{"title":"comment1"

...

},

...

{"title":"comment2"

...

}

...

]

...

}

...

}

...

One

...

other

...

property

...

which

...

might

...

help

...

during

...

the

...

serialization

...

is

...

a

...

boolean

...

"ignoreMixedContent"

...

property

...

which

...

allows you to

...

bypass

...

a

...

Jettison

...

issue

...

to

...

do

...

with

...

outputting

...

'$'

...

properties

...

when

...

dealing

...

with

...

empty

...

strings

...

typically

...

encountered

...

in

...

mixed

...

content

...

trees.

...

You

...

may

...

request

...

that

...

JSONProvider

...

ignores

...

an

...

'xsi:type'

...

attribute

...

which

...

is

...

serialized

...

in

...

some

...

cases

...

by

...

setting

...

a

...

"writeXsiType"

...

boolean

...

property

...

with

...

a

...

'false'

...

value.

...

You

...

may

...

also

...

request

...

that

...

JSONProvider

...

ignores

...

all

...

the

...

namespaces

...

during

...

the

...

serialization

...

process

...

by

...

setting

...

an

...

"ignoreNamespaces"

...

boolean

...

property

...

with

...

a

...

'true'

...

value.

...

Starting from CXF 2.7.6 (and Jettison 1.3.4):

  • 'writeNullAsString' property can be used to affect the way Jettison writes out null values, if this property is set to 'false' then Jettison will write null values without wrapping them in double quotes.
  • new 'dropElementsInXmlStream' can be set to false and be used with outDropElements property to affect the serialization directly at the Jettison level

BadgerFish convention

Starting from CXF 2.2.5 it is possible to configure JSONProvider to support a BadgerFish convention. By default a "mapped" convention is supported, set a JSONProvider "convention" property with the value "badgerfish" if you'd like to work with the BadgerFish convention.

Wrapping and Unwrapping JSON sequences

A "wrapperName" string property can be used to append a dropped root element name to an incoming JSON sequence for it to be deserialized properly. A "wrapperMap" map property can be used to nominate wrapper names for individual class names. In both cases, a 'supportUnwrapped' boolean property also has to be set.

A boolean "dropRootName" property can be used to tell JSONProvider that a root element needs to be dropped.

TypeConverters

Jettison 1.2 supports the registration of org.codehaus.jettison.mapped.TypeConverter

...

implementations

...

which

...

can

...

be

...

used

...

to

...

convert

...

types

...

to

...

JSON

...

primitives.

...

The

...

"typeConverter"

...

property

...

can

...

be

...

used

...

to

...

register

...

a

...

converter

...

with

...

JSONProvider

...

instance.

...

The

...

"convertTypesToStrings"

...

property

...

can

...

be

...

used

...

to

...

configure

...

JSONProvider

...

to

...

convert

...

all

...

the

...

types

...

to

...

strings.

Jackson

If you prefer working with Jackson JSON providers then register either JacksonJsonProvider:

Code Block
xml
xml
   

h2. Jackson

If you prefer working with Jackson JSON providers then register either JacksonJsonProvider:
{code:xml}
<jaxrs:providers>
   <bean class="org.codehaus.jackson.jaxrs.JacksonJsonProvider"/>
</jaxrs:providers>
{code}

or

...

JacksonJaxbJsonProvider

...

(when

...

working

...

with

...

JAXB

...

beans):

Code Block
xml
xml


{code:xml}
<jaxrs:providers>
   <bean class="org.codehaus.jackson.jaxrs.JacksonJaxbJsonProvider"/>
</jaxrs:providers>
{code}


and add this Maven dependency:
{code:xml}

and add this Maven dependency:

Code Block
xml
xml
<dependency>
  <groupId>org<groupId>com.fasterxml.codehausjackson.jackson<jaxrs</groupId>
  <artifactId>jackson-jaxrs-json-jaxrs<provider</artifactId>
  <version>1<version>2.9.0<3</version>
</dependency>
{code}

h1. Common JAXB and JSON configuration

In this section 

Common JAXB and JSON configuration

In this section it's

...

expected

...

that

...

Jettison

...

is

...

used

...

to

...

handle

...

JSON.

...

Single

...

JAXBContext

...

and

...

extra

...

user

...

classes

...

By

...

default

...

JAXBContexts

...

are

...

created

...

on

...

demand.

...

Starting

...

from

...

CXF

...

2.3.2

...

and

...

2.4.0

...

it

...

is

...

possible

...

to

...

configure

...

JAXB-based

...

providers

...

to

...

support

...

the

...

creation

...

of

...

a

...

single

...

JAXBContext,

...

example

...

:

Code Block
xml
xml


{code:xml}
<bean id="jaxb" class="org.apache.cxf.jaxrs.provider.JAXBElementProvider">
      <property name="singleJaxbContext" value="true"/>
      <property name="extraClass">
         <list>
           <value>org.apache.cxf.jaxrs.resources.SuperBook</value>
           <value>org.apache.cxf.jaxrs.resources.SuperBook</value>  
         </list>
      </property>
</bean>
{code}

Please

...

note

...

that

...

if

...

an

...

extraClass

...

property

...

is

...

set

...

then

...

the

...

JAXBContext

...

(single

...

as

...

in

...

the

...

above

...

example

...

or

...

the

...

one

...

created

...

dynamically

...

on

...

a

...

per-class

...

or

...

per-package

...

basis)

...

will

...

also

...

include

...

the

...

extra

...

user

...

classes

...

thus

...

making

...

it

...

possible

...

to

...

avoid

...

setting

...

an

...

XmlSeeAlso

...

JAXB

...

annotation

...

or

...

dealing

...

with

...

JAXB

...

jaxb.index

...

or

...

ObjectFactory

...

resources.

...

This

...

property

...

is

...

identical

...

to

...

a

...

CXF

...

JAXBDataBinding

...

'extraClass'

...

property.

...

Trying

...

to

...

create

...

a

...

single

...

JAXBContext

...

is

...

also

...

an

...

optimization

...

step.

...

Having

...

a

...

single

...

JAXBContext

...

for

...

classes

...

the

...

JAX-RS

...

runtime

...

can

...

statically

...

discover

...

by

...

checking

...

all

...

the

...

root

...

resources

...

and

...

their

...

sub-resources

...

(assuming

...

the

...

jaxrs:server

...

endpoint

...

has

...

been

...

configured

...

to

...

do

...

the

...

static

...

resolution

...

of

...

the

...

sub-resources)

...

does

...

not

...

preclude

...

JAX-RS

...

Responses

...

wrapping

...

JAXB

...

beans

...

being

...

used

...

as

...

well.

...

One

...

may

...

want

...

to

...

use

...

the

...

"singleJaxbContext"

...

property

...

in

...

combination

...

with

...

the

...

"skipChecks"

...

property

...

if

...

it

...

is

...

known

...

that

...

only

...

valid

...

JAXB

...

beans

...

will

...

be

...

read

...

or

...

written.

...

Also

...

note

...

that

...

setting

...

only

...

"extraClass",

...

without

...

setting

...

"singleJaxbContext"

...

property

...

will

...

also

...

work

...

in

...

cases

...

when

...

no

...

package

...

JAXB

...

contexts

...

are

...

created

...

(specifically

...

when

...

no

...

ObjectFactory

...

or

...

jaxb.index

...

have

...

been

...

found).

...

Starting

...

from

...

CXF

...

2.7.2

...

and

...

2.6.4

...

it

...

will

...

also

...

work

...

well

...

for

...

package

...

contexts.

...

However,

...

when

...

possible,

...

prefer

...

always

...

setting

...

both

...

"singleJaxbContext"

...

and

...

"extraClass"

...

properties.

...

Starting

...

from

...

CXF

...

2.7.2

...

this

...

will

...

also

...

work

...

well

...

for

...

package-level

...

contexts

...

-

...

add

...

"useSingleContextForPackages"

...

property

...

to

...

get

...

the

...

created

...

single

...

context

...

always

...

used

...

as

...

a

...

package

...

context.

...

Automatic JAXBElement conversion during serialization

In some cases, wrapping object instances into JAXBElements may affect the way XML is produced. For example, given Base and Derived classes, returning an instance of Derived class, with Base one being a method response type, would produce an additional xsi:type attribute if this instance is wrapped into JAXBElement. One can set a "jaxbElementClassNames" list property which can contain class names like "org.foo.Base",

...

etc.

...

Handling JAXB beans without XmlRootElement annotations

A "jaxbElementClassNames"

...

list

...

property

...

mentioned

...

in

...

the

...

previous

...

section

...

can

...

affect

...

the

...

serialization

...

of

...

objects

...

of

...

types

...

with

...

XmlRootElement

...

annotations.

...


In

...

some

...

cases

...

no

...

XmlRootElement

...

annotations

...

are

...

available

...

on

...

types

...

and

...

adding

...

them

...

manually

...

may

...

not

...

be

...

an

...

option;

...

likewise

...

having

...

explicit

...

JAXBElements

...

in

...

method

...

signatures

...

may

...

also

...

be

...

seen

...

as

...

too

...

intrusive.

...

In

...

such

...

cases,

...

one

...

might

...

want

...

to

...

use

...

a

...

"jaxbElementClassMap"

...

map

...

property

...

which

...

contains

...

class

...

name

...

to

...

simple

...

or

...

expanded

...

QName

...

pairs.

...

This

...

will

...

also

...

lead

...

to

...

the

...

automatic

...

JAXBElement

...

conversion

...

durring

...

the

...

serialization.

...

Finally,

...

'marshalAsJaxbElement'

...

boolean

...

property

...

can

...

be

...

used

...

when

...

all

...

the

...

instances

...

need

...

to

...

be

...

wrapped

...

-

...

provided

...

that

...

simple

...

class

...

names

...

of

...

these

...

instances

...

can

...

be

...

used

...

as

...

element

...

names.

...

When

...

deserializing,

...

one

...

can

...

either

...

update

...

an

...

existing

...

ObjectFactory

...

with

...

methods

...

returning

...

JAXBElements

...

or

...

simply

...

set

...

an

...

'unmarshalFromJaxbElement'

...

property

...

on

...

either

...

JAXB

...

or

...

JSON

...

provider.

...

Handling explicit collections

JAXB and JSON providers can handle explicit collections like List, Set or base Collection.
By default they will try to deduce the name of the collection root element from a collection member class. For example, given a Book.class whose @XmlRootElement value is 'Book', the name of the collection name will be 'Books'.
One can override it by setting a 'collectionWrapperName' string property, like 'Books' or '{http://books}Book'.

...

There's

...

also

...

a

...

'collectionWrapperMap'

...

property

...

available

...

for

...

use

...

in

...

more

...

advanced

...

cases,

...

when

...

collections

...

of

...

different

...

types

...

are

...

used,

...

for

...

example,

...

when

...

mixed

...

collections

...

of

...

objects

...

descended

...

from

...

abstract

...

classes

...

having

...

no

...

@XmlRootElement

...

tags

...

are

...

returned

...

:

Code Block
xml
xml

{code:xml}
<!-- Configure JAXB Provider -->
<bean id="jaxbProvider"
    class="org.apache.cxf.jaxrs.provider.JAXBElementProvider">
    <property name="collectionWrapperMap">
  <map>
      <entry><map>
      <key><value>com.foo.bar.MyObject</value></key>
      <value>MyObjects</value><entry>
                <key><value>com.foo.bar.MyObject</value></key>
                <value>MyObjects</value>
            </entry>
        </map>
    </property>
</bean> 
{code}

JSONProvider

...

can

...

only

...

serialize

...

explicit

...

collections

...

at

...

the

...

moment.

...

If

...

needed,

...

it

...

can

...

be

...

told

...

to

...

drop

...

a

...

collection

...

element

...

name

...

using

...

a

...

boolean

...

'dropCollectionWrapperElementName'.

...

For

...

example,

...

a

...

'dropCollectionWrapperElementName'

...

and

...

'serializeAsArray'

...

properties

...

can

...

be

...

used

...

to

...

make

...

the

...

Pojo JSON

...

RestStore

...

consume

...

the

...

resulting

...

JSON

...

sequence

...

(in

...

CXF

...

2.2.5).

Customizing JAXB XML and JSON input and output

Sometimes you may want to adapt an incoming XML request or outgoing XML response. For example, your application has changed but a lot of legacy clients have not been updated yet.
When dealing with XML, the easiest and fastest option is to register a custom STAX XMLStreamWriter or XMLStreamReader and modify XML as needed. You can register a custom STAX
handler from RequestHandler or ResponseHandler filters or input/output CXF interceptors. For example, see XMLStreamWriterProvider and CustomXmlStreamWriter.

Another option is to register a custom JAXB or JSON provider extending CXF JAXBElementProvider or JSONProvider and overriding a method like createStreamWriter().
Typically one would delegate to a super class first and then wrap the returned writer in a custom writer, see CustomXmlStreamWriter for an example.

One can also use XSLTJaxbProvider to produce or modify the incoming XML. In fact, XSLTJaxbProvider can be used to adapt formats like JSON for legacy consumers.

Please also see this overview of various related features available in CXF.

In CXF 2.2.5, a new feature has been introduced whose goal is to generalize and simplify in a number of cases the way both JAXB and JSON can be customized.

Note that starting from CXF 2.4.0 the new Transformation Feature can be used instead.

The following configuration properties have been added to the base JAXB/JSON AbstractJAXBProvider :

  • "outTransformElements" map property: can be used to change the output element names and change or drop namespaces; keys are the elements to be changed, values are the new element names. Examples:
Code Block
xml
xml


h1. Customizing JAXB XML and JSON input and output

Sometimes you may want to adapt an incoming XML request or outgoing XML response. For example, your application has changed but a lot of legacy clients have not been updated yet.
When dealing with XML, the easiest and fastest option is to register a custom STAX XMLStreamWriter or XMLStreamReader and modify XML as needed. You can register a custom STAX 
handler from RequestHandler or ResponseHandler filters or input/output CXF interceptors. For example, see [XMLStreamWriterProvider|http://svn.apache.org/repos/asf/cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/XmlStreamWriterProvider.java] and [CustomXmlStreamWriter|http://svn.apache.org/repos/asf/cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/CustomXmlStreamWriter.java].

Another option is to register a custom JAXB or JSON provider extending CXF JAXBElementProvider or JSONProvider and overriding a method like createStreamWriter(). 
Typically one would delegate to a super class first and then wrap the returned writer in a custom writer, see [CustomXmlStreamWriter|http://svn.apache.org/repos/asf/cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/CustomXmlStreamWriter.java] for an example.

One can also use XSLTJaxbProvider to produce or modify the incoming XML. In fact, XSLTJaxbProvider can be used to adapt formats like JSON for legacy consumers.

Please also see this [overview|http://soa.dzone.com/articles/pragmatic-web-services-apache] of various related features available in CXF. 

In CXF 2.2.5, a new feature has been introduced whose goal is to generalize and simplify in a number of cases the way both JAXB and JSON can be customized.

Note that starting from CXF 2.4.0 the new [Transformation Feature|TransformationFeature] can be used instead.

The following configuration properties have been added to the base JAXB/JSON AbstractJAXBProvider :

- "outTransformElements" map property: can be used to change the output element names and change or drop namespaces; keys are the elements to be changed, values are the new element names. Examples: 

{code:xml}
<bean id="jaxbProvider" class="org.apache.cxf.jaxrs.provider.JAXBElementProvider">
  <property name="outTransformElements">
    <map>
      <!-- change "book" to "thebook" -->
      <entry key="book" value="thebook"/>
      
      <!-- drop the namespace from "book" -->
      <entry key="{http://books}book" value="book"/> 
      
      <!-- qualify "book" with "http://books" -->
      <entry key="book" value="{http://books}thebook"/> 
      
      <!--  change namespace to "http://books" for all the elements with the "http://book" namespace -->
      <entry key="{http://book}*" value="{http://books}*"/> 
    </map>
  </property>
</bean> 
{code}

- 
  • "inTransformElements"

...

  • map

...

  • property:

...

  • can

...

  • be

...

  • used

...

  • to

...

  • change

...

  • the

...

  • input

...

  • element

...

  • names

...

  • and

...

  • change

...

  • or

...

  • drop

...

  • namespaces;

...

  • see

...

  • the

...

  • "outTransfromElements"

...

  • property

...

  • description

...

  • for

...

  • an

...

  • example.

...

  • "outAppendElements"

...

  • map

...

  • property:

...

  • can

...

  • be

...

  • used

...

  • to

...

  • append

...

  • new

...

  • simple

...

  • or

...

  • qualified

...

  • elements

...

  • to

...

  • the

...

  • output;

...

  • keys

...

  • are

...

  • the

...

  • new

...

  • elements,

...

  • values

...

  • are

...

  • the

...

  • elements

...

  • the

...

  • new

...

  • ones

...

  • will

...

  • be

...

  • appended

...

  • before.

...

  • Examples:
Code Block
xml
xml
 

{code:xml}
<bean id="jaxbProvider" class="org.apache.cxf.jaxrs.provider.JAXBElementProvider">
  <property name="outAppendElements">
    <map>
      <!-- append "book" before "thebook" -->
      <entry key="book" value="thebook"/>
      
      <!-- qualify "book" with "http://books" -->
      <entry key="{http://books}book" value="book"/> 
      
      <!-- drop the namespace from the "book" -->
      <entry key="book" value="{http://books}thebook"/> 
      
      <!--  change namespace to "http://book" for all the elements with the "http://books" namespace -->
      <entry key="{http://book}*" value="{http://books}*"/> 
    </map>
  </property>
</bean> 
{code}

- 
  • "inAppendElements"

...

  • map

...

  • property

...

  • :

...

  • can

...

  • be

...

  • used

...

  • to

...

  • append

...

  • new

...

  • simple

...

  • or

...

  • qualified

...

  • elements

...

  • to

...

  • the

...

  • input;

...

  • see

...

  • the

...

  • "outAppendElements"

...

  • property

...

  • description

...

  • for

...

  • an

...

  • example.

...

  • "outDropElements"

...

  • list

...

  • property

...

  • :

...

  • can

...

  • be

...

  • used

...

  • to

...

  • drop

...

  • elements

...

  • during

...

  • the

...

  • serialization;

...

  • note

...

  • that

...

  • children

...

  • elements

...

  • if

...

  • any

...

  • of

...

  • a

...

  • given

...

  • dropped

...

  • element

...

  • are

...

  • not

...

  • affected.

...

  • Examples:
Code Block
xml
xml
 

{code:xml}
<bean id="jaxbProvider" class="org.apache.cxf.jaxrs.provider.JAXBElementProvider">
  <property name="outDropElements">
    <list>
      <!-- ignore drop and {http://numbers}number elements -->
      <value>{http://numbers}number</value>
      <value>index</value>
    </list>
  </property>
</bean> 
{code}

- 
  • "inDropElements"

...

  • list

...

  • property

...

  • :

...

  • can

...

  • be

...

  • used

...

  • to

...

  • drop

...

  • elements

...

  • during

...

  • the

...

  • deserialization;

...

  • note

...

  • that

...

  • children

...

  • elements

...

  • if

...

  • any

...

  • of

...

  • a

...

  • given

...

  • dropped

...

  • element

...

  • are

...

  • not

...

  • affected.

...

  • Please

...

  • see

...

  • the

...

  • "outDropElements"

...

  • property

...

  • description

...

  • for

...

  • an

...

  • example.

...

  • "attributesAsElements"

...

  • boolean

...

  • property

...

  • :

...

  • can

...

  • be

...

  • used

...

  • to

...

  • have

...

  • attributes

...

  • serialized

...

  • as

...

  • elements.

...

The

...

combination

...

of

...

"attributesAsElements"

...

and

...

"outDropElements"

...

properties

...

can

...

be

...

used

...

to

...

have

...

certain

...

attributes

...

ignored

...

in

...

the

...

output

...

by

...

turning

...

then

...

into

...

elements

...

first

...

and

...

then

...

blocking

...

them.

...

This

...

feature

...

might

...

be

...

used

...

in

...

a

...

number

...

of

...

cases.

...

For

...

example,

...

one

...

may

...

have

...

rootless

...

JSON

...

array

...

collections

...

such

...

as

...

"

...

a:b

...

},

...

{c:d

...

"

...

deserialized

...

into

...

a

...

bean

...

by

...

using

...

a

...

"wrapperName"

...

JSONProvider

...

property

...

with

...

a

...

value

...

like

...

"list"

...

which

...

identifies

...

a

...

bean

...

field

...

and

...

an

...

"inAppendMap"

...

property

...

with

...

a

...

name

...

of

...

the

...

bean

...

(ex,

...

"book")

...

being

...

appended

...

before

...

the

...

"list",

...

thus

...

effectively

...

turning

...

the

...

original

...

JSON

...

sequence

...

into

...

"

...

{book:

...

{list:

...

a:b

...

},

...

{c:d

...

}

...

}

...

".

...

Controlling

...

Large

...

JAXB

...

XML

...

and

...

JSON

...

input

...

payloads

...

Starting

...

from

...

CXF

...

2.6.0

...

it

...

is

...

possible

...

to

...

control

...

the

...

depth

...

of

...

large

...

XML

...

and

...

JSON

...

payloads

...

on

...

the

...

per-endpoint

...

basis

...

in

...

order

...

to

...

limit

...

the

...

risk

...

of

...

the

...

denial

...

of

...

service

...

attacks.

...

Please

...

see

...

this

...

section

...

on

...

how

...

to

...

use

...

a

...

new

...

DepthRestrictingInterceptor

...

in

...

order

...

to

...

control

...

XML

...

payloads

...

which

...

are

...

read

...

either

...

by

...

JAXBElementProvider

...

or

...

SourceProvider

...

(which

...

supports

...

JAXP

...

Source

...

and

...

DOM

...

Document

...

types).

...

Additionally

...

it

...

is

...

possible

...

to

...

configure

...

JAXBElementProvider

...

or

...

JSONProvider

...

with

...

contextual

...

properties

...

or

...

DocumentDepthProperties:

Code Block
xml
xml
<bean id="depthProperties" class="org|http://svn.apache.org/repos/asf/cxf/trunk/api/src/main/java/org/apache/cxf/staxutils/DocumentDepthProperties.java]:

{code:xml}

<bean id="depthProperties" class="org.apache.cxf.staxutils.DocumentDepthPropertiescxf.staxutils.DocumentDepthProperties">
  <property name="innerElementCountThreshold" value="500"/>
</bean> 

<bean id="jaxbProvider" class="org.apache.cxf.jaxrs.provider.JAXBElementProvider">
  <property name="depthProperties" ref="depthProperties"/>
</bean> 

<bean id="jsonProvider" class="org.apache.cxf.jaxrs.provider.json.JSONProvider">
  <property name="depthProperties" ref="depthProperties"/>
</bean> 

<jaxrs:server id="endpoint1">
  <jaxrs:serviceBeans>
    <bean class="my.package.RootResource"/>
  </jaxrs:serviceBeans>
  <jaxrs:providers>
    <ref bean="jaxbProvider"/>
    <ref bean="jsonProvider"/>
  </jaxrs:providers>
</jaxrs:server>

<jaxrs:server id="endpoint2">
  <jaxrs:serviceBeans>
    <bean class="my.package.RootResource"/>
  </jaxrs:serviceBeans>
  <jaxrs:properties>
    <entry key="depthInnerElementCountThreshold" value="500"/
  </jaxrs:properties>
</jaxrs:server>


{code}

h1. JSON With Padding (JSONP)

One option for supporting "JSON With Padding" ([JSONP|http://en.wikipedia.org/wiki/JSONP]) is to extend the default JSONProvider and override its writeTo method as follows:
{code:java}

@Produces("application/javascript")
class JsonpProvider extends JSONProvider {
		
    @Override
    public void writeTo(Object obj, Class<?> cls, Type genericType, Annotation[] anns, MediaType m, MultivaluedMap<String, Object> headers,
	OutputStream os) throws IOException {
	String prefix = getContext().getHttpServletRequest().getParameter("_jsonp");
	boolean hasPrefix = !isEmpty(prefix);
	if(hasPrefix) {
	    os.write(prefix.getBytes(HttpUtils.getSetEncoding(m, headers, "UTF-8")));
	    os.write('(');
	}
	super.writeTo(obj, cls, genericType, anns, m, headers, os);
	if(hasPrefix) {
		os.write(')');
	}
    }
}
{code} 

Similar approach can work when Jackson is used.

Alternatively, a custom servlet filter can be used to support JSONP. Please read the [Supporting JSONP|http://josh.media.berkeley.edu/?p=78] blog post for more information. 

Starting from CXF 2.3.4 and 2.4.0, JSONP can be supported with the help of CXF in/out interceptors:

{code:xml}
<jaxrs:server id="bookJsonp" address="/jsonp">
    <jaxrs:serviceBeans>
      <ref bean="serviceBean" />
    </jaxrs:serviceBeans>		  

    <jaxrs:inInterceptors>
       <bean class="

JSR-353 JSON Processing

As per JAX-RS 2.0 specification, the support of JSR-353 Java API for JSON Processing is mandatory requirement and implies the presence of message body reader(s)/writer(s) for following types: JsonStructure, JsonArray and JsonObject. Apache CXF provides such a support in a form of JsrJsonpProvider provider distributed by Apache CXF JAX-RS Extensions Providers module (cxf-rt-rs-extension-providers).

Code Block
xml
xml
<jaxrs:providers>
   <bean class="org.apache.cxf.jaxrs.provider.jsrjsonp.JsrJsonpProvider"/>
</jaxrs:providers>

Adding JsrJsonpProvider provider alone (or in a combination with other providers) allows JAX-RS resources to natively use JsonStructure, JsonArray, JsonObject as input parameters or return values. For example:

Code Block
java
java
@GET
@Path("/books")
@Produces(MediaType.APPLICATION_JSON)
public JsonArray getBooks() {
    // Implementation here
}

@GET
@Path("/books/{bookId}")
@Produces(MediaType.APPLICATION_JSON)
public JsonObject getBook(@PathParam("bookId") Long id) {
    // Implementation here
}

@POST
@Path("/books")
@Consumes(MediaType.APPLICATION_JSON)
public Response addBook(@Context final UriInfo uriInfo, JsonObject obj) {
    // Implementation here
}

The JsrJsonpProvider provider could be used on server side or on a client side. By default, the provider uses JSR-353 Java API for JSON Processing reference implementation to read/write message bodies.

JSR-367 JSON Binding

As per JAX-RS 2.1 specification, the support of JSR 367: Java API for JSON Binding (JSON-B) is desired requirement and implies the presence of message body reader(s)/writer(s) for Java types supported by JSON-B. Apache CXF provides such a support in a form of JsrJsonbProvider provider distributed by Apache CXF JAX-RS Extensions Providers module (cxf-rt-rs-extension-providers).

Code Block
xml
xml
<jaxrs:providers>
   <bean class="org.apache.cxf.jaxrs.provider.jsrjsonb.JsrJsonbProvider"/>
</jaxrs:providers>

Adding JsrJsonbProvider providers also covers JsonStructure, JsonArray, JsonObject as input parameters or return values.

Simple JsonMapObject support

org.apache.cxf.jaxrs.provider.json.JsonMapObjectProvider is available starting from CXF 3.0.3 and CXF 3.1.0. This provider can read or write JSON into/from org.apache.cxf.jaxrs.provider.json.JsonMapObject which is a simple Map wrapper.

JsonMapObject can detect duplicate JSON sibling properties which can be useful in certain applications.

JSON With Padding (JSONP)

One option for supporting "JSON With Padding" (JSONP) is to extend the default JSONProvider and override its writeTo method as follows:

Code Block
java
java
@Produces("application/javascript")
class JsonpProvider extends JSONProvider {
		jsonp.JsonpInInterceptor"/>
    </jaxrs:inInterceptors>
    <jaxrs:outInterceptors>@Override
    public void writeTo(Object <bean class="org.apache.cxf.jaxrs.provider.jsonp.JsonpPreStreamInterceptor"/>
       <bean class="org.apache.cxf.jaxrs.provider.jsonp.JsonpPostStreamInterceptor"/>obj, Class<?> cls, Type genericType, Annotation[] anns, MediaType m, 
    </jaxrs:outInterceptors> 
</jaxrs:server>
{code}

JsonpInInterceptor checks if a JSONP callback query parameter is available (default is _jsonp) and if yes then it saves itsMultivaluedMap<String, valueObject> onheaders, theOutputStream currentos) exchangethrows forIOException out{
	 interceptors to know ifString theyprefix = getContext().getHttpServletRequest().getParameter("_jsonp");
	    boolean hasPrefix = !isEmpty(prefix);
	    if(hasPrefix) {
	        os.write(prefix.getBytes(HttpUtils.getSetEncoding(m, headers, "UTF-8")));
	        os.write('(');
	    }
	    super.writeTo(obj, cls, genericType, anns, m, headers, os);
	    if(hasPrefix) {
		    os.write(')');
	    }
    }
}

A similar approach can work when Jackson is used.

Alternatively, a custom servlet filter can be used to support JSONP.

Starting from CXF 2.3.4 and 2.4.0, JSONP can be supported with the help of CXF in/out interceptors:

Code Block
xml
xml
have to write the paddings or not. The name of the expected callback parameter can be customized. JsonpPreStreamInterceptor and JsonpPostStreamInterceptor ensure the actual JSON stream is 'padded' properly. JsonpPreStreamInterceptor will also set Content-Type to "application/x+javascript" by default but this can be changed:

{code:xml}
<jaxrs:server id="bookJsonp" address="/jsonp">
    <jaxrs:serviceBeans>
      <ref bean="serviceBean" />
    </jaxrs:serviceBeans>		  

    <jaxrs:inInterceptors>
       <bean class="org.apache.cxf.jaxrs.provider.jsonp.JsonpInInterceptor"/>
    </jaxrs:inInterceptors>
    <jaxrs:outInterceptors>
  <property name="callbackParam" value="myjsonp"/>
       </bean> 
    </jaxrs:inInterceptors>
    <jaxrs:outInterceptors>
            <bean class="org.apache.cxf.jaxrs.provider.jsonp.JsonpPreStreamInterceptor">
           <property name="mediaType" value="text/x+javascript"/>
       </bean>
       <bean class="org.apache.cxf.jaxrs.provider.jsonp.JsonpPostStreamInterceptor"/>
           <!-- default is ');' -->
           <property name="paddingEnd" value=")"</jaxrs:outInterceptors> 
</jaxrs:server>

JsonpInInterceptor checks if a JSONP callback query parameter is available (default is _jsonp) and if yes then it saves its value on the current exchange for out interceptors to know if they have to write the paddings or not. The name of the expected callback parameter can be customized. JsonpPreStreamInterceptor and JsonpPostStreamInterceptor ensure the actual JSON stream is 'padded' properly. JsonpPreStreamInterceptor will also set Content-Type to "application/x+javascript" by default but this can be changed:

Code Block
xml
xml
<jaxrs:server id="bookJsonp" address="/jsonp">
    <jaxrs:serviceBeans>
      <ref bean="serviceBean" />
    </jaxrs:serviceBeans>		  

   </bean> <jaxrs:inInterceptors>
    </jaxrs:outInterceptors> 
</jaxrs:server>
{code}

h1. Form payloads

Form payload is a sequence of name and value pairs, example, "name=Barry&age=20".
One can capture the form data by using either JAX-RS FormParam annotation or MultivaluedMap, for example:

{code:java}

import javax.ws.rs.FormParam;
import javax.ws.rs.MultivaluedMap;

@Path("resource")
public class FormResource {

   @POST
   @Path("/form1")
   @Consumes("application/x-www-form-urlencoded")
   public void form1(@FormParam("name") String name, @FormParam("age") int age) {
   }

   @POST
   @Path("/form2")
   @Consumes("application/x-www-form-urlencoded")
   public void form1(MultivaluedMap<String, String> params) {
       String name = params.getFirst("name");   <bean class="org.apache.cxf.jaxrs.provider.jsonp.JsonpInInterceptor">
          <property name="callbackParam" value="myjsonp"/>
       </bean> 
    </jaxrs:inInterceptors>
    <jaxrs:outInterceptors>
       <bean class="org.apache.cxf.jaxrs.provider.jsonp.JsonpPreStreamInterceptor">
           <property name="mediaType" value="text/x+javascript"/>
       </bean>
       <bean class="org.apache.cxf.jaxrs.provider.jsonp.JsonpPostStreamInterceptor">
           <!-- default is ');' -->
           <property name="paddingEnd" value=")"/>
       String age = params.getFirst("age");
   }

}
{code}

Note that it is possible to control the maximum number of the expected form parameters by setting a "maxFormParameterCount" contextual property (set within the jaxrs:properties). The client will receive HTTP 413 if the limit is reached.

h1. Atom

CXF JAXRS offers users 3 options for dealing with Atom

1. Register Apache Abdera based Feed and/or Entry providers </bean>
    </jaxrs:outInterceptors> 
</jaxrs:server>

Form payloads

A Form payload is a sequence of name and value pairs, example, "name=Barry&age=20".
One can capture the form data by using either JAX-RS FormParam annotation or MultivaluedMap, for example:

Code Block
java
java
import javax.ws.rs.FormParam;
import javax.ws.rs.MultivaluedMap;

@Path("resource")
public class FormResource {

   @POST
   @Path("/form1")
   @Consumes("application/x-www-form-urlencoded")
   public void form1(@FormParam("name") String name, @FormParam("age") int age) {
   }

   @POST
   @Path("/form2")
   @Consumes("application/x-www-form-urlencoded")
   public void form1(MultivaluedMap<String, String> params) {
       String name = params.getFirst("name");
       String age = params.getFirst("age");
   }

}

Note that it is possible to control the maximum number of the expected form parameters by setting a "maxFormParameterCount" contextual property (set within the jaxrs:properties). The client will receive HTTP 413 if the limit is reached.

Atom

CXF JAXRS offers users 3 options for dealing with Atom

1. Register Apache Abdera based Feed and/or Entry providers (org.apache.cxf.jaxrs.ext.provider.atom.AtomFeedProvider

...

and

...

org.apache.cxf.jaxrs.ext.provider.atom.AtomEntryProvider)

...

with

...

a

...

jaxrs

...

endpoint

...

and

...

have

...

resource

...

methods

...

explicitly

...

dealing

...

with

...

Abdera

...

Feed

...

or

...

Entry

...

classes.

...

This

...

is

...

the

...

most

...

advanced

...

option

...

in

...

that

...

it

...

lets

...

users

...

build

...

Feeds

...

or

...

Entries

...

in

...

the

...

way

...

which

...

suits

...

most.

...

Note

...

that

...

Abdera

...

has

...

not

...

been

...

actively

...

mantained

...

recently

...

but

...

practically

...

speaking

...

it

...

is

...

very

...

good

...

for

...

working

...

with

...

most

...

of

...

the

...

cases

...

one

...

may

...

have

...

to

...

deal

...

with

...

when

...

developing

...

Atom-based

...

applications.

...

Both

...

AtomFeedProvider

...

and

...

AtomEntryProvider

...

support

...

a

...

'formattedOutput'

...

(pretty-printing)

...

property.

...

2.

...

Register

...

an

...

AtomPojoProvider injected with either AtomElementWriter or AtomElementReader implementations parameterized by either Abdera Feed or Entry and type of object which will have to be converted to/read from Feed/Entry.

For example, BookAtomElementWriter<Feed, Book> will be responsible for converting Book instances into Feeds while ChapterAtomElementWriter<Entry, Chapter> will be responsible for converting Chapter instances into Entries.

AtomElementWriter and AtomElementReader are injected using 'atomWriters' and 'atomReaders' map properties, where the keys are class names of the objects to be converted to/read from Feed or Entries, ex "org.apache.cxf.systest.jaxrs.Book".

AtomPojoProvider offers users a way to have no Abdera Feed/Entry classes referenced from the 'main' application code, example :

Code Block
java
java
@Path("books")
public class BooksRootResource {

    private Books books;

    @GET
    @Produces({"application/xml", "application/json", "application/atom+xml;type=feed"})
    public Books getCollectionOfBooks() {
        return books;
    } 

    @GET
    @Produces({"application/xml", "application/json", "application/atom+xml;type=entry"})
    @Path("{id}")
    public Book getBook(@PathParam("id") Long id) {
        return books.get(id);
    }
}

Note that when an object such as Books is about to be converted to/read from Feed (which in our case is essentially a collection of entries each of them representing an individual Book) the AtomPojoProvider needs to know about the collection getters and/or setters so that it can create individual Entries. The "collectionGetters" and "collectionSetters" map properties with keys being the names of collection classes and values being the method names need to be used for providing this information, example a pair "org.apache.cxf.systest.jaxrs.Books:getBooks" tells AtomPojoProvider that when creating a Books Feed, the objects representing individual entries can be retrieved from Book with the help of "getBooks". If these properties are not set then AtomPojoProvider will try to get a method adding the simple class name to either 'get' or 'set', for example, an "org.apache.cxf.systest.jaxrs.Books:getBooks" pair is redundant if the Books class has a getBooks method.

3. This option is nearly identical to the option 2, except that users configure AtomPojoProvider with concrete implementations of either AbstractFeedBuilder or AbstractEntryBuilder.

The difference is that in this case users have no explicit dependencies in their code on Atom-aware libraries such as Abdera - it may make it easier to experiment with various Atom libraries.

Aegis Data Binding

Use org.apache.cxf.provider.AegisElementProvider

...

to

...

start

...

doing

...

Aegis

...

with

...

JAX-RS

...


org.apache.cxf.provider.AegisJSONProvider

...

can

...

be

...

used

...

to

...

output

...

JSON

...

with

...

the

...

help

...

of

...

Aegis.

...


Similarly

...

to

...

the

...

default

...

JSONProvider

...

this

...

Aegis-based

...

JSON

...

provider

...

can

...

have

...

"namespaceMap",

...

"serializeAsArray",

...

"arrayKeys",

...

"dropRootElement"

...

and

...

"writeXsiType"

...

properties

...

set.

...

XMLBeans

Use org.apache.cxf.provider.XmlBeansElementProvider

...

to

...

start

...

doing

...

XmlBeans

...

with

...

JAX-RS

...

CXF

...

DataBindings

...

as

...

JAX-RS

...

providers

...

Starting

...

from

...

CXF

...

2.2.3

...

it

...

is

...

possible

...

to

...

register

...

a

...

CXF

...

DataBinding

...

bean

...

using

...

a

...

jaxrs:databinding

...

element

...

and

...

it

...

will

...

be

...

wrappped

...

as

...

a

...

JAXRS

...

MessageBodyReader/Writer

...

DataBindingProvider

...

capable

...

of

...

dealing

...

with

...

XML-based

...

content.

...

It

...

can

...

be

...

of

...

special

...

interest

...

to

...

users

...

combining

...

JAX-RS

...

and

...

JAXWS.

...

Thus

...

CXF

...

JAXB,

...

JIBX,

...

Aegis,

...

SDO

...

and

...

XMLBeans

...

DataBindings

...

can

...

be

...

plugged

...

in.

...

DataBindingProvider

...

can

...

also

...

be

...

registered as a jaxrs:provider with its dataBinding property being set as needed.

JSON support is also provided for all these databindings by DataBindingJSONProvider.
Please see this configuration file for some examples.

Similarly to the default JSONProvider the DataBindingJSONProvider JSON provider can have "namespaceMap", "serializeAsArray", "arrayKeys", "dropRootElement" and "writeXsiType" properties set. Additionally it may also have an "ignoreMixedContent" property set.

Starting from CXF 2.4.0 and CXF 2.3.2 a CXF DataBinding annotation is also supported.

JAXRS DataBinding

Available starting from CXF 2.3.2 and CXF 2.4.0

org.apache.cxf.jaxrs.provider.JAXRSDataBinding

...

is

...

a

...

CXF

...

DataBinding

...

implementation

...

which

...

wraps

...

JAX-RS

...

providers

...

and

...

can

...

be

...

used

...

by

...

CXF

...

JAX-WS

...

endpoints

...

thus

...

making

...

it

...

possible

...

to

...

use

...

JAX-RS

...

providers

...

for

...

reading

...

and

...

writing

...

XML

...

payloads

...

during

...

SOAP

...

and

...

RESTful

...

invocations.

...

Example

...

:

Code Block
xml
xml


{code:xml}
  <jaxrs:server id="hello_rest" address="/hello-rest">
    <jaxrs:serviceBeans>
        <bean class="org.apache.cxf.systest.jaxrs.jaxws.HelloWorldImpl"/>
    </jaxrs:serviceBeans>

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

  <jaxws:endpoint xmlns:s="http://hello.com"
      serviceName="s:HelloWorld"
      endpointName="s:HelloWorldPort"
      id="hello_soap-databinding"
      implementor="org.apache.cxf.systest.jaxrs.jaxws.HelloWorldImpl"
      address="/hello-soap-databinding">
      
      <jaxws:dataBinding>
          <ref bean="jaxrs-data-binding"/>
      </jaxws:dataBinding>
      
  </jaxws:endpoint>        
 
  <bean id="jaxrs-data-binding" class="org.apache.cxf.jaxrs.provider.JAXRSDataBinding">
      <property name="provider" ref="jaxbProviderSoap"/>
  </bean>

  <bean id="jaxbProviderSoap" class="org.apache.cxf.jaxrs.provider.JAXBElementProvider"/>

This option is similar to the one involving wrapping CXF DataBindings as JAX-RS providers and using them for handling the data for the JAX-RS endpoints. This time though it is SOAP endpoints which are relying on the JAX-RS providers to handle the data properly.

If you would like to write your own custom XML provider and have it wrapped by the JAXRSDataBinding then custom MessageBodyReader and MessageBodyWriter implementations should be ready to accept null InputStream and OutputStream parameters and retrieve XMLStreamReader and XMLStreamWriter instances from the current CXF Message. To make the custom provider as portable as possible, one may want to follow the following approach :

Code Block
java
java
>
{code} 

This option is similar to the one involving wrapping CXF DataBindings as JAX-RS providers and using them for handling the data for the JAX-RS endpoints. This time though it is SOAP endpoints which are relying on the JAX-RS providers to handle the data properly. 

If you would like to write your own custom XML provider and have it wrapped by the JAXRSDataBinding then custom MessageBodyReader and MessageBodyWriter implementations should be ready to accept null InputStream and OutputStream parameters and retrieve XMLStreamReader and XMLStreamWriter instances from the current CXF Message. To make the custom provider as portable as possible, one may want to follow the following approach :

{code:java}

public class PortableXMLProvider implements MessageBodyReader, MessageBodyWriter {

    public Object readFrom(Class<Object> type, Type genericType, Annotation[] anns, MediaType mt, 
                           MultivaluedMap<String, String> headers, InputStream is) 
                           throws IOException {

        XMLStreamReader reader = createReaderUsingStandardStaxApi(is);
        return readFromStream(reader);  

    }

    public void writeTo(Object obj, Class<?> cls, Type genericType, Annotation[] anns,  
                        MediaType m, MultivaluedMap<String, Object> headers, OutputStream os)
                        throws IOException {
        XMLStreamWriter writer = createWriterUsingStandardStaxApi(os);
        writeToStream(writer);  
    }

    // add more parameters if needed
    protected Object readFromStream(XMLStreamReader reader) {
        // read from XMLStreamReader
    }
    
    // add more parameters if needed
    protected void writeToStream(XMLStreamWriter writer) {
        // write to XMLStreamWriter
    }

    
}

public class CXFCustomXMLProvider extends PortableXMLProvider {

    @Override
    public Object readFrom(Class<Object> type, Type genericType, Annotation[] anns, MediaType mt, 
                           MultivaluedMap<String, String> headers, InputStream is) 
                           throws IOException {

        XMLStreamReader reader = getStaxHandlerFromCurrentMessage(XMLStreamReader.class);
        return readFromStream(reader);  

    }

    @Override
    public void writeTo(Object obj, Class<?> cls, Type genericType, Annotation[] anns,  
                        MediaType m, MultivaluedMap<String, Object> headers, OutputStream os)
                        throws IOException {
        XMLStreamWriter writer = getStaxHandlerFromCurrentMessage(XMLStreamWriter.class);
        writeToStream(writer);  
    }


    protected <T> T getStaxHandlerFromCurrentMessage(Class<T> staxCls) {
        Message m = PhaseInterceptorChain.getCurrentMessage();
        if (m != null) {
            return staxCls.cast(m.getContent(staxCls));
        }
        return null;
    }
}
{code}

Please

...

note

...

that

...

if

...

you

...

need

...

the

...

advanced

...

DataBinding

...

support

...

for

...

your

...

JAX-WS

...

endpoints

...

(such

...

as

...

the

...

schema

...

validation

...

with

...

the

...

schemas

...

being

...

available

...

in

...

the

...

WSDL

...

documents

...

-

...

likely

...

to

...

be

...

supported,

...

un-wrapping

...

the

...

XML

...

payloads

...

into

...

multiple

...

method

...

parameters)

...

then

...

you

...

are

...

recommended

...

to

...

use

...

one

...

of

...

the

...

CXF

...

DataBindings

...

supported

...

by

...

CXF

...

JAX-WS

...

endpoints

...

directly.

...

If

...

all

...

the

...

resource

...

methods

...

have

...

a

...

single

...

parameter

...

such

...

as

...

a

...

valid

...

JAXB

...

class

...

and

...

a

...

response

...

type

...

which

...

is

...

not

...

expected

...

to

...

be

...

wrapped

...

then

...

it

...

is

...

likely

...

this

...

approach

...

will

...

work.

...

When

...

using

...

a

...

CXF

...

JAX-RS

...

JAXBElementProvider,

...

you

...

may

...

need

...

to

...

tune

...

it

...

to

...

properly

...

handle

...

JAXB

...

classes

...

without

...

XmlRootElement

...

annotations

...

and

...

optionally

...

create

...

a

...

single JAXBContext, something that CXF JAXBDataBinding does automatically. Also note that JAXBElementProvider is not aware that in some cases the local name of the first method parameter is "arg0" for SOAP requests and the local name of the SOAP response is expected to be "return". You may need to use JAX-WS WebParam and WebResult annotations to create different names; alternatively, you can use JAXBElementProvider's inTransformElements and outTransformElements properties, for example, to have 'arg0' converted to a bean name such as 'User' and 'User' converted to 'return'.

Schema validation

New: starting from CXF 3.0.0-milestone2 it is possible to point only to classpath folders containing multiple schema resources.

Schema validation can be enabled in one of the following ways:

1. Using jaxrs:schemaLocations element

Code Block
xml
xml
<beans>
    <jaxrs:server address="/" serviceClass="org.apache.cxf.systest.jaxrs.BookStore">
        <jaxrs:schemaLocations>
             <jaxrs:schemaLocation>classpath:/schemas/a.xsd</jaxrs:schemaLocation>
             <jaxrs:schemaLocation>classpath:/schemas/b.xsd</jaxrs:schemaLocation>
             <!-- Possible from CXF 3.0.0 milestone2: -->
             <!-- 
             JAXBContext, something that CXF JAXBDataBinding does automatically. Also note that JAXBElementProvider is not aware that in some cases the local name of the first method parameter is "arg0" for SOAP requests and the local name of the SOAP response is expected to be "return". You may need to use JAX-WS WebParam and WebResult annotations to create different names; alternatively, you can use JAXBElementProvider's inTransformElements and outTransformElements properties, for example, to have 'arg0' converted to a bean name such as 'User' and 'User' converted to 'return'.    

h1. Schema validation

Schema validation can be enabled in one of the following ways:

1. Using jaxrs:schemaLocations element

{code:xml}
<beans>
<jaxrs:server address="/" serviceClass="org.apache.cxf.systest.jaxrs.BookStore">
  <jaxrs:schemaLocations>
     <jaxrs:schemaLocation>classpath:/schemas/a.xsd<</jaxrs:schemaLocation>
         <jaxrs:schemaLocation>classpath:/schemas/b.xsd</jaxrs:schemaLocation>
    -->  
        </jaxrs:schemaLocations>
    </jaxrs:server>
</beans>
{code}

Using this option is handy when you have multiple bindings involved which support the schema validation. In this case
individual MessageBodyReader implementations which have a method setSchemas(List<Sring> schemaLocations) have it called and locations tobeans>

Using this option is handy when you have multiple bindings involved which support the schema validation. In this case individual MessageBodyReader implementations which have a method setSchemas(List<Sring> schemaLocations) have it called and locations to schema resources injected. Default JAXBElementProvider and JSONProvider which rely on JAXB can be enabled to do the validation this way. In the above example two schema documents are provided, with b.xsd schema importing a.xsd

2. Configuring providers individually

JAXB and JSON providers can be configured explicitly, for example:

Code Block
xml
xml
 schema resources injected. Default JAXBElementProvider and JSONProvider which rely on JAXB can be enabled to do the validation this way. In the above example two schema documents are provided, with b.xsd schema importing a.xsd  

2. Configuring providers individually

JAXB and JSON providers can be configured explicitly, for example:

{code:xml}
<beans xmlns:util="http://www.springframework.org/schema/util">
   <jaxrs:server address="/" serviceClass="org.apache.cxf.systest.jaxrs.BookStore">
 <jaxrs:providers>

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

    <bean id="jaxbProvider" class="org.apache.cxf.jaxrs.provider.JAXBElementProvider">
        <property name="schemaLocations" ref="schemaHolder"/>
    </bean>
  
    <util:list id="theSchemas">
        <value>classpath:/WEB-INF/schemas/bookid.xsd</value>
        <value>classpath:/org/apache/cxf/systest/jaxrs/resources/book.xsd</value>
    </util:list>
</beans>
{code}

If

...

you

...

have

...

both

...

JAXB

...

and

...

JSON

...

providers

...

validating

...

the

...

input

...

data

...

then

...

you

...

can

...

get

...

schemas

...

shared

...

between

...

them,

...

for

...

example:

Code Block
xml
xml

{code:xml}
<beans xmlns:util="http://www.springframework.org/schema/util">
    <jaxrs:server address="/" serviceClass="org.apache.cxf.systest.jaxrs.BookStore">
        <jaxrs:providers>
            <ref bean="jaxbProvider"/>
            <ref bean="jsonProvider"/>
        </jaxrs:providers>
    </jaxrs:server>

    <bean id="jaxbProvider" class="org.apache.cxf.jaxrs.provider.JAXBElementProvider">
        <property name="schemaHandler" ref="schemaHolder"/>
    </bean>

    <bean id="jsonProvider" class="org.apache.cxf.jaxrs.provider.json.JSONProvider">
        <property name="schemaHandler" ref="schemaHolder"/>
    </bean>
  
    <bean id="schemaHolder" class="org.apache.cxf.jaxrs.utils.schemas.SchemaHandler">
        <property name="schemas" ref="theSchemas"/>
    </bean>
  
    <util:list id="theSchemas">
        <value>classpath:/WEB-INF/schemas/bookid.xsd</value>
        <value>classpath:/org/apache/cxf/systest/jaxrs/resources/book.xsd</value>
    </util:list>
</beans>
{code}

h2. Support for catalogs

Available starting from CXF 

3. Using SchemaValidation annotation 

Starting from CXF 3.0.0 it is possible to use org.apache.cxf.annotations.SchemaValidation with JAX-RS root resources. Set its optional "schemas" property.

Support for catalogs

Available starting from CXF 2.5.5,

...

2.6.2

...

XML

...

Catalogs

...

can

...

be

...

used

...

for

...

the

...

main

...

schema

...

(which

...

is

...

used

...

to

...

validate

...

the

...

data)

...

to

...

get

...

the

...

imported

...

or

...

included

...

schema

...

resources

...

resolved

...

locally.

...


By

...

default,

...

a

...

"META-INF/jax-rs-catalog.xml"

...

will

...

be

...

checked

...

however

...

the

...

catalog

...

location

...

can

...

be

...

set

...

either

...

on

...

JAXBElementProvider

...

or

...

JSONProvider:

Code Block
xml
xml


{code:xml}
<bean id="jaxbProvider" class="org.apache.cxf.jaxrs.provider.JAXBElementProvider">
   <property name="catalogLocation" value="classpath:/schemas/mycatalog.xml"/>
</bean>

{code}

where 

where mycatalog.xml

...

may

...

look

...

like

...

this:

Code Block
xml
xml


{code:xml}
<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog" prefer="system">
    <system systemId="http://schemas/bookid.xsd" uri="classpath:WEB-INF/schemas/bookid.xsd"/>
</catalog>
{code}


h2. Output validation

By default, after a valid schema has been located, only JAXB Unmarshaller will use it to validate the input.
Starting from CXF 

Output validation

By default, after a valid schema has been located, only JAXB Unmarshaller will use it to validate the input.
Starting from CXF 2.3.4

...

and

...

2.4,

...

the

...

following

...

properties

...

can

...

be

...

used

...

to

...

enable

...

the

...

output

...

validation:

...

  • validateOutput
  • validateBeforeWrite

Setting the 'validateOutput'

...

property

...

will

...

ensure

...

that

...

JAXBMarshaller

...

will

...

validate

...

the

...

output

...

while

...

writing

...

the

...

data.

...

The

...

'validateBeforeWrite'

...

property

...

can

...

be

...

set

...

to

...

ensure

...

the

...

validation

...

is

...

done

...

before

...

data

...

are

...

written

...

to

...

the

...

output

...

stream.

Bean Validation

Bean Validation can be used to complement the schema validation or as an alternative form of validation, please see this page for more information.

Fast Infoset

You can enable FastInfoset by explicitly registering CXF FastInfoset interceptors with a JAXRS endpoint and configuring JAXBElementProvider to support an "application/fastinfoset"

...

media

...

type

...

:

...


for

...

example

...

:

Code Block
xml
xml

{code:xml}

<jaxrs:server id="restservice3" address="/rest3">

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

    <jaxrs:providers>
        <ref bean="jaxbProvider"/>
    </jaxrs:providers>

    <jaxrs:outInterceptors>
        <ref bean="fastInfosetOutInterceptor"/>
    </jaxrs:outInterceptors>

    <jaxrs:inInterceptors>
        <ref bean="fastInfosetInInterceptor"/>
    </jaxrs:inInterceptors>

    <jaxrs:properties>
        <entry key="org.apache.cxf.endpoint.private" value="true"/>
    </jaxrs:properties>
</jaxrs:server>

<util:list id="fastinfosetType">
    <value>application/fastinfoset</value>
</util:list>

<bean id="jaxbProvider" class="org.apache.cxf.jaxrs.provider.JAXBElementProvider">
    <property name="produceMediaTypes" ref="fastinfosetType"/>
    <property name="consumeMediaTypes" ref="fastinfosetType"/>
</bean>
<bean id="fastInfosetOutInterceptor" class="org.apache.cxf.interceptor.FIStaxOutInterceptor"/>
<bean id="fastInfosetInInterceptor" class="org.apache.cxf.interceptor.FIStaxInInterceptor"/>
{code}

Note

...

that

...

explicitly

...

registering

...

the

...

interceptors

...

is

...

not

...

required

...

anymore

...

given

...

that

...

CXF

...

FastInfoset

...

and

...

Feature

...

annotations

...

are

...

also

...

currently

...

supported.

...