Hi Alex,
could you please zip the web application and send it to me?
If it is too big, please send it privately (to jakub.podlesak at sun.com).
Thanks,
~Jakub
On Tue, Mar 23, 2010 at 11:18:44AM +0000, Alex Treppass wrote:
> The web service I am writing using Jersey / JAXB plays perfectly with
> @Consuming and @Producing XML from JAXB-annotated POJOs. However when
> working with JSON, JAXB (or Jersey?) seems to require a brittle ordering of
> JSON elements. I am using Jersey 1.1.5 and JaxB 2.2 ri-20091104 (latest).
>
> I've created a simple Web application project to demonstrate:
>
> POJO
> ---------------
> @XmlRootElement(name = "Test")
> @XmlAccessorType(XmlAccessType.FIELD)
> public class Test
> {
> @XmlAttribute
> private int int1;
> @XmlElement
> private String string1;
> @XmlElement
> private List<String> strings;
> @XmlAttribute
> private int int2;
> @XmlAttribute
> private long long1;
>
> public Test()
> {
> super();
> }
>
> public Test(int int1, String string1, List<String> strings, int int2,
> long long1)
> {
> super();
> this.int1 = int1;
> this.int2 = int2;
> this.long1 = long1;
> this.string1 = string1;
> this.strings = strings;
> }
>
> ... hashcode & equals omitted.
> }
>
> Interface
> ---------------
> @Path("test")
> public interface IView
> {
> @GET
> @Path("get/")
> @Produces(MediaType.APPLICATION_JSON)
> public abstract Test getTest();
>
> @POST
> @Path("post/")
> @Consumes(MediaType.APPLICATION_JSON)
> @Produces(MediaType.APPLICATION_JSON)
> public abstract Test takeTest(final Test test);
> }
>
> Implementation
> ---------------
> @Provider
> public class View implements IView
> {
> public Test getTest()
> {
> return new Test(1, "string", Arrays.asList(new String[] { "s1", "s2"
> }), 2, 3L);
> }
>
> public Test takeTest(final Test test)
> {
> return test;
> }
> }
>
> When I request /test/get, JAXB returns me the following JSON every time,
> even though I have no @XmlType(propOrder =) class annotation set. This is
> fine - I don't mind an arbitrary ordering for output.
> (Note that I am using a custom ContextResolver<JAXBContext> to read &
> return JSONConfiguration.natural() notation for my Test class)
> {"int1":1,"int2":2,"long1":3,"string1":"string","strings":["s1","s2"]}
>
> However, when I try and consume JSON that does not match this order, strange
> things happen and my int / long fields are not set. This is shown in the
> following example:
>
> Post:
> {"int1":1,"string1":"string","strings":["s1","s2"],"int2":2,"long1":3}
> Response:
> {"int1":1,"int2":0,"long1":0,"string1":"string","strings":["s1","s2"]}
> equals(): false
> [...fields int2 and long1 are not being set.]
> ----------
>
> I've created a test script which constructs various JSON strings and posts
> them off to my takeTest() method, which returns a JSON representation of the
> parsed Test object.
> I then use Jackson within my test script to build this into a new Test
> object (via a JaxbAnnotationIntrospector) and test equality on the two
> objects.
>
> Post:
> {"string1":"string","strings":["s1","s2"],"int1":1,"int2":2,"long1":3}
> Response:
> {"int1":0,"int2":0,"long1":0,"string1":"string","strings":["s1","s2"]}
> equals(): false
> [... none of the int or long fields are being set]
> ----------
>
> Post:
> {"int1":1,"int2":2,"string1":"string","strings":["s1","s2"],"long1":3}
> Response:
> {"int1":1,"int2":2,"long1":0,"string1":"string","strings":["s1","s2"]}
> equals(): false
> [... int1 and int2 are correctly set, but long1 is not set]
> ----------
>
> Post:
> {"int1":1,"int2":2,"long1":3,"string1":"string","strings":["s1","s2"]}
> Response:
> {"int1":1,"int2":2,"long1":3,"string1":"string","strings":["s1","s2"]}
> equals(): true
> ----------
>
> If I attach an @XmlType(propOrder = { "int1", "int2", "long1", "string1",
> "strings" }) annotation to my Test class, Jackson will happily follow this
> and generate JSON that matches JAXB's expected ordering. I don't however
> think the onus should be on clients to guarantee the 'primitives first'
> ordering that Jersey / JAXB seems to expect.
>
> My issue here is that if I'm using a particular JSON library (in whatever
> language, divorced from my server) to post JSON at /test/post/ I cannot
> guarantee element ordering. Is this a bug with Jersey's use of JAXB? Or
> potentially JAXB by itself?
--
http://blogs.sun.com/japod