users@jersey.java.net

Re: [Jersey] How to get JAXB entity in subresource

From: Jakub Podlesak <Jakub.Podlesak_at_Sun.COM>
Date: Tue, 26 Aug 2008 11:13:04 +0200

On Mon, Aug 25, 2008 at 01:10:19PM +0200, Paul Sandoz wrote:
> Kevin Duffey wrote:
>
>
> >Thank you for your quick work. I am not entirely sure what this does for
> >me just yet, but I will be playing with it this week and giving you
> >feedback.
> >
>
> Thanks!
>
> Attached is a simple maven project that exercises all possible
> combinations [*] of server/client support of @XmlRootElement, @XmlType
> and JAXBElement<T>.
>
> Note that if you switch to using "application/json" there may be some
> issues we are currently investigating.

It should work fine with JSON now. Please see attached
for updated [pom.xml] and [Main.java] files.

~Jakub

>
> Paul.
>
> [*] Actually not quite all, you can also declare the use of Object for
> unmarshalling if and only if you supply a JAXB context with
> ContextResolver that returns a JAXB context for Object.
>
> >----- Original Message ----
> >From: Paul Sandoz <Paul.Sandoz_at_Sun.COM>
> >To: users_at_jersey.dev.java.net
> >Sent: Monday, August 25, 2008 12:28:00 AM
> >Subject: Re: [Jersey] How to get JAXB entity in subresource
> >
> >Hi Kevin,
> >
> >There are two kinds of JAXB beans:
> >
> > 1) JAXB root element beans whose classes are annotated with
> >@XmlRootElement. These correspond to XSD
> > elements; and
> >
> > 2) JAXB type beans whose classes are annotated with @XmlType. These
> >correspond to XSD types.
> >
> >Depending on how things are defined in a schema XJC may generate only of
> >2) and provide methods in the Object factory that return JAXBElement<T>.
> >
> >For unmarshalling the JAXB unmarshaller can be supplied with a JAXB
> >context that supports 1) or 2). If an XML type bean is returned by the
> >unmarshaller then the root element of the XML document will be processed
> >but that root element information will not be associated with the JAXB
> >type bean. Or if the root element is required to be known for 2) then it
> >is necessary to obtain a JAXBElement instance for the JAXB bean type
> >using a specific method on the JAXB unmarshaller.
> >
> >For marshalling it is required that JAXB have enough information to
> >create a well formed XML document. Thus JAXB root element beans can be
> >marshalled but JAXB type beans cannot, because it does not have a XML
> >root element associated with it. In this case an instance of
> >JAXBElement<T> needs to be used.
> >
> >Jersey has supported 1) using JAXB root element bean instances and types
> >and supported 2) using JAXBElement<T> instances and types where T is a
> >JAXB type bean. However i have just added support for 2) in the trunk
> >for unmarshalling (consuming) such that a JAXB type bean class can be
> >referenced directly. This also solves for you the Client API issue.
> >
> >As for the other issues, i think i am going to write a stand alone
> >sample application for you that exercises various JAXB use cases and
> >will help you understand what is going on and the best way to implement
> >you services.
> >
> >Paul.
> >
> >
> >On Aug 24, 2008, at 6:44 PM, Kevin Duffey wrote:
> >
> >>Hey all,
> >>
> >>Two problems I am trying to figure out: First is how to "consume" a
> >>put/post body of xml in the subresource class:
> >>
> >>@Path("/path")
> >>class MyClass {
> >>
> >> @GET
> >> @Produces("application/xml")
> >> public Response get(){
> >> return Response.ok().build();
> >> }
> >>
> >> @Path("{page}")
> >> public MySubClass getSubResource(@PathParam("page") String page){
> >> return new MySubClass(page);
> >> }
> >>}
> >>
> >>
> >>
> >>class MySubClass {
> >> @PUT
> >> @Consumes("application/xml")
> >> public Response update(JAXBElement<MyJaxBGenClass> mjbgc) {
> >> }
> >>}
> >>
> >>The problem is, everything I've tried, I am not seeing the
> >>MyJaxBGenClass getting passed to the subresource class. I've tried
> >>consuming on the getSubResource, tried using the JAXBElement parameter
> >>in the getSubResource() method itself. Every where I put the @Consumes
> >>and the JAXBElement parameter, it fails.
> >>
> >>
> >>Second problem, which is "similar" to the first.. why do I have to
> >>use JAXBElement<MyJAXBClass> instead of MyJAXBClass in a method
> >>signature? :
> >>
> >>@GET
> >>@Produces({"application/xml", "text/xml", "application/json"})
> >>public Response find(JAXBElement <MyJAXBGenClass> myclass){
> >>}
> >>
> >>The above always tells me it can't find a BodyReader fo the
> >>MyJAXBGenClass. Yet, it's generated with XJC and has the JAXB
> >>annotations in the XSD that generates the classes. Now, if Paul
> >>recalls, there is an issue on the Jersey Client where by the
> >>terminating method can not handle a JAXB Class directly. I am
> >>wondering if the same thing is happening here. For some reason my JAXB
> >>generated classes do not have an @XmlRootElement anywhere. Not even
> >>the "root" class. I am using the Ant XJC taskdef to generate these, so
> >>maybe I am not passing in a param to XJC that I should be? At any
> >>rate, I've seen some of the sample code that uses the JAXB generated
> >>classes directly in the method signuature:
> >>
> >>@GET
> >>@Produces("application/xml")
> >>public Response find(MyJAXBGenClass myclass){
> >>}
> >>
> >>@PUT
> >>@Consumes("appluication/xml")
> >>public Response update(MyJAXBGenClass myclass){
> >>}
> >>
> >>
> >>So the above code should work, right? I shouldn't need to do any
> >>special JAXB stuff to turn the JAXBElement into an actual object?
> >>Right now, every method I use I have something like:
> >>
> >>@GET
> >>@Produces("application/xml")
> >>public Response find(){
> >> MyJAXBClass mc = new MyJAXBClass();
> >> mc.set....
> >>
> >> JAXBElement<MyClass> v = new ObjectFactory().createMyClass(mc);
> >> return Response.ok(v).build();
> >>}
> >>
> >>and the reverse:
> >>
> >>@PUT
> >>@Consumes("application/xml")
> >>public Response update(JAXBElement<MyClass> mc){
> >> MyClass m = (MyClass)mc.getValue();
> >>}
> >>
> >>
> >>So.... I don't know why I have to keep doing it that way when some of
> >>the examples, the JAXBJSon one specifically show the actual class
> >>itself in the method as if the JAXB/Jersey knows how to handle it
> >>without me needing to do any JAXB getValue() or
> >>ObjectFactory.createClass() stuff.
> >>
> >>I even copied the @Producer class from the sample, called
> >>JAXBContextResolver, and put my classes in there and it's still not
> >>working. I don't even know if that resolver class is required. But
> >>from my understanding using JAXB generated classes, the Annotations in
> >>the generated classes are all that Jersey needs to be able to do the
> >>JAXB conversions for me. I just seem to be missing something.
> >>
> >>Thanks.
> >>
> >>
> >>
> >>
> >
> >
>
> --
> | ? + ? = To question
> ----------------\
> Paul Sandoz
> x38109
> +33-4-76188109


> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
> For additional commands, e-mail: users-help_at_jersey.dev.java.net


-- 
http://blogs.sun.com/japod