`
fcxx182
  • 浏览: 28784 次
  • 性别: Icon_minigender_1
  • 来自: 苏州
社区版块
存档分类
最新评论

apache cxf在线阅读(http://cxf.apache.org/docs/jax-rs.html)

阅读更多
     
    Apache CXF   

Apache CXF Documentation > Index > RESTful Services > JAX-RS  Download | Documentation

    
  Overview
How-Tos
Frontends
DataBindings
Transports
Configuration
Debugging and Logging
Tools
RESTful Services
WSDL Bindings
Service Routing
Dynamic Languages
WS-* Support
Advanced Integration
Deployment
Use of Schemas and Namespaces

--------------------------------------------------------------------------------

API (Javadoc)
CXF Website
JAX-RS (JSR-311)
Introduction
Migrating from 0.8 to 1.0
Maven dependencies
Setting up the classpath in Eclipse or Ant
CXF JAX-RS bundle
Understanding the basics
Resource class
@Path
HTTP Method
Return types
Exception handling
Dealing with Parameters
Parameter beans
Resource lifecycles
Overview of the selection algorithm.
Selecting between multiple resource classes
Selecting between multiple resource methods
Resource methods and media types
Custom selection between multiple resources
Context annotations
URIs calculation using UriInfo and UriBuilder
Annotation inheritance
Sub-resource locators.
Static resolution of subresources
Message Body Providers
Custom Message Body Providers
Registering custom providers
Customizing media types for message body providers
Support for data bindings
JAXB support
Configuring JAXB provider
JSON support
Configuring JSON provider
Dealing with JSON array serialization issues
BadgerFish convention
Wrapping and Unwrapping JSON sequences
Automatic JAXBElement conversion during serialization
Handling JAXB beans without XmlRootElement annotations
Handling explicit collections
Customizing JAXB XML and JSON input and output
Aegis Data Binding
XMLBeans
Support for CXF DataBindings
Schema validation support
Debugging
Logging
ATOM push-style logging
Spring configuration
Properties file
Programming style
Filters
Difference between JAXRS filters and CXF interceptors
Overriding request and response properties
Overriding HTTP method
Overriding request URI
Overriding response status code and headers
Ignoring JAXRS MessageBodyWriters
Custom invokers
Advanced HTTP
Support for Continuations
Secure JAX-RS services
Checking HTTP security headers
SecurityManager and IllegalAccessExceptions
Client API
Proxy-based API
Customizing proxies
Converting proxies to Web Clients and vice versa
Handling exceptions
Configuring proxies in Spring
Injecting proxies
Limitations
HTTP-centric clients
Handling exceptions
Configuring HTTP clients in Spring
XML-centric clients
Configuring Clients at Runtime
Configuring HTTP Conduit from Spring
XPath and XSLT
XPath support
XSLT support
Redirection
With RequestDispatcherProvider
With CXFServlet
Custom Redirection
Model-View-Controller support
XSLT
JSP
Support for Multiparts
Reading attachments
Forms and multiparts
Writing attachments
Uploading files
Reading large attachments
Service listings and WADL support
Documenting resource classes and methods in WADL
Configuring JAX-RS services
Configuring JAX-RS services programmatically can create a JAX-RS RESTful service by using JAXRSServerFactoryBean from the cxf-rt-frontend-jaxrs package:
Configuring JAX-RS endpoints programmatically without Spring
Configuring JAX-RS clients programmatically without Spring
Configuring JAX-RS services in container with Spring configuration file.
web.xml
Using Spring ContextLoaderListener
Using CXFServlet init parameters
beans.xml
Configuring JAX-RS services in container without Spring
Attaching JAXRS endpoints to an existing Jetty server
Configuring JAX-RS services programmatically with Spring configuration file.
Lifecycle management
From Spring
With CXFNonSpringJaxrsServlet
Programmatically
PostConstruct and PreDestroy
Locating custom resources in web applications
Multiple endpoints and resource classes
How the request URI is matched against a given jaxrs endpoint
Combining JAX-WS and JAX-RS
Dealing with contexts
JAX-RS and Spring AOP
RESTful services without annotations
Configuration
Integration with Distributed OSGi
How to contribute
Introduction
CXF supports JAX-RS (JSR-311), Java API for RESTful Web Services. JAX-RS provides a more standard way to build RESTful services in Java. CXF 2.2.x supports the final version of JSR-311 API while CXF 2.1.x supports the 0.8 version of JSR-311 API .

JAX-RS related demos are located under samples/jax_rs directory (CXF 2.2 and CXF 2.1 only).
This documentation will refer to JSR-311 API 1.0 .

Migrating from 0.8 to 1.0
The following major changes in 1.0 will most likely affect users migrating from 0.8

@ProduceMime and @ConsumeMime have been replaced with @Produces and @Consumes respectively
HttpHeaders has had some of its methods returning a string representation of Locale updated to return Locale instead
As JAX-RS API 1.0 is currently supported in CXF 2.2.x, it's also worth noting of the following changes in dependencies :

Spring version have changed from 2.0.8 in 2.1.x to 2.5.6
jaxb-api version has changed to javax.xml.bind/jaxb-api/2.1
jaxb-impl version has changed to com.sun.xml.bind/jaxb-impl/2.1.7
Additionally, org.apache.cxf/cxf-rt-databinding-aegis/2.2.x compile-time dependency has been added

Maven dependencies
To incorporate JAX-RS, you will need:

   <dependency>
      <groupId>org.apache.cxf</groupId>
      <artifactId>cxf-rt-frontend-jaxrs</artifactId>
      <version>2.2.3</version>
   </dependency>

This will in turn pull in the following 3rd-party dependencies are used when building CXF JAX-RS implementation :

1. javax.ws.rs/jsr311-api/1.0

available from either

<repository>
    <id>java.net.2</id>
    <name>Java Net 2 Repository</name>
    <url>http://download.java.net/maven/2</url>
</repository>

or from a central maven repository

2. org.apache.abdera groupId : abdera-core, abdera-parser and abdera-extensions-json artifacts, version 0.4.0-incubating. It's a compile time dependency. Available from


<repository>
    <id>apache.incubating</id>
    <name>Apache Incubating Repository</name>
    <url>http://people.apache.org/repo/m2-incubating-repository</url>
</repository>

3. org.springframework/spring-core/2.5.6

4. org.codehaus.jettison/jettison/1.1

5. org.apache.xmlbeans/xmlbeans/2.3.0 - compile time

Please check the pom.xml for the list of cxf components used by the JAX-RS implementation. Snapshots are available from http://repository.apache.org/snapshots/org/apache/cxf/apache-cxf/

Setting up the classpath in Eclipse or Ant
If no Maven is used then the following jars need to be available at the runtime classpath :

cxf-2.3.0-SNAPSHOT.jar
jsr311-api-1.0.jar
jaxb-impl-2.1.12.jar
jaxb-api-2.1.jar
geronimo-annotation_1.0_spec-1.1.1.jar
geronimo-activation_1.1_spec-1.0.2.jar
geronimo-servlet_2.5_spec-1.2.jar
commons-logging-1.1.1.jar
geronimo-stax_api_1.0_spec-1.0.1.jar
woodstox-core-asl-4.0.3.jar
stax2-api-3.0.1.jar
geronimo-jaxws_2.1_spec-1.0.jar
wsdl4j-1.6.2.jar
XmlSchema-1.4.5.jar
neethi-2.0.4.jar
For CXF 2.2.3 (2.2.4-SNAPSHOT) :

add cxf-2.2.3.jar (or cxf-2.2.4-SNAPSHOT.jar) instead of cxf-2.3.0-SNAPSHOT.jar
do not add stax2-api-3.0.1.jar
add wstx-asl-3.2.8.jar instead of woodstox-core-asl-4.0.3.jar
add saaj-api-1.3.jar
If Spring configuration is used then add spring.jar from the Spring distribution or the spring jars available in the CXF distribution. When creating client proxies from concrete classes the cglib-nodep-2.1_3.jar needs to be added. You do not need to add JAXB libraries if you do not use JAXB. If you depend on Jetty then you will also need to add two jetty jars shipped with CXF.

We will work on reducing the set of required dependencies.
Please see the configuration sections below on how a spring dependency can be dropped.

CXF JAX-RS bundle
A standalone JAX-RS bundle is now available which may be of interest to users doing JAX-RS work only.

Understanding the basics
You are encouraged to read JAX-RS spec to find out information not covered by this documentation.

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 at least with a @Path annotation, while subresource classes typically have no root @Path values. A typical root resource class in JAX-RS looks like this below:

package demo.jaxrs.server;

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) {
       ......
    }
}

Customer resource class can handle requests starting from /customerservice. When /customerservice request is 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.

@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, only it's 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
@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 :

@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) {
        ......
    }
}


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
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 :

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 {
}

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 :

@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);
    }

}

Yet another option is to register an ExceptionMapper provider. Ex :

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

This allows to throw 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 propogated (wrapped in ServletException) to the underlying container as required by the specification. Thus one option for intercepting the exceptions is to register a custom servlet filter which will catch ServletExceptions and handle the causes. If no custom servlet filter which can handle ServletExceptions is available then most likely only 500 error status will be reported.

This propogation can be disabled by registering a boolean jaxrs property 'org.apache.cxf.propogate.exception' with a false value. If such property is set and no exception mapper can be found for a given exception then it will be wrapped into an xml error response by the CXF 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.

Dealing with Parameters
PathParam annotation is used to map a given Path template variable to a method parameter.
For example :


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

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

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 :


public enum Gender {
   MALE,
   FEMALE;

   public static 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) {
        ...
    }
}

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 :

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) {
        ...
    }
}

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.

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 :


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


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 :

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

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.

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

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

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 ex :


@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) {...} 
}




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 :

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);
}

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 the construction time :

@Path("/")
public class PerRequestResourceClass {

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

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

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.

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

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.

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

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.

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

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

@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; }

}

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 :

@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) {...}

}

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 :

@Path("/")
public class Test1 {

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

}

TODO : more info

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

Starting from CXF 2.2.5 it is possible to register a custom ResourceComparator implementation using a jaxrs:server/resourceComparator element.

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.

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 the future ones) and also lets check the current message's properties.

Example :

@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();
    }
}


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.

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

@Path("/customers")
public class CustomerService {

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

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

}

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

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>

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

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>

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

The core part of solution is to use injected UriInfo object. Method "getCustomers" has to have UriInfo object injected. This helper object allows to extract some useful information about current URI context, but what's more important, allow to get UriBuilder object. UriBuilder has multiple appender methods that extends final URI it can build; in our case to current URI we can append path in multiple ways, providing it as string (which we actually want to avoid here) or providing resource (class or method) to extract @Path value. Finally UriBuilder that is composed of paths with templates (variables) must have variables bound to values to render URI. This case in action looks like this:

@Path("/customers")
public class CustomerService {

    @GET
    public Customers getCustomers(@Context UriInfo ui) {
        ......
        // builder starts with current URI and has appended path of getCustomer method
        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) {
        ......
    }

}

Annotation inheritance
Most of the JAX-RS annotations can be inherited from either an interface or a superclass. For example :


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);
    }

}

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

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:

@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() {
       ......
    }

}

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 is returned.
The request to http://localhost:9000/customerservice/orders/223/products/323/items will be delivered to getItems() method which in turn will delegate to an overloaded getItems().

Note that a subresource class like Order is 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, similarly to Order.getItems() 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 :

@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) {...}
}


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 :

<beans>
<jaxrs:server staticSubresourceResolution="true">
<!-- more configuration -->
</jaxrs:server>
</beans>

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 a "Support for data bindings" section below.

Custom Message Body Providers
It's likely that a given application may need to deal with types which are not supported by default.
Alternatively, developers may want to provide a more efficient support for handling default types such as InputStream.

Here's an example of a custom MessageBodyReader for InputStream :


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


and here's an example of a custom MessageBodyWriter for Long :


@ProduceMime("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());
       
    }


CXF ships some custom providers too. These are providers 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 the Spring configuration or programmatically :


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

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 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 ex, 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 :


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

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.

Support for data bindings
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:

@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;
    }
}

In the example below, the Customer object returned by getCustomer is marshaled using JAXB data binding:

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

The wire representation of Customer object is:

<Customer>
    <id>123</id>
    <name>John</name>
</Customer>

The simplest way to work with the collections is to define a type representing a collection. For example:

@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() {
        ....
    }
}

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

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 :

<beans xmlns:util="http://www.springframework.org/schema/util">
<bean id="jaxbProvider" class="org.apache.cxf.jaxrs.provider.JAXBElementProvider">
<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>

Individual marshal properties can be injected as simple properties. At the moment, Marshaller.JAXB_SCHEMA_LOCATION can be injected as "schemaLocation" property. 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 Support" 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'

Marshall, unmarshall and context properties can be configured as well for both JAXB and JSON providers.

JSON support
Default JSON provider relies on Jettison 1.1 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.

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

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

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

<beans xmlns:util="http://www.springframework.org/schema/util">
<bean id="jaxbProvider" class="org.apache.cxf.jaxrs.provider.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>

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 Support" sections for more information.

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 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 :

@XmlRootElement()
@XmlType(name = "", propOrder = {"title", "comments" })
public static class Post {
    private String title;
    private List<Comment> comments = new ArrayList<Comment>();
    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;
     }
}

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 lets 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.

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.

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.

Note that this property is supported for both JAXB and JSON providers.

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 :

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

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 Dojo 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.

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:
> book:thebook - change "book" to "thebook"
> {http://books}book:book - drop the namespace from "book"
> book:{http://books}thebook - change "book" to a different qualified name

"inTransformElements" map property : can be used to change the input element names and change or drop namespaces; see "outElementsMap"
"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:
> book:thebook - append "book" before "thebook"
> {http://books}book:book - append the namespace to the "book"
> book:{http://books}book - drop the namespace from the "book"

"inAppendElements" map property : can be used to append new simple or qualified elements to the input; see "outAppendMap"
"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:
> index, {http://numbers}number - drop "index" and {http://numbers}number elements

"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.
"attributesAsElements" boolean property : can be used to have attributes be serialized as elements.
The combination of "attributesAsElements" and "outDropElements" properties can be used to have certain attributes ignored in the output.

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}}".

// TODO : add more examples

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

Support for CXF DataBindings
Starting from CXF 2.2.3 it is now 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, Aegis, SDO and XMLBeans databindings can be easily plugged in.
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.

Note that at the moment this feature is only available on the trunk. JAXB and Aegis DataBindings (XML only) is supported in CXF 2.2.3.

Schema validation support
There're two ways you can enable a schema validation.

1. Using jaxrs:schemaLocations element :

<beans xmlns:util="http://www.springframework.org/schema/util">
<jaxrs:server address="/">
  <jaxrs:schemaLocations>
     <jaxrs:schemaLocation>classpath:/schemas/a.xsd</jaxrs:schemaLocation>
     <jaxrs:schemaLocation>classpath:/schemas/b.xsd</jaxrs:schemaLocation>
  </jaxrs:schemaLocations>
</jaxrs:server>
/<beans>

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) called. 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 presumably importing a.xsd

2. Configuring providers individually

Please see this example of how both JAXB and JSON providers are using a shared schema validation configuration.

Debugging
One can easily try from a browser how a given resource class reacts to different HTTP Accept or Accept-Language header values.
For example, if a resource class supports "/resource" URI then one can test the resource class using one of the following
queries :

GET /resource.xml
GET /resource.en

The runtime will replace '.xml' or '.en' with an appropriate header value. For it to know the type or language value associated with
a given URI suffix, some configuration needs to be done. Here's an example how to do it in Spring :


  <jaxrs:server id="customerService" address="/">
    <jaxrs:serviceBeans>
      <ref bean="customerService" />
    </jaxrs:serviceBeans>
    <jaxrs:extensionMappings>
      <entry key="json" value="application/json"/>
      <entry key="xml" value="application/xml"/>
    </jaxrs:extensionMappings>
    <jaxrs:languageMappings/>
  </jaxrs:server>

See below for a more complete configuration example.

See the JAX-RS specification for more details.

CXF also supports _type query as an alternative to appending extensions like '.xml' to request URIs :

GET /resource?_type=xml

Logging
Existing CXF features can be applied to jaxrs:server or jaxrs:client, whenever it makes sense.
To enable logging of requests and responses, simply do :

<beans xmlns:cxf="http://cxf.apache.org/core"
xsi:schemaLocation="http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd">
<jaxrs:server>
<jaxrs:features>
     <cxf:logging/>
</jaxrs:features>
<jaxrs:server>
</beans>

Please make sure a "http://cxf.apache.org/core" namespace is in scope.

ATOM push-style logging
This feature is under development and is available in 2.2.6-SNAPSHOT. Changes will appear without notice.

Since 2.2.6 CXF supports collecting log events, converting them to ATOM Syndication Format and pushing to the client. Logging is based on custom java.util.logging (JUL) handler that can be registered with loggers extending today's publishing protocols.

Push-style handler enqueues log records as they are published from loggers. After the queue size exceeds configurable "batch size", processing of collection of these records (in size of batch size) is triggered. Batch of log events is transformed by converter to ATOM element and then it is pushed out by deliverer to client. Both converter and deliverer are configurable units that allow to change transformation and transportation strategies. Next to predefined own custom implementations can be used when necessary – see examples. Batches are processed sequentially to allow clien
分享到:
评论

相关推荐

    cxf.apache.org/schemas/(jaxrs.xsd、jaxrs.xsd、core.xsd)文件下载

    CXF和Spring整合时,配置文件中所需要的CXF标签的 schema 文件,将所需的xsd文件配置到本地,可以解决部分IDE在编写配置文件时,无法自动提示的问题。

    cxf-rt-frontend-jaxrs-3.0.1-API文档-中文版.zip

    Maven坐标:org.apache.cxf:cxf-rt-frontend-jaxrs:3.0.1; 标签:cxf、jaxrs、rt、apache、frontend、jar包、java、API文档、中文版; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览...

    CXFWS-Security

    http://cxf.apache.org/docs/ws-security.html http://resource.ajava.org/java/jdk-6.0-api-zh/javax/security/auth/callback/CallbackHandler.html 2)CXFWS工程是基于WS-Security规范,实现X.509身份验证的,...

    cxf.xml,cxf-servlet.xml,cxf-extension-soap.xml

    &lt;import resource="classpath:META-INF/cxf/cxf.xml"/&gt; &lt;import resource="classpath:META-INF/cxf/cxf-extension-soap.xml"/&gt; &lt;import resource="classpath:META-INF/cxf/cxf-servlet.xml"/&gt;

    apache-cxf-2.4.6.zip

    apache-cxf-2.4.6.zip

    apache-cxf-2.7.6.rar

    apache-cxf-2.7.6.rar webservice

    apache-cxf-2.6.1.zip

    apache-cxf-2.6.1.zip cxf转化wsdl文件,生成javaBean实体类 附上使用文章:http://blog.csdn.net/sinat_34979884/article/details/78776305

    apache-cxf-3.2.8.zip

    集成soapUI快速生成客户端,CXF 继承了 Celtix 和 XFire 两大开源项目的精华,提供了对 JAX-WS 全面的支持,并且提供了多种 Binding 、DataBinding、Transport 以及各种 Format 的支持,并且可以根据实际项目的需要...

    apache-cxf-3.5.0.zip

    Apache CXF 是一个开放源代码框架,提供了用于方便地构建和开发 Web 服务的可靠基础架构。

    apache-cxf-2.2.3.zip

    apache-cxf-2.2.3.zip java webservice 框架 内有 demo

    webServiceSprin整合jar包apache-cxf-2.5.9.rar

    其他新版本的jar包请到官网:http://cxf.apache.org/download.html下载

    apache-cxf-2.2.10(A)

    apache-cxf-2.2.10所有的jar,无需在一个一个的去找了。cxf.jar commons-logging.jar neethi.jar jaxb-api.jar jaxb-impl.jar stax-api.jar 由于上传大小有限无法一次性传全部,在这分为2次上传。 apache-cxf-2.2.10...

    cxf-manifest.jar

    webservice CXF 报错:java.lang.NoClassDefFoundError: org/apache/neethi/builders/AssertionBuilder 需要用到此jar文件 通过apache官网可获得。 文件位置\apache-cxf-2.7.13\lib

    cxf-rt-rs-client-3.0.1-API文档-中文版.zip

    Maven坐标:org.apache.cxf:cxf-rt-rs-client:3.0.1; 标签:cxf、rt、apache、client、jar包、java、API文档、中文版; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性...

    apache-cxf-3.0.7.zip

    原地址:http://www.apache.org/dyn/closer.lua/cxf/3.0.7/apache-cxf-3.0.7.zip

    cxf-rt-rs-extension-providers-3.0.1-API文档-中文版.zip

    Maven坐标:org.apache.cxf:cxf-rt-rs-extension-providers:3.0.1; 标签:cxf、rt、extension、apache、providers、jar包、java、API文档、中文版; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”...

    cxf-rt-transports-http-3.0.1-API文档-中文版.zip

    Maven坐标:org.apache.cxf:cxf-rt-transports-http:3.0.1; 标签:cxf、transports、rt、apache、http、jar包、java、API文档、中文版; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览...

    apache-cxf-2.2.10(B)包含api

    apache-cxf-2.2.10所有的jar,无需在一个一个的去找了。cxf.jar commons-logging.jar neethi.jar jaxb-api.jar jaxb-impl.jar stax-api.jar 由于上传大小有限无法一次性传全部,在这分为2次上传。 apache-cxf-2.2.10...

    apache-cxf-3.1.6

    apache-cxf-3.1.6

    cxf-rt-frontend-simple-3.0.1-API文档-中文版.zip

    Maven坐标:org.apache.cxf:cxf-rt-frontend-simple:3.0.1; 标签:cxf、rt、apache、simple、frontend、jar包、java、API文档、中文版; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览...

Global site tag (gtag.js) - Google Analytics