Hello
After the interesting discussions on q-value, I would like to suggest a
patch to the spec to solve the related issues.
Goals:
*
Address issue 46
*
Produce the same results as the current spec if providers and
methods specify no q-value (except that it might prevents some 406
responses)
*
Remove duplications between provider matching when determining the
response-type and when processing the value returned by a resource
method
*
Prevent that a response media-type has been selected using a
MessageBodyWriter for which isWritable returns false in the case
when isWritable can be invoked before invoking the method.
(reduces unnecessary 406 response)
Not sure on how to 'patch' specification, so using some free-style syntax.
Looking forward to your feedback,
Reto
The 'Patch':
[replace first paragraph of 3.7.2 with]
A request is matched to a set of suitable resource methods or
sub-resource methods by comparing the normalized request URI (see
section 3.7.1), and the media type of any request entity to the metadata
annotations on the resource classes and their methods.
The set of media type producible with the suitable methods and writers
is then matched against the requested media types to select the
combination of method and writer capable of generating the media-type
that matches the request best. If no matching method and writer can be
found then an appropriate error response is returned. The selection of
sub-resource methods, resource method and writer proceeds in four stages
as follows:
[...]
3. Identify the methods that can handle the request:
[...]
[drop end of section 3 starting at "(b) Sort M in descending order as
follows:"]
4. Select method and writer
*
Obtain the acceptable media types A. If A = {}, set A = {‘*/*’}
*
Set T = {}. For each method in M m
o
Gather the set of producible media types P :
+
If the method is annotated with @Produces, set P = {V
(method)} where V (t) represents the values of
@Produces on the specified target t.
+
Else if the class is annotated with @Produces, set P =
{V (class)}.
+
Else set P = {V (writers)} where ‘writers’ is the set
of MessageBodyWriter that support the class of the
returned entity object.
o
If P = {}, set P = {‘*/*’}
o
Set V = {}. For each member of A, a:
+
For each member of P, p:
#
If a is compatible with p, add S(a, p) to V ,
where the function S returns the most specific
media type of the supplied list.
o
For each member of V, v:
+
if the subtype of v is '*' set v to
‘application/octet-stream’
+
if m returns Response, GenericEntity or void set W =
to {null}, otherwise W = the set of suitable
MessageBodyWriter provider for v and m following
section 4.2.2.
+
For each member of W,w: add the triple (m,w, v) to T
*
Remove the members of W for which the writer is a pre-packaged
entity and another member of W contains the same media-type but an
application provided writer.
*
Calculate a compound q-value for each triple (m,w, v) in W as follow:
o
If the most concrete @Produces value compatible with v has a
q-value set mq to this value otherwise to 1.
o
If w is not null and the most concrete @Produces value (if
any) compatible with w has a q-value set mw to this value
otherwise to 1.
o
Determine the member of A compatible with v that has the
highest q value and set ma to this value
o
The compound q-value is the product of mq, mw and ma.
*
Sort the members of W using the compound q-value as primary key
and the type of the writer as secondary key, where
application-provided writer > null > pre-packaged writer
*
Process the request using the elements of the first member of W.
If if the writer is null it is determined after the method has
been invoked using the returned object. The steps of section 4.2.2
are followed, if no writer is found a WebApplicationException with
a not acceptable response (HTTP 406 status) and no entity MUST be
generated. The exception MUST be processed as described in section
3.3.4.
[ drop section 3.8]
[In Section 4.2.2]
[change 7. to]
7. Else if a suitable data handler can be found using the JavaBeans
Activation Framework create a MessageBodyWriter that uses this handler
to map the object to the entity body.
[drop 8. ]