From: Bill B. <bb...@re...> - 2012-05-25 17:37:53
|
Ok, The problem is that you also have to annotate the link parameter: @PUT @Path("attributes") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @Mapped(namespaceMap = { @XmlNsMap(namespace = "http://ejava.info", jsonName = "ejava"), }) public Response putLinkJSON(@Mapped(namespaceMap = { @XmlNsMap(namespace = "http://ejava.info", jsonName = "ejava"), }) Link link) {...} Basically the 1st @Mapped applies to the response entity, the 2nd (the one on the parameter) applies to the parameter. Please let me know if this fixes your problem. If it doesn't, you may be encountering a different namespace mapping bug (for XJC generated code) that I've fixed in Branch_2_3. On 5/13/12 11:22 PM, Jim Stafford wrote: > I am encountering an error while demarshalling a JSON object as input > to a JAX-RS method. After some tinkering, the error seems to be due to > the XmlNsMap defined for the output not being applied to the input. > > org.jboss.resteasy.plugins.providers.jaxb.JAXBUnmarshalException: > javax.xml.bind.UnmarshalException > - with linked exception: > [com.sun.istack.SAXParseException2; columnNumber: 0; unexpected > element (uri:"", local:"ejava.link"). Expected elements are > <{http://ejava.info}link>] > > Is there something similar to the ContextResolver<JAXBContext> that > has to be done for JSON XmlNsMaps? > > > The RESTEasy JSON examples generate data (which I can do) but none > consume data. I have gotten it to work by injecting a String and > demarshalling the object thru the Jettison APIs. I can also get the > manual approach to generate the same error message -- which leads me > to think the input/demarshaller for JSON needs more than the @Mapped > annotation. > > * I am working with a simple Link class in the "http://ejava.info" namespace. > package ejava.util.rest; > @XmlRootElement(name="link", namespace="http://ejava.info") > @XmlType(name="LinkType", namespace="http://ejava.info") > public class Link { > ... > } > > * I have attempted to pass the JSON object straight into the method > and have RESTEasy do the demarshalling. I have added the > @Mapped/@XmlNsMap annotations for the used namespace. This has allowed > me to generate Link objects successfully. > @PUT @Path("attributes") > @Consumes(MediaType.APPLICATION_JSON) > @Produces(MediaType.APPLICATION_JSON) > @Mapped(namespaceMap = { > @XmlNsMap(namespace = "http://ejava.info", jsonName = "ejava"), > }) > public Response putLinkJSON(Link link) //String jsonString) > throws JSONException, XMLStreamException, JAXBException { > link.setHref(uriInfo.getRequestUri()); > link.setType(MediaType.APPLICATION_XML); > return Response.ok(link, MediaType.APPLICATION_JSON).build(); > } > > * When I PUT my JSON object to the method... > > PUT /jaxrs-representations-dmv-war6/data/attributes HTTP/1.1 > Content-Type: application/json > Accept: application/json > Content-Length: 30 > Host: dmv.ejava.info:9092 > Connection: Keep-Alive > User-Agent: Apache-HttpClient/4.1.3 (java 1.5) > > {"ejava.link":{"@rel":"self"}} > > > ... it reports the following error > -Failed executing PUT /data/attributes > org.jboss.resteasy.plugins.providers.jaxb.JAXBUnmarshalException: > javax.xml.bind.UnmarshalException > - with linked exception: > [com.sun.istack.SAXParseException2; columnNumber: 0; unexpected > element (uri:"", local:"ejava.link"). Expected elements are > <{http://ejava.info}link>] > at org.jboss.resteasy.plugins.providers.jaxb.AbstractJAXBProvider.readFrom(AbstractJAXBProvider.java:125) > > * When I inject the JSON object into a String and manually demarshal > the JSON. It works (see the 200 reply below) > > @PUT @Path("attributes") > @Consumes(MediaType.APPLICATION_JSON) > @Produces(MediaType.APPLICATION_JSON) > @Mapped(namespaceMap = { > @XmlNsMap(namespace = "http://ejava.info", jsonName = "ejava"), > }) > public Response putLinkJSON(String jsonString) > throws JSONException, XMLStreamException, JAXBException { > > JAXBContext ctx = JAXBContext.newInstance(Link.class); > Configuration config = new Configuration(); > Map<String, String> xmlToJsonNamespaces = new HashMap<String,String>(); > xmlToJsonNamespaces.put("http://ejava.info", "ejava"); > config.setXmlToJsonNamespaces(xmlToJsonNamespaces); > MappedNamespaceConvention con = new MappedNamespaceConvention(config); > > JSONObject obj = new JSONObject(jsonString); > XMLStreamReader xmlStreamReader = new MappedXMLStreamReader(obj, con); > Unmarshaller unmarshaller = ctx.createUnmarshaller(); > Link link = (Link) unmarshaller.unmarshal(xmlStreamReader); > > link.setHref(uriInfo.getRequestUri()); > link.setType(MediaType.APPLICATION_XML); > return Response.ok(link, MediaType.APPLICATION_JSON).build(); > } > > HTTP/1.1 200 OK > Content-Type: application/json > Transfer-Encoding: chunked > Server: Jetty(6.1.26) > > {"ejava.link":{"@href":"http:\/\/dmv.ejava.info:9092\/jaxrs-representations-dmv-war6\/data\/attributes","@rel":"self","@type":"application\/xml"}} > > > * When I comment out the Map in the working code... > Map<String, String> xmlToJsonNamespaces = new HashMap<String,String>(); > //xmlToJsonNamespaces.put("http://ejava.info", "ejava"); > config.setXmlToJsonNamespaces(xmlToJsonNamespaces); > > ...I get an error message similar to the one from the original case. > [com.sun.istack.SAXParseException2; columnNumber: 0; unexpected > element (uri:"", local:"ejava.link"). Expected elements are > <{http://ejava.info}link>] > at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.handleStreamException(UnmarshallerImpl.java:434) > at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:371) > at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:341) > at ejava.examples.jaxrsrep.handlers.JSONHandlerDemoRS.putLinkJSON(JSONHandlerDemoRS.java:100) > > This leads me to think that I need to register something similar to > the ContextResolver that I have done for other JAXB cases -- however, > I haven't located any documentation on how I can help setup the > Jettison demarshaller. > > ideas? > > thanks, > jim > > ------------------------------------------------------------------------------ > Live Security Virtual Conference > Exclusive live event will cover all the ways today's security and > threat landscape has changed and how IT managers can respond. Discussions > will include endpoint security, mobile security and the latest in malware > threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/ > _______________________________________________ > Resteasy-users mailing list > Res...@li... > https://lists.sourceforge.net/lists/listinfo/resteasy-users -- Bill Burke JBoss, a division of Red Hat http://bill.burkecentral.com |