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);
...
}
}
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-jaxrs</artifactId>
<version>1.9.7</version>
</dependency>
<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.
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);
}
}
<bean id="jacksonMapper" class="com.xproject.server.util.CustomObjectMapper" />
<bean id="jaxbProvider" class="org.codehaus.jackson.jaxrs.JacksonJsonProvider">
<constructor-arg ref="jacksonMapper" />
</bean>
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>
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)