Not sure if this is helpful or applicable to you, but...some time ago I was running into a somewhat related issue where the propOrder attribute specified on the JAXB-annotated class appeared to be getting ignored - XML output was fine, but JSON output was not. I posted a thread asking about this and it was related to the *jsonProvider *configuration in the Spring bean definition.
That thread is below: Sergey Beryozkin [email protected] Mar 25 to users Hi, I updated the documentation to get JacksonJaxbJsonProvider referenced as well Thanks, Sergey On 24/03/12 21:05, Mark Streit wrote: Think I SOLVED this. Appears the issue is with the following line in cxf-beans.xml file... <bean id="jsonProvider" class="org.codehaus.jackson.jaxrs.* JacksonJsonProvider*"/> SHOULD be: <bean id="jsonProvider" class="org.codehaus.jackson.jaxrs.* JacksonJaxbJsonProvider*"/> Simply changing that class reference, appears to have solved the issue. *Now *the JSON element order matches the XML element order in the response > > output. > > Hopefully this is indeed the correction. > > > On Sat, Mar 24, 2012 at 1:47 PM, Mark Streit<[email protected]> wrote: > > I hope I have what MIGHT be a simple question. (one article I found on >> Google indicated that this *should *work, however I also found a number >> >> of threads relating to this where it was commented that JSON objects have >> fields which are inherently UNORDERED). We have a case where the consumer >> is expecting the JSON to adhere to a JSON schema that has been >> pre-defined. >> >> Have a simple Book class annotated as shown: >> >> @XmlAccessorType(XmlAccessType.FIELD) >> @XmlRootElement(name="Book") >> @XmlType(name = "Book", namespace="http://dvo.services.book.acme.com/", >> *propOrder >> *= { "bookID", "bookTitle", "authorName", "ISBN", "bookTypeCode", >> >> "bookPublisher", "bookRetail", "bookCost", "pageCount" }) >> public class Book { >> >> Using a JAX-RS annotated service class (for a REST endpoint) works >> perfectly returning XML when the Accept header is application/xml... the >> XML returned *honors *the propOrder attribute *as specified*. >> >> >> However, if I pass the Accept header as application/json - I DO get a >> complete JSON response, as expected... except the propOrder appears to be >> *ignored *- the elements come back in a different order. >> >> >> I have the JSON provider for Jackson set as follows in the beans >> configuration file (called cxf-beans.xml in my case) >> >> <?xml version="1.0" encoding="UTF-8"?> >> <beans xmlns="http://www.springframework.org/schema/beans" >> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" >> xmlns:jaxws="http://cxf.apache.org/jaxws" >> xmlns:jaxrs="http://cxf.apache.org/jaxrs" >> xsi:schemaLocation=" >> http://www.springframework.org/schema/beans >> http://www.springframework.org/schema/beans/spring-beans-2.5.xsd >> http://cxf.apache.org/jaxws >> http://cxf.apache.org/schemas/jaxws.xsd >> http://cxf.apache.org/jaxrs >> http://cxf.apache.org/schemas/jaxrs.xsd"> >> >> <import resource="classpath:META-INF/cxf/cxf.xml" /> >> <import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" /> >> <import resource="classpath:META-INF/cxf/cxf-servlet.xml" /> >> >> <bean id="jsonProvider" >> class="org.codehaus.jackson.jaxrs.JacksonJsonProvider"/> >> >> <!-- JAX-RS --> >> <jaxrs:server id="bookService" address="/RS"> >> <jaxrs:serviceBeans> >> <ref bean="bookServiceRS" /> >> </jaxrs:serviceBeans> >> <jaxrs:providers> >> <ref bean="jsonProvider"/> >> </jaxrs:providers> >> </jaxrs:server> >> ... >> ... >> >> I will keep looking but thought I'd post this in case someone has seen >> this behavior before. I am guessing I have missed something in telling >> Jackson how to serialize, perhaps... >> >> I do not have any sort of custom JSON serializer configured - just relying >> on whatever OOTB behavior JAXB/Jackson provide when used with CXF - (using >> version 2.5.2). >> >> Thanks >> >> >> On Tue, May 22, 2012 at 6:20 PM, <[email protected]> wrote: > No, not working with OSGI. Just using a standard Web application with > Spring. I am using CXF 2.6.0 though, not sure if that should matter. > > Note that I did have to manually add the Jettison dependency, and after I > did I received an error stating that the context did not know about my > class. From there I created the JSONProvider instance with the class > identified in jaxbElementsClassName property and was able to get my Web > resource to work. > > -----Original Message----- > From: Sergey Beryozkin [mailto:[email protected]] > Sent: Tuesday, May 22, 2012 2:25 PM > To: [email protected] > Subject: Re: JSON for JAX-RS configuration > > Thanks,indeed the default JSON Provider should manage XMLRootElement > annotated classes without any additional configuration. > > Tom, do you work with OSGI ? Jettison bundle may need to be installed there > > Cheers, Sergey > On 22/05/12 18:37, Shane Saunders wrote: > > Tom, > > > > This is what I setup for a very basic sample project that I created > > for our project to use as a starting point for JSON. I think your > > setup looks good, but I did not use the JSON Provider parameters that > > you have setup. I built this with CXF 2.5.2. It was able to > > (un)marshall the JSON correctly for me on the server side and I used a > similar setup for the WebClient class. > > > > beans.xml: > > ... > > <jaxrs:server id="myServer" address="/sample"> > > <jaxrs:providers> > > <ref bean="jsonProvider" /> > > </jaxrs:providers> > > > > <jaxrs:serviceBeans> > > <ref bean="myBean" /> > > </jaxrs:serviceBeans> > > </jaxrs:server> > > > > <bean id="myBean" > > class="com.hp.exstream.sample.SampleRestJsonImpl" /> > > > > <bean id="jsonProvider" > > class="org.apache.cxf.jaxrs.provider.JSONProvider"> > > <property name="ignoreNamespaces" value="true" /> > > </bean> > > ... > > > > Web Service Interface class: > > > > @Path("/") > > public interface SampleRestJson { > > > > @POST > > @Produces("application/json") > > @Consumes("application/json") > > @ElementClass(response = ResponseData.class, request = > > RequestData.class) > > @Path("/request") > > public ResponseData request1(RequestData req); } > > > > > > RequestData: > > > > @XmlRootElement > > @XmlAccessorType(XmlAccessType.FIELD) > > public class RequestData { > > > > private String stringData; > > private int intData; > > ... > > } > > > > > > ResponseData: > > > > @XmlRootElement > > @XmlAccessorType(XmlAccessType.FIELD) > > public class ResponseData { > > > > private String stringData; > > private int intData; > > ... > > } > > > > > > HTH, > > Shane > > > > > > On Tue, May 22, 2012 at 10:49 AM,<[email protected]> > wrote: > > > >> After spending a couple of days trying to get JAXB and JSON working > with a > >> JAX-RS service I found that the following was required. It wasn't > clear to > >> me from the documentation or samples that explicit declarations of the > JAXB > >> objects in the service bean configuration was required. My initial > >> assumption was that there was a default JSONProvider instance that > didn't > >> require configuration, and that any object with the @XmlRootElement > >> annotation could be marshaled. > >> > >> The following is the correct method for configuring a JAX-RS service > using > >> JSON as the communication protocol? > >> > >> Web resource interface: > >> @Path("users") > >> public interface RestUserService { > >> > >> @GET > >> @Path("/{name}") > >> @Consumes("application/json") > >> @Produces("application/json") > >> public Response findUser(@PathParam("name") String name); > >> > >> @POST > >> @Consumes("application/json") > >> @Produces("application/json") > >> public Response create(User user); > >> } > >> > >> > >> Spring bean definition: > >> <!-- This provider is required when Web resources are using JSON > as > >> the protocol --> > >> <bean id="jsonProvider" > >> class="org.apache.cxf.jaxrs.provider.json.JSONProvider"> > >> <property name="singleJaxbContext" value="true" /> > >> <property name="jaxbElementClassNames"> > >> <list> > >> > >> <value>com.thomsonreuters.services.userservice._2012_02_01.User</value> > >> </list> > >> </property> > >> </bean> > >> > >> <jaxrs:server id="restServices" address="/rest"> > >> <jaxrs:serviceBeans> > >> <ref bean="restUserService" /> > >> </jaxrs:serviceBeans> > >> > >> <jaxrs:providers> > >> <ref bean="jsonProvider" /> > >> </jaxrs:providers> > >> </jaxrs:server> > >> > >> Tom > >> > >> > > > > > *Mark *
