users@jersey.java.net

Re: One Resource class for two URLs

From: Martin Probst <mail_at_martin-probst.com>
Date: Wed, 23 Apr 2008 14:02:32 +0200

>> I will need to inject, as I currently plan to have a "getURI()"
>> method in all my resources, so I can easily link to them in the
>> views. And that of course needs a UriInfo. Or does it?
>
> If you could access UriInfo from your templates would that work? I
> can easily add it as a "standard" property, as i do for the model.
> BTW you can access the servlet request/response using "_request" and
> "_response".

UriInfo inside templates would definitely help - I'd like to avoid
writing <a href="/foo/bar"/> and rather have
"linker.linkTo(Book.class, "create")" or similar.

That aside, I'd still prefer to have resources that can provide a link
(at least one, default link) to themselves without any helpers. I
think this is more restful, and I'd presume it's useful if all your
resources can be linked to in a simple, standard way.

I have some unstructured ideas about how to solve the problem with
linking to stuff from views. I don't have a solution yet, but I'm
thinking in terms of a URI helper ("linker") that can be instructed to
produce links to certain things, maybe according to certain
properties, (e.g. "linker.formFor(book, "delete")"). I think links
should be created by the controller together with the model, but never
by the view.

>> I only need the UriInfo for host, port and scheme
>
> More accurately would it be the base URI the application is deployed
> at?

Yes, indeed. Or a way to explicitly create relative URIs, starting
from the current request URI, or ideally both :-)

Relative URIs from the current URI would be really nice, something like:
request to /book/12/author, then
uriInfo.getRelativePathBuilder().path(Books.class) -> ../../../books.

This way you could avoid the trouble with absolute URIs, and you
wouldn't need to actually know all that host and port stuff. I think
in many scenarios a web application might actually not know it's
correct absolute URI, for example if you're only an application server
behind some proxy/balancer/... stuff. Giving out http://localhost:8092/foo/bar
  won't really help clients :-)

>> - simply instantiating a UriBuilder gives URLs like "//:-1/...". Is
>> that a bug (I think I've seen it behave differently)?
>
> Can you send code to how you are building? For example i can build a
> relative path as follows:
>
> UriBuilder.fromPath("rel").path("sub).build();
>
> IIRC there might have been an issue that i fixed, but my memory is a
> bit hazy on the matter.

In my version, that only works if you call .build() like that. But if
you supply parameters to build(), the call dispatches to

UriTemplate.createURI(scheme,
                 userInfo, host, String.valueOf(port),
                 path.toString(), query.toString(), fragment, values,
encode);

And then you'll get the //:-1/ stuff. A bug?

My actual code was something like this:
UriBuilder.fromResource(Books.class).path(Book.class,
"getBook").build(getId()); Maybe it would be nice

> Ideally there should be just one way. For example, a browser that
> receives a 201 created with no content and a Location header would
> perform GET from the URI declared in the Location header. IIRC
> firefox does not do this. Unfortunately i think we have a split :-(

I'm getting increasingly irritated by these long standing browser
"misbehaviours". Another nice one is that no browser on earth supplies
a content encoding when posting a form or GETting a URI. Very annoying.

> One way you could hide things underneath is to have a servlet filter
> that checks the User-Agent and converts a 201 (Created) to a 303
> (See Other).

That might work. Or I'll just always return the 303 for the time
being...

Regards,
Martin