2

I have a use-case where I need to maintain two sets of JSON output, one with pretty names for the JSON property and one without. So I decided to customize my ObjectMapper so that it ignores the @JsonProperty("pretty name") annotation on the fields and uses the field property names. In this case would like the following JSON output

{"result":{"data":[{"totalUsers":12345,"totalBooks":883}]}} 

The JSON output with pretty names would like like follows

{"result":{"data":[{"Total Users":12345,"Total Books":883}]}} 

My ObjectMapper configuration code looks like

ObjectMapper mapper = new ObjectMapper(); mapper.setSerializationInclusion(Include.NON_EMPTY); mapper.setSerializationInclusion(Include.NON_NULL); mapper.configure(MapperFeature.USE_WRAPPER_NAME_AS_PROPERTY_NAME, true); mapper.configure(SerializationFeature.WRAP_ROOT_VALUE, true); mapper.configure(MapperFeature.USE_ANNOTATIONS, false); mapper.setVisibility(PropertyAccessor.FIELD, Visibility.NONE) .setVisibility(PropertyAccessor.GETTER, Visibility.ANY); 

I have looked at a few other answers on SO which didn't work for me. I get an NPE. Please see the following stacktrace

java.lang.NullPointerException at com.fasterxml.jackson.databind.introspect.POJOPropertiesCollector._renameWithWrappers(POJOPropertiesCollector.java:728) at com.fasterxml.jackson.databind.introspect.POJOPropertiesCollector.collect(POJOPropertiesCollector.java:264) at com.fasterxml.jackson.databind.introspect.BasicClassIntrospector.collectProperties(BasicClassIntrospector.java:142) at com.fasterxml.jackson.databind.introspect.BasicClassIntrospector.forSerialization(BasicClassIntrospector.java:68) at com.fasterxml.jackson.databind.introspect.BasicClassIntrospector.forSerialization(BasicClassIntrospector.java:11) at com.fasterxml.jackson.databind.SerializationConfig.introspect(SerializationConfig.java:490) at com.fasterxml.jackson.databind.ser.BeanSerializerFactory.createSerializer(BeanSerializerFactory.java:131) at com.fasterxml.jackson.databind.ser.SerializerFactory.createSerializer(SerializerFactory.java:53) at com.fasterxml.jackson.databind.SerializerProvider._createUntypedSerializer(SerializerProvider.java:935) at com.fasterxml.jackson.databind.SerializerProvider._createAndCacheUntypedSerializer(SerializerProvider.java:892) at com.fasterxml.jackson.databind.SerializerProvider.findValueSerializer(SerializerProvider.java:429) at com.fasterxml.jackson.databind.SerializerProvider.findTypedValueSerializer(SerializerProvider.java:520) at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:99) at com.fasterxml.jackson.databind.ObjectWriter.writeValue(ObjectWriter.java:457) at com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider.writeTo(JacksonJsonProvider.java:583) at org.apache.cxf.jaxrs.utils.JAXRSUtils.writeMessageBody(JAXRSUtils.java:1173) at org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor.serializeMessage(JAXRSOutInterceptor.java:259) at org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor.processResponse(JAXRSOutInterceptor.java:155) at org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor.handleMessage(JAXRSOutInterceptor.java:86) at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:271) at org.apache.cxf.interceptor.OutgoingChainInterceptor.handleMessage(OutgoingChainInterceptor.java:77) at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:271) at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121) at org.apache.cxf.transport.http.AbstractHTTPDestination.invoke(AbstractHTTPDestination.java:238) at org.apache.cxf.transport.servlet.ServletController.invokeDestination(ServletController.java:222) at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:163) at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:137) at org.apache.cxf.transport.servlet.CXFNonSpringServlet.invoke(CXFNonSpringServlet.java:158) at org.apache.cxf.transport.servlet.AbstractHTTPServlet.handleRequest(AbstractHTTPServlet.java:239) at org.apache.cxf.transport.servlet.AbstractHTTPServlet.doGet(AbstractHTTPServlet.java:164) 

The problem is in this line of code in at

com.fasterxml.jackson.databind.introspect.POJOPropertiesCollector._renameWithWrappers(POJOPropertiesCollector.java:728) 

where _annotationIntrospector is null

PropertyName wrapperName = _annotationIntrospector.findWrapperName(member); 

Not quite sore what should I do to acheieve my goal. Any advice? Thanks.

4
  • 1
    Just a thought: Did you consider to use mixin-annotations for the pretty printed JSON instead? (Maybe I find time tomorrow to look into your actual problem.) Commented Mar 6, 2013 at 19:42
  • I did a short test and obviously mapper.configure(MapperFeature.USE_ANNOTATIONS, false); clashes with mapper.configure(MapperFeature.USE_WRAPPER_NAME_AS_PROPERTY_NAME, true); and mapper.setVisibility(PropertyAccessor.FIELD, Visibility.NONE).setVisibility(PropertyAccessor.GETTER, Visibility.ANY);. Right now I cannot think of an easy way to fix that without messing around with Jackson's library. For another approach to solve your use-case look into my previous post. Commented Mar 8, 2013 at 9:08
  • @nutlike- Thanks. No I have not tried mixin-annotations, but will give them a go. Commented Mar 8, 2013 at 15:30
  • Added a small example as answer, I hope it helps you to get started. Commented Mar 8, 2013 at 15:44

1 Answer 1

3

Small example to show a solution for your use-case with mixins:

class Data { int totalUsers; int totalBooks; } 

class DataMixin { @JsonProperty("Total Users") int totalUsers; @JsonProperty("Total Books") int totalBooks; } 

Jackson 2.0 - 2.4 (deprecated in 2.5)

ObjectMapper mapper = new ObjectMapper(); if (pretty) { mapper.addMixInAnnotations(Data.class, DataMixin.class); } 

Jackson 2.5+

ObjectMapper mapper = new ObjectMapper(); if (pretty) { mapper.addMixin(Data.class, DataMixin.class); } 
Sign up to request clarification or add additional context in comments.

2 Comments

Interestingly when I tried to use the example given on wiki.fasterxml.com/JacksonMixInAnnotations for this i.e setting it in a Module and using a SetUpContext. It didn't work for me. But I tried something simillar to the example you posted and it worked i.e not using the Module and just using mapper.addMixInAnnotations
Remember that you have to register the Module for Jackson to see it, i.e., use objectMapper.registerModule(new MyMixInModule());

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.