Re: JSR311: URI-based conneg - take 2

From: Marc Hadley <Marc.Hadley_at_Sun.COM>
Date: Thu, 06 Mar 2008 11:02:03 -0500

On Mar 6, 2008, at 3:42 AM, Stephan Koops wrote:
> that's a good proposal. I put some remarks between the points, see
> below:
>> - We only offer automatic support for content types and language,
>> nothing for charset or encoding negotiation.
>> - The feature is controlled by a combination of annotation and
>> config:
>> * A property of ApplicationConfig defines the default (enabled/
>> disabled).
> I think it is enough if getMediaTypes() and getLanguages() both
> return null or an empty map.

That depends on whether you want per-resource control or not. Not
having per-resource control of the feature simplifies things a lot and
in that case your suggestion above would work fine.

> What about a MultivaluedMap for getMediaTypes()? This could be
> useful for XML,(*.xml -> { text/xml, application/xml, application/*
> +xml }Javascript (*.js -> { text/javascript, application/
> javascript}) and perhaps others.

I don't think I understand the reason for a one-to-many config.
If .xml mapped to multiple types then you'd have to fall back to the
original accept header to select which one to use. But if you are
going to use the original accept header then why bother with the
extension at all, you can just use the accept header with the platonic

>> [...]
>> * Each extension is compared to the keys in
>> ApplicationConfig.getMediaTypesMap (Map<String, MediaType) and
>> ApplicationConfig.getLanguageMap (Map<String, String). If a match
>> is found the corresponding Accept or Accept-Language header value
>> is replaced with the value for the matching key.
> Should JAX-RS support /widgets/ -> Uri = /widgets/5,
> Accept: text/xml,application/json and Accept-Language: en, fr. ?
> If yes, it should be defined, if en or fr has the higher quality;
> the same for xml and json. I propose, the first extension has a
> higher quality than the laters.

I had naively thought that the final would overwrite the
prior .xml.en. IMO use of extensions is about selecting a single
distinct representation, not multiple possibilities.

>> - Existing UriInfo methods are not affected, any extensions in the
>> URI are included in the path returned by any of the methods. For
>> convenience we add:
>> * UriInfo.getPathExtension() that returns the extensions as a
>> String or null if there isn't one,
> Define if with a "." at the beginning or without?


>> [...]
>> Issues:
>> (i) Because matching is controlled on a per-resource basis we can't
>> just preprocess the request URI and then use that for matching. It
>> would be simpler but less flexible without the per-resource
>> control. Is that a tradeoff folks would consider ?
> I think: pre-process and then match, or fully disabled for the full
> JAX-RS environment instance.

I'm thinking the same. Per-resource config really complicates things,
a simple URI rewriting approach seems much easier to grok.

> If someone needs the file name with extension (for returning a file
> from the filesystem or whatever) he could use UriInfo.getPath() or
> UriInfo.getPathSegments(). It is useful to add
> UriInfo.getLastPathSegment() ?

I dunno, getPathSegments() returns a list and its pretty easy to get
the last item in a list...

>> (ii) A result of (i) is that for efficiency we essentially treat a
>> URI with any extensions as matching a platonic URI. E.g.
>> would match WidgetsResource above and be
>> treated the same as or Rejecting
>> URIs with extensions that don't match one of the configured
>> extensions on a per-resource basis would be expensive, rejecting
>> them globally would mean you couldn't have a distinct resource path
>> that had a non-conforming extension.
> Yes, we should keep in mind, that this forbid all "." in the URI, if
> this feature is enabled. For implementing I would look for the last
> point in the String, get the extension and shortening the URI, and
> loop, until a non-matching is found. I think, this is an efficient
> way.
> Perhaps we should only forbid extensions in @Path given this
> getMediaTypes() and getLanguages(), when reading it the first time,
> or warn in a log.
For the pre-processing approach I think extensions in @Path are OK
provided they don't match one of the values in getMediaTypes() and
getLanguages(). When you rewrite the URI you'd only need to snip out
the matching extensions.


Marc Hadley <marc.hadley at>
CTO Office, Sun Microsystems.