jsr339-experts@jax-rs-spec.java.net

[jsr339-experts] Re: [jax-rs-spec users] Re: Need clarification on Section 6.7

From: Sergey Beryozkin <sberyozkin_at_talend.com>
Date: Fri, 1 Feb 2013 11:55:46 +0000

On 01/02/13 11:38, Marek Potociar wrote:
>
> On Jan 31, 2013, at 6:29 PM, Sergey Beryozkin<sberyozkin_at_talend.com> wrote:
>
>> On 31/01/13 16:57, Marek Potociar wrote:
>>> Hi Bill,
>>> I'm forwarding my recent reply to a similar question we received from
>>> TCK team:
>>>
>>> Global and globally name-bound filters and interceptors should be
>>> invoked for all responses. Resource and method name-bound interceptors
>>> should be invoked only for responses originated from the bound resource
>>> or resource method.
>>>
>>> I.e. if we define 2 groups of filters and interceptors based on their
>>> binding:
>>>
>>> G1: Global and globally name-bound (i.e. name-bound to the Application
>>> sub-class) response filters and interceptors
>>> - IMO the user intention with these is clearly to invoke them for ALL
>>> responses
>>>
>>> G2: Resource and method name-bound response filters and interceptors
>>> - IMO the user intention with these is to invoke them only for responses
>>> originated from a particular resource or method
>>>
>>
>> What are resource-bound filters, is it:
>>
>> @SomeName
>> class MyFilter...
>>
>> @SomeName
>> @Path("/root")
>> public class RootResource {
>> }
>>
>> Effectively MyFilter applies to all RootResource methods ?
>
> Yes, exactly.
>
>>
>>> With the groups defined above, here's what I think it should work
>>> (Santiago, please correct me if you think otherwise):
>>>
>>> UC1: Response returned from pre-matching filter:
>>> - G1 gets invoked
>>>
>>> UC2: Response produced by an ExceptionMapper from an exception that
>>> originated in a pre-matching filter:
>>> - G1 gets invoked
>>>
>>> UC3: Response returned from post-matching filter:
>>> - G2 + G1 gets invoked
>>>
>>> UC4: Response returned from matched resource method:
>>> - G2 + G1 gets invoked
>>>
>>> UC5: Response produced by an ExceptionMapper from an exception that
>>> originated in a matched resource method:
>>> - G2 + G1 gets invoked
>>>
>>> UC6: Response produced by an ExceptionMapper from an exception that
>>> originated in a response filter or interceptor processing a response to
>>> a matched request:
>>> - G2 + G1 gets invoked
>>>
>>> UC7: Response produced by an ExceptionMapper from an exception that
>>> originated in a response filter or interceptor processing a response to
>>> an unmatched request:
>>> - G1 gets invoked
>>>
>>> Additionally, there is a condition in the spec that prevents infinite
>>> loops for UC6 and UC7 (see 2nd paragraph in section 6.7 of the spec).
>>> So, to sum-up, here's the conceptual algorithm I have in mind:
>>>
>>> start request processing
>>> store G1 response filters and interceptors into the request context
>>> try {
>>> invoke pre-matching request filters
>>> match request
>>> if (request matched) {
>>> store G2 response filters and interceptors into the request context
>>> invoke global and bound post-matching request filters
>>> invoke resource method
>>> }
>>> invoke all response filters stored to the request context
>>> } catch (Exception ex) {
>>> try {
>>> map exception to response
>>> invoke all response filters stored to the request context
>>> } catch (Exception ex) {
>>> propagate exception to the hosting container
>>> }
>>> }
>>> exit request processing
>>>
>> I think it basically says that in Bill's (2) case all response filters are executed,
>> What about his case 3 though, I think it is UC6, UC7 points, still not clear what if the mapped response has to run through remaining filters or not, for example,
>>
>> A->B, A throws the exception, is B still given a chance to handle the mapped response ?
>
> I thought the algorithm above is also clear on that. For a mapped exception response, ALL applicable response filters are invoked (not only "remaining ones"). So, both, A and B are invoked.
>
> FWIW, throwing an exception from a filter is IMO not the programming model we should optimize for. Such exceptions should mostly indicate that there is a problem with the filter implementation as such.
>

Hmm..., both A and B are response filters, they are processing some
Response, A is first to process it and decides to throw an exception
(intentionally) - what I don't quite get is whether it means we have an
immediate 500, or, we try to map this A-originated exception and if the
mapping was successful, then let B a chance to handle this mapped
response, even though A thought it was an exception case...

I'm sorry if I'm slow :-), but I'm still a bit unclear.

thanks, Sergey

> HTH,
> Marek
>
>>
>> Thanks, Sergey
>>
>>
>>
>>> HTH,
>>> Marek
>>>
>>>
>>> On Jan 30, 2013, at 4:29 PM, Bill Burke<bburke_at_redhat.com
>>> <mailto:bburke_at_redhat.com>> wrote:
>>>
>>>> The section on filters and exception handling is unclear.
>>>>
>>>> if an exception is thrown from a resource method:
>>>>
>>>> 1. An exception mapper is found
>>>> 2. bound and global filters are executed on the response
>>>>
>>>> If an exception is thrown from a request filter:
>>>>
>>>> 1. An exception mapper is found and executed
>>>> 2. response filters are executed. BOund response filters only executed
>>>> if this is not prematch
>>>>
>>>> If an exception is thrown from a response filter:
>>>>
>>>> 1. An exception maper is found and executed
>>>> 2. ??? I assume no response filters are then executed?
>>>> --
>>>> Bill Burke
>>>> JBoss, a division of Red Hat
>>>> http://bill.burkecentral.com
>>>
>>
>>
>