Override Jackson object's Mapper properties on Websphere 8.5.5 using Apache Wink

We use IBM in the Apache Wink bundle to offer JAXRS endpoints for our application. We code for Websphere 8.5.5. Since we are compatible with servlets 3.0, we use the β€œsoftware” way to configure the JaxRS application, which means there are no entries in web.xml, and we rely on class scanning for jax rs annotated resources. All in all, it works great.

@ApplicationPath("/api/v1/") public class MyApplication extends Application{ 

This version of Websphere, along with Apache Wink, uses Jackson 1.6.x for JSON de / serialization and generally works well. We would like to at least change some default values ​​for Object Mapper

Thus, we defined a client permission context that simply changed some se / deserialzation properties.

 @Provider @Produces(MediaType.APPLICATION_JSON) public class CustomJackssonConverter implements ContextResolver<ObjectMapper> { final ObjectMapper defaultObjectMapper; public AibasJackssonConverter() { defaultObjectMapper = createDefaultMapper(); } ... mapper.getSerializationConfig().set(SerializationConfig.Feature.INDENT_OUTPUT, true); 

During JAX-RS calls, we see that the container registers a new provider, without errors

The problem is that the Configuration does not β€œfollow”, from the logs I can see that the Wink Engine is looking for the WinkJacksonProvider, which in turn returns JacksonProvider, which follows the default values ​​of Jackson (s)

Is there any way to change this default value?

I tried to change the implementation of the application object, as indicated here, to programmatically configure the providers, but this did not work.

http://www.ibm.com/developerworks/java/library/wa-aj-jackson/index.html

Any clues or hints?

Thank you very much

+6
source share
2 answers

I solved this problem by simply executing the MessageBodyWriter class, for example:

 import java.io.IOException; import java.io.OutputStream; import java.lang.annotation.Annotation; import java.lang.reflect.Type; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.ext.MessageBodyWriter; import javax.ws.rs.ext.Provider; import org.codehaus.jackson.map.ObjectMapper; import org.codehaus.jackson.map.SerializationConfig; @Provider @Produces(MediaType.APPLICATION_JSON) public class DefaultMessageBodyWriter implements MessageBodyWriter<Object> { @Override public long getSize(Object object, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) { return -1; } @Override public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) { return true; } @Override public void writeTo(Object object, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap<String, Object> httpHeaders, OutputStream entityStream) throws IOException { ObjectMapper mapper = new ObjectMapper(); mapper.configure(SerializationConfig.Feature.FAIL_ON_EMPTY_BEANS, false); mapper.writeValue(entityStream, object); } } 

Each time JSON serialization is requested, this class takes effect and finally its writeTo method is called.

Here SerializationConfig.Feature.FAIL_ON_EMPTY_BEANS is turned off by request of WebSphere.

+2
source

I use MOXy instead of Jackson in WAS v8.0.0.x.

To override Jackson, I implement my application class like this:

 @Named @ApplicationScoped @ApplicationPath("/resources/") public class WinkApplication extends Application implements Serializable { private static final long serialVersionUID = 1L; @Override public Set<Class<?>> getClasses() { Set<Class<?>> classes = new HashSet<Class<?>>(); classes.add(WinkResource.class); classes.add(WinkMOXyJsonProvider.class); classes.add(WinkResponseException.class); classes.add(WinkResponseExceptionMapper.class); return classes; } } 

However, I noticed that WAS seems to ignore the following annotation:

 @ApplicationPath("/resources/") 

So, I resorted to using web.xml:

 <!-- Wink Servlet --> <servlet> <description>JAX-RS Tools Generated - Do not modify</description> <servlet-name>JAX-RS Servlet</servlet-name> <servlet-class>com.ibm.websphere.jaxrs.server.IBMRestServlet</servlet-class> <init-param> <param-name>javax.ws.rs.Application</param-name> <param-value>com.company.team.project.webservices.config.WinkApplication</param-value> </init-param> <!-- <init-param> <param-name>propertiesLocation</param-name> <param-value>/WEB-INF/my-wink-properties.properties</param-value> </init-param> --> <load-on-startup>1</load-on-startup> <enabled>true</enabled> <async-supported>false</async-supported> </servlet> <!-- Wink Servlet Mapping --> <servlet-mapping> <servlet-name>JAX-RS Servlet</servlet-name> <url-pattern>/resources/*</url-pattern> </servlet-mapping> 

The fact is, because WAS or Wink ignore the application implementation when using the ApplicationPath annotation, Wink loads the default application class, which Jackson uses by default.

And yes, I read the documentation and even watched IBM videos on the Internet that mentioned that @ApplicationPath avoids XML configuration, however this problem seems to be an error.

UPDATE:

An alternative approach might be what David Blevins mentioned in another SO post.

Check out Using JAX-RS

-1
source

All Articles