remove null value field from apache cxf REST respo

2019-05-13 19:27发布

问题:

I'm using apache-cxf 2.7.11 + jackson (codehaus) 1.9.13 + spring 3.5 in my REST services web-container. I was wondering what would be the best way to remove null value fields from REST responses.

For example:
My response is now like this:

{
 "name": "MyName",
 "age": 10,
 "address": null
}

I want my response to be like this (the address field has been removed):

{
 "name": "MyName",
 "age": 10
}

I've read about apache-cxf interceptors and filters here:

  • http://cxf.apache.org/docs/jax-rs-filters.html
  • http://cxf.apache.org/docs/jax-rs-data-bindings.html

and wondering what is the best practice? is there any configurable setting that I can change instead of implementing my own filer or interceptor class?

I'm using beans.xml file for configuration, thus I'm looking on how to config it all here, where my beans are:

<bean id="jaxrsRestJacksonObjectMapper" class="org.codehaus.jackson.map.ObjectMapper"/>

<bean id="jsonProvider" class="org.codehaus.jackson.jaxrs.JacksonJsonProvider">
    <property name="mapper" ref="jaxrsRestJacksonObjectMapper"/>
</bean>


<jaxrs:server id="restContainer" address="/">
        <jaxrs:serviceBeans>

        </jaxrs:serviceBeans>
        <jaxrs:providers>
            <ref bean="jsonProvider"/>
        </jaxrs:providers>

</jaxrs:server>

Cheers!

回答1:

Found it!
This is the answer I was looking for:

see the updated beans.xml file:

<bean id="jacksonObjectMapper" class="org.codehaus.jackson.map.ObjectMapper">
    <property name="serializationInclusion" value="NON_NULL"/>
</bean>

<bean id="jsonProvider" class="org.codehaus.jackson.jaxrs.JacksonJsonProvider">
    <property name="mapper" ref="jacksonObjectMapper"/>
</bean>


回答2:

You could add

@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL) 

on top of your POJO class. This would ignore the null fields for that one class.

Or you could configure the ObjectMapper so it would apply globally

ObjectMapper mapper = new ObjectMapper();
mapper.setSerializationInclusion(JsonSerialize.Inclusion.NON_NULL);

If you go with the latter, you can pass the ObjectMapper as a constructor arg to the JacksonJsonProvider or JacksonJaxbJsonProvider (whichever one you are currently using)


UPDATE

You could also use a ContextResolver as seen here, and register the ContextResolver like you would any other provider. This will work better more complicated configurations. You might want to do that instead. With the ContextResolver, you don't need to configure the ObjectMapper with the JacksonJsonProvider, but you still do need the JacksonJsonProvider.