nil instead of null

classic Classic list List threaded Threaded
10 messages Options
Reply | Threaded
Open this post in threaded view
|

nil instead of null

nbaliga
I annotate my POJOs with JAXB annotations and I had a question about Jersey's behavior when it comes to attributes marked with @XmlElement(nillable = true).

When I use the POJO Mapping Feature, I get, what I think is the correct JSON notation, i.e.

 "attribute":null

However, for various reasons, I am forced to go with the JAXB Context Resolver approach i.e. have a class such that:

class JAXBContextResolver
      implements ContextResolver<JAXBContext>

And in the constructor of said class, I set my JAXBContext instance =

 new JSONJAXBContext( JSONConfiguration.natural().rootUnwrapping( false ).humanReadableFormatting( true ).build(), .... );

By doing so, my understanding is that I am asking Jersey to use Jackson and I get some more control over what it produces. Incidentally, the rootUnwrapping feature is the reason for this approach over POJO Mapping Feature.

Using the above, causes null attributes to show up as:

 "attribute":{"nil":true}

How do I go about getting Jersey to go back to using null instead of nil? I know the default Jackson behavior is to use null and not nil, both from my experimentation with the POJO mapping feature, as well as simple POCs using Jackson directly.

Any help will be greatly appreciated.
Reply | Threaded
Open this post in threaded view
|

Re: nil instead of null

nbaliga
I tried using pure Jackson approach by enabling the POJO Mapping Feature and then creating a ObjectMapper Provider via a ContextResolver.

However due to the mess that Jackson 1.7 and 1.8 is in w.r.t. JAXB Annotation support, that is a dead end.

If I use the POJO Mapping Feature WITHOUT supplying my own ObjectMapper, i.e. using the default that Jersery instantiates, then I lose out on the Root Unwrapping feature wherein the XmlRootElement's name property is ignored.

So, I need to try and find a solution for my JSON  "attribute":{"nil":true} generation problem via Jersey's interface AND using the JAXBContextResolver approach.

So, once again, any help in this area would be appreciated.
Reply | Threaded
Open this post in threaded view
|

Re: nil instead of null

nbaliga
After attaching sources and doing some debugging and stepping through, it looks like the JAXB XML Serializer instructs the Stax2JacksonWriter to write the nil true value.

So Jackson is essentially doing what its told.

Since I want to use JAXB annotations for both JSON and XML generation, cannot use pure Jackson approach, it doesn't look like there's any way out of this situation.

Reply | Threaded
Open this post in threaded view
|

Re: nil instead of null

Cowtowncoder
On Fri, Sep 23, 2011 at 10:42 AM, nbaliga <[hidden email]> wrote:
> After attaching sources and doing some debugging and stepping through, it
> looks like the JAXB XML Serializer instructs the Stax2JacksonWriter to write
> the nil true value.
>
> So Jackson is essentially doing what its told.
>
> Since I want to use JAXB annotations for both JSON and XML generation,
> cannot use pure Jackson approach, it doesn't look like there's any way out
> of this situation.

Not sure if this would help, but Jackson 1.9 has full support for root
element wrapping/unwrapping (including deserialization, not just
serialization). It will be out soon (i.e. within weeks), and the
latest snapshot should allow you to verify its working.

-+ Tatu +-
Reply | Threaded
Open this post in threaded view
|

Re: nil instead of null

nbaliga
I did try using the 1.9 SNAPSHOT in my efforts to incorporate a Jackson provider in my Jersey project.

However, and I double checked this morning, the root unwrapping feature doesn't work for me. I still get the Java name of the root variable instead of the XmlRootElement name attribute value.

I think this is a side effect of the fact that Jackson seems to be ignoring the JAXB annotations altogether, because the propOrder of the elements is also being ignored.

Here are the options I'm configuring my ObjectMapper with:
     
      objectMapper = new ObjectMapper();

      objectMapper.configure( SerializationConfig.Feature.WRAP_ROOT_VALUE, true );

      objectMapper.configure( SerializationConfig.Feature.INDENT_OUTPUT, false );

      objectMapper.configure( SerializationConfig.Feature.USE_ANNOTATIONS, true );

      objectMapper.configure( JsonGenerator.Feature.WRITE_NUMBERS_AS_STRINGS, false );

      objectMapper.configure( DeserializationConfig.Feature.USE_ANNOTATIONS, true );


      final AnnotationIntrospector introspector = new JaxbAnnotationIntrospector();

      // make serializer use JAXB annotations (only)
      objectMapper.getSerializationConfig().withAnnotationIntrospector( introspector );

      // make deserializer use JAXB annotations (only)
      objectMapper.getDeserializationConfig().withAnnotationIntrospector( introspector );

I toggled the INDENT_OUTPUT option to ensure that Jersey is indeed using the ObjectMapper instance that I am providing, and sure enough the output changed according to what I set this feature to.

I am using Jersey 1.5 btw.

Reply | Threaded
Open this post in threaded view
|

Configuration of Struts 2 + Jersey in one app

Kevin Duffey
In reply to this post by Cowtowncoder
Hi all,

