Paul Sandoz wrote:
>[...]
>
> The runtime supports a very common matching approach, say the 80% rule,
> but in no way restricts an application to that rule. It is possible to
> apply an alternative based on specific *application* semantics of an
> acceptable set of media types [*], which is what the example about audio
> is: application semantics about relative audio quality.
No, I'm talking about the semantics defined in RFC 2616.
>
> For example, the following resource method uses many of the JAX-RS
> features and can support the audio quality semantics as it requires:
>
> @Produces("audio/*")
> @GET
> public Response get(@Context HttpHeaders h) {
> List<MediaType> ahs = h.getAcceptableMediaTypes();
> // application-based behaviour for media type selection
> MediaType bestType = selectBestAudio(ahs);
>
> Audio a = getAudio();
> return Response.ok(a, bestType).build();
> }
You cannot interpret the q-value in an RFC compliant way, without
knowing about the relative quality of the producers, so selectBestAudio
would have not only to take the accept-headers but also the available
providers:
public Response get(@Context HttpHeaders h, @Context Providers providers) {
List<MediaType> ahs = h.getAcceptableMediaTypes();
// application-based behaviour for media type selection
MediaType bestType = selectBestAudio(ahs, providers);
...
the selectBestAudio would have to get the producers for all entries in
the accept-header retrieve the q-value by getting parsing the @Produces
annotation and select the best one.
>
> Note that the runtime algorithm of ordering will not get in the way in
> such circumstances and in no way does it appear that applications are no
> longer benefiting from many features otherwise provided.
If the runtime supports the q-value semantics to add that low quality
wma producers for devices that do not (decently) support another format
is trivial. Without that support in the runtime the application has to
care about details (via context-injection, annotation parsing and
returning Response instead of Audio) it otherwise wouldn't.
>
> You can even do this (although i do not know why you would want to):
>
> @Produces("audio/basic")
> @GET
> public Response getBasic(@Context HttpHeaders h) {
> return get(h);
> }
>
> :-) i.e. what is returned in the Response always takes precedence.
>
> Paul.
>
>
> [*] what does the following mean in such circumstances?
> +
> Accept: audio/*; q=0.2, audio/basic, image/png;q=0.3
>
> obviously the q parameter when comparing in this case makes no sense in
> terms of audio quality when applied to the image.
The q-value indicates "the relative degree of preference" the sound
quality is one possible factor composing such a relative preference. If
the resource for which a representation is requested with the
accept-header above can be represented equally well by audio and by
image the client will get audio/basic if the server can produce this
with a relative quality > (0.3 * quality of producible png) and >= (0.2
* quality of producible audio/*), otherwise it gets image/png if it
quality is at least 50% higher than the producible quality for audio/*.
Of course, I don't think there are many resources that can be
represented equally well by audio and by image, so independently of the
quality of a producer a resource might indicate that it's much better
represented by an audio than an image:
@Produces("audio/*")
@GET
@Path("my-song")
public Song get() {
//returns the song
}
@Produces("image/*;q=.05")
@GET
@Path("my-song")
public Song getImage() {
//returns an image representation of my song
}
I think for getting the quality of an available representation for a
particular resource, the q-value of the method hat to be multiplied with
the q-value of the producer. In the example having a 20-time smaller
q-value for image than for songs makes sure, that an image is delivered
only if the client can't reasonable handle sound.
Reto