My Wiki!

Rest Jax-RS

Sample

Basic

JAXB - JAX-RS

JAX-RS Concepts

Entity Providers

These providers control the mapping of data representations (like XML, JSON, CSV) to their Java object equivalents.

Context Providers

These providers control the context that resources can access via @Context annotations.

Exception Providers

These providers control the mapping of Java exceptions to a JAX-RS Response instance.

public interface Providers {
  <T> MessageBodyReader<T> getMessageBodyReader(Class<T> type, Type genericType, Annotation annotations[], MediaType mediaType);
  <T> MessageBodyWriter<T> getMessageBodyWriter(Class<T> type, Type genericType, Annotation annotations[], MediaType mediaType);
  <T extends="" throwable=""> ExceptionMapper<T> getExceptionMapper(Class<T> type);
  <T> ContextResolver<T> getContextResolver(Class<T> contextType, MediaType mediaType);
}
@Path("/something/")
class MyResource {
    @Context
    javax.ws.rs.ext.Providers providers;

    @GET
    public Response get() {
        ContextResolver<StorageEngine> resolver = providers.getContextResolver(StorageEngine.class, MediaType.WILDCARD_TYPE);
        StorageEngine engine = resolver.get(StorageEngine.class);
        ...
    }
}

JAX-RS Request Processing

JSON Support

Polymorphic resolution without annotations

1. Configure Jackson object mapper in CXF Provider

2.2 CXF vs Jersey and Jackson - Explaination

3. ObjectMapperResolver

4. Custom ObjectMapper for Provider

4.1 Add Jackson maven dependency

<dependency>
    <groupId>org.codehaus.jackson</groupId>
    <artifactId>jackson-jaxrs</artifactId>
    <version>1.9.7</version>
</dependency> 

4.2 Include Jackson provider bean into your service providers:

<bean id="jsonProvider" class="org.codehaus.jackson.jaxrs.JacksonJsonProvider"/>
<jaxrs:server id="clientService" address="/clientservice">
        <jaxrs:serviceBeans>
            <ref bean="clientBean" />
        </jaxrs:serviceBeans>
        <jaxrs:extensionMappings>
            <entry key="json" value="application/json"/>
            <entry key="xml" value="application/xml"/>
        </jaxrs:extensionMappings> 
        <jaxrs:providers>
            <ref bean="jaxbProvider"/>
        </jaxrs:providers>
 </jaxrs:server>

Now all JSON responces from “clientService” are generated by Jackson.

4.3 Jackson configuration

Enable wrapping entities with root element. Exclude null values from JSON responce. This features are disabled by default. To enable it I created my custom ObjectMapper class, that extends from “org.codehaus.jackson.map.ObjectMapper”

import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.SerializationConfig;
import org.codehaus.jackson.map.annotate.JsonSerialize;

public class CustomObjectMapper extends ObjectMapper{

    public CustomObjectMapper() {
    super();
    super.configure(SerializationConfig.Feature.WRAP_ROOT_VALUE, true);
    super.setSerializationInclusion(JsonSerialize.Inclusion.NON_NULL);
    }

}

4.4 Then added CustomObjectMapper to "jsonProvider" constructor:

<bean id="jacksonMapper" class="com.xproject.server.util.CustomObjectMapper" />
<bean id="jaxbProvider" class="org.codehaus.jackson.jaxrs.JacksonJsonProvider">
        <constructor-arg ref="jacksonMapper" />
 </bean>

5. Fasterxml Polymorphic Type Handling

5.1 Custom Ser/Deser

Jax-RS WebClient

Troubleshooting

Proxy Webclient: service is not an interface

Problem:

Rest service class is not interface so CGLIB proxy will be created by JAXRSClientFactory.

https://cxf.apache.org/javadoc/latest/org/apache/cxf/jaxrs/client/JAXRSClientFactory.html

Solution:

Add this to class path

<dependency>
      <groupId>cglib</groupId>
      <artifactId>cglib-nodep</artifactId>
      <version>2.2.2</version>
</dependency>

WebClient Error 400 JAXB expected..

Error: JAXBException occurred : unexpected element (uri:“”, local:“headers”)

Cause:

xmlrootelement is serialized as wrapper element for json object. CXF JAXB always expects it but some clients only send the object.

Solution:

Ignoring the tags may not works correctly. As suggested: https://stackoverflow.com/a/16390260/707704 . The answers above give more information.

private static JacksonJsonProvider jackson_json_provider = new JacksonJaxbJsonProvider()
  .configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false)

Navigation