I can't seem to find any sort of information on how to configure both Jersey and Struts 2 in one app. I have the following web.xml:

    <servlet>
        <servlet-name>ServletAdaptor</servlet-name>
        <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>ServletAdaptor</servlet-name>
        <url-pattern>/ajax/*</url-pattern>
    </servlet-mapping>

    <filter>
      <filter-name>struts2</filter-name>
        <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
    </filter>

    <filter-mapping>
      <filter-name>struts2</filter-name>
       <url-pattern>/*</url-pattern>
    </filter-mapping>


    I am using Struts 2 annotation configuration for action classes, results, etc. However, I still have a struts.xml in the src/  that gets put into the WEB-INF/classes to configure a few things. One of them is an option not easily found on google about telling Struts to ignore one or more URL patterns. So given that I want ALL requests EXCEPT any url with ajax/* in it, to Struts 2, I have the above and added the ajax/* pattern to the struts.xml like so:


<struts>
    <constant name="struts.devMode" value="true" />
    <constant name="struts.convention.classes.reload" value="true" />
    <constant name="struts.enable.SlashesInActionNames" value="true" />
    <constant name="struts.action.excludePattern" value="/ajax/*?" />

    <package name="default" extends="struts-default" namespace="/">
        <action name="index">
            <result>/index.jsp</result>
        </action>
    </package>
</struts>



As you see, the excludePattern is used to tell Struts what to ignore. Still, I can't get any of my Jersey requests to get through to the resources. They are loading..I see them being round in the log output. The only error I get is that Struts has no action mapped to /ajax/somePath.

So if anyone has configured Struts 2 and Jersey, I'd be much appreciated in helping me resolve how to make them work together so that one (or a few url paths) make it through to Jersey, the rest go to Struts 2.

Thank you.














Reply | Threaded
Open this post in threaded view
|

Re: nil instead of null

Cowtowncoder
In reply to this post by nbaliga
On Mon, Sep 26, 2011 at 7:14 AM, nbaliga <[hidden email]> wrote:
> I did try using the 1.9 SNAPSHOT in my efforts to incorporate a Jackson
> provider in my Jersey project.
>
> However, and I double checked this morning, the root unwrapping feature
> doesn't work for me. I still get the Java name of the root variable instead
> of the XmlRootElement name attribute value.

This could happen if you do not use JAXBAnnotationIntrospector, but
when using it @XmlRootElement is the one that is used (or if not, it'd
be a bug, but I am pretty sure this is unit tested).

> I think this is a side effect of the fact that Jackson seems to be ignoring
> the JAXB annotations altogether, because the propOrder of the elements is
> also being ignored.

It definitely sounds like support for JAXB annotations was not enabled then.
And the problem is probably with this:

>     // make serializer use JAXB annotations (only)
>     objectMapper.getSerializationConfig().withAnnotationIntrospector(introspector );

which would not set the configuration, but only create a new config
object -- all "withXxx()" methods create a new immutable copy of
object they are called on, return that instance.

What you can do instead is just:

objectMapper.setAnnotationIntrospector(introspector);

which calls appropriate methods on both config objects etc.

-+ Tatu +-
Reply | Threaded
Open this post in threaded view
|

Re: nil instead of null

nbaliga
I tried out the changes you suggested above and yes, it works just fine!

The UNWRAP_ROOT_NODE Feature on DeserializationConfig also works, which was another issue I think in 1.8.

Since I haven't heard from anyone about how to get Jersey's Natural implementation to generate a null instead of a nil, I'm concluding that the only solution is to wait for Jackson 1.9 to be GA and incorporate it into my Jersey app.

Thanks for your help.
Reply | Threaded
Open this post in threaded view
|

Re: nil instead of null

Cowtowncoder
On Wed, Sep 28, 2011 at 7:36 AM, nbaliga <[hidden email]> wrote:
> I tried out the changes you suggested above and yes, it works just fine!
>
> The UNWRAP_ROOT_NODE Feature on DeserializationConfig also works, which was
> another issue I think in 1.8.

Ok good.

> Since I haven't heard from anyone about how to get Jersey's Natural
> implementation to generate a null instead of a nil, I'm concluding that the
> only solution is to wait for Jackson 1.9 to be GA and incorporate it into my
> Jersey app.

Yeah -- there may be other suggestions coming down, but I think
jackson-based POJO binding is the preferred way at this point.

Jackson team is now in process of beta-testing 1.9; users have found
couple of issues that we want to fix, but so far so good, and release
should be out within about 1 week. It should be really useful update,
esp. for anyone using JAXB annotations.

-+ Tatu +-
Reply | Threaded
Open this post in threaded view
|

Re: nil instead of null

japod
Hi,

On 28.9.2011 10:05, Tatu Saloranta wrote:
> <snip/>
>> Since I haven't heard from anyone about how to get Jersey's Natural
>> implementation to generate a null instead of a nil, I'm concluding that the
>> only solution is to wait for Jackson 1.9 to be GA and incorporate it into my
>> Jersey app.
> Yeah -- there may be other suggestions coming down, but I think
> jackson-based POJO binding is the preferred way at this point.

I do not know how to solve this using the JAXB based approach.
So the Jackson based POJO binding seems to be the only way.

> Jackson team is now in process of beta-testing 1.9; users have found
> couple of issues that we want to fix, but so far so good, and release
> should be out within about 1 week. It should be really useful update,
> esp. for anyone using JAXB annotations.
Great news, i can upgrade Jackson in Jersey right after the new Jackson
version is available.

~Jakub

> -+ Tatu +-
>