You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@cxf.apache.org by John Klassa <jo...@klassa.com> on 2009/10/07 15:31:29 UTC

UriBuilder confusion

I'm trying to use Apache CXF with JSR-311 annotations to prototype  
some web services.  So far, so good, but with some snags.  The one I'm  
facing currently is with UriBuilder...

Basically, I've got a resource class that represents Widgets, let's  
say.  That class has sub-resources, which we'll call Dongles.  In the  
XML that's emitted for a Widget, I want to insert links to the Dongle  
"children" of the Widget.  In URI terms, it'd be something like:

http://foo.com/Widget/999
(returns the XML for the Widget with ID 999)

http://foo.com/Widget/999/Dongle/23
(returns the XML for Widget 999's Dongle with ID 12)

In the XML for Widget 999, I'd like to see something like:

<Dongle xlink:href="/Widget/999/Dongle/23">
dongle details
</Dongle>

And of course, I don't want to hard-code anything, so I'm trying to  
build the link programmatically.  So, I followed some examples, and  
came up with something like this:

import javax.ws.rs.core.UriBuilder;  // among others

@Path("/Widget")
public class WidgetResource
{
    @GET
    @Path("/{id}")
    @Produces("application/xml")
    public Widget getWidget (@PathParam("id") String id,
                             @Context UriInfo info)
    {
        UriBuilder noteBuilder =
            info.getAbsolutePathBuilder().path(DongleResource.class);
        // ...and later, something like...
        obj.setHref(dongleBuilder.build(id, dongle.getID()).toString());
        /// ...and so on...
    }
}

@Path("/Widget/{id}/Dongle")
public class DongleResource
{
    @GET
    @Path("/{dongleID}")
    @Produces("text/plain")
    public Dongle getDongle (@PathParam("id") String id,
                             @PathParam("dongleID") String dongleID)
    {
         // ...stuff happens...
    }
}

However, when I use this, I invariably get a built URI that looks like  
this:

<Dongle xlink:href="/Widget/999/Widget/999/Dongle">...

with the Widget/ID repeated, and no primary key on the Dongle -- or  
variants thereof, but never what I'm looking for.  I've tried defining  
the Path in different ways, with different parts exposed in different  
places.  I've also tried fetching the UriBuilder like so:

info.getAbsolutePathBuilder().path(DongleResource.class, "getDongle")

to explicitly call out the method of interest, that I'm hoping will  
provide the template for the URI.  In short, it's not clear to me how  
UriBuilder does its thing, or what the best practices around it are,  
so I'm hoping someone can shed some light on the subject.

Thanks.

Re: UriBuilder confusion

Posted by Sergey Beryozkin <sb...@progress.com>.
Hi,

>        UriBuilder noteBuilder =
>            info.getAbsolutePathBuilder().path(DongleResource.class);

so if we have

http://foo.com/Widget/999

the uri builder will already have /Widget/999, and then

path(DongleResource.class);

adds "/Widget/{id}/Dongle" but no trailing "/{dongleId}" so we have

http://foo.com/Widget/999/Widget/{id}/Dongle"

So when you do builder.build(widegetId, dongleId), dongleId is ignored.

One problem is that DongleResource.class is also acts as a root resource class so it also has 'Widget'.
You might just to do :

Uri u = UriBuilder.fromResource(DongleResource.class).path(dongleId).build(widgetId);

you can append @Path("{dongleId}") from the method to the DongleResource.class Path value instead which will let you do

Uri u = UriBuilder.fromResource(DongleResource.class).build(widgetId, dongleId);

which will give you something like : 

"/Widget/999/Dongle/1"

cheers, Sergey







----- Original Message ----- 
From: "John Klassa" <jo...@klassa.com>
To: <us...@cxf.apache.org>
Sent: Wednesday, October 07, 2009 2:31 PM
Subject: UriBuilder confusion


> 
> I'm trying to use Apache CXF with JSR-311 annotations to prototype  
> some web services.  So far, so good, but with some snags.  The one I'm  
> facing currently is with UriBuilder...
> 
> Basically, I've got a resource class that represents Widgets, let's  
> say.  That class has sub-resources, which we'll call Dongles.  In the  
> XML that's emitted for a Widget, I want to insert links to the Dongle  
> "children" of the Widget.  In URI terms, it'd be something like:
> 
> http://foo.com/Widget/999
> (returns the XML for the Widget with ID 999)
> 
> http://foo.com/Widget/999/Dongle/23
> (returns the XML for Widget 999's Dongle with ID 12)
> 
> In the XML for Widget 999, I'd like to see something like:
> 
> <Dongle xlink:href="/Widget/999/Dongle/23">
> dongle details
> </Dongle>
> 
> And of course, I don't want to hard-code anything, so I'm trying to  
> build the link programmatically.  So, I followed some examples, and  
> came up with something like this:
> 
> import javax.ws.rs.core.UriBuilder;  // among others
> 
> @Path("/Widget")
> public class WidgetResource
> {
>    @GET
>    @Path("/{id}")
>    @Produces("application/xml")
>    public Widget getWidget (@PathParam("id") String id,
>                             @Context UriInfo info)
>    {
>        UriBuilder noteBuilder =
>            info.getAbsolutePathBuilder().path(DongleResource.class);
>        // ...and later, something like...
>        obj.setHref(dongleBuilder.build(id, dongle.getID()).toString());
>        /// ...and so on...
>    }
> }
> 
> @Path("/Widget/{id}/Dongle")
> public class DongleResource
> {
>    @GET
>    @Path("/{dongleID}")
>    @Produces("text/plain")
>    public Dongle getDongle (@PathParam("id") String id,
>                             @PathParam("dongleID") String dongleID)
>    {
>         // ...stuff happens...
>    }
> }
> 
> However, when I use this, I invariably get a built URI that looks like  
> this:
> 
> <Dongle xlink:href="/Widget/999/Widget/999/Dongle">...
> 
> with the Widget/ID repeated, and no primary key on the Dongle -- or  
> variants thereof, but never what I'm looking for.  I've tried defining  
> the Path in different ways, with different parts exposed in different  
> places.  I've also tried fetching the UriBuilder like so:
> 
> info.getAbsolutePathBuilder().path(DongleResource.class, "getDongle")
> 
> to explicitly call out the method of interest, that I'm hoping will  
> provide the template for the URI.  In short, it's not clear to me how  
> UriBuilder does its thing, or what the best practices around it are,  
> so I'm hoping someone can shed some light on the subject.
> 
> Thanks.