users@jax-rs-spec.java.net

[jax-rs-spec users] Re: _at_Logged deep binding

From: Alex Rojkov <alex_at_caucho.com>
Date: Wed, 6 Feb 2013 11:09:55 -0800

>>>
>>>>>>> IMO it should.
>>>>>>
>>>>>> Thanks. I am adding conditional return to MyResourceClass#hello.
>>>>>>
>>>>>> MyResourceClass#hello may return any implementation of Foo. Some implementations may not be annotated with @Logged.
>>>>>>
>>>>>> Can you explain how a jaxrs implementation can determine that LogginFilter should be invoked?
>>>>>
>>>>> By introspecting the Java type of the returned sub-resource instance. Since this is a potentially processing-intensive operation, the implementations may consider caching the introspection results for future use.
>>>>
>>>> I see. That means filters can be invoked between resources / sub resource method invocations. Appendix C suggests that filters are invoked before any resource method invocations.
>>>
>>> Not sure what you mean by "filters can be invoked between resources / sub resource method invocations". Note that subresource locators are part of JAX-RS request-to-resource method matching facility and following is the only possible scenario for any matched request:
>>>
>>> request -> [subresource-locator [-> ... -> subresource-locator] -> ] resource method
>>>
>>> The above demonstrates that zero or more sub-resource locators may be invoked as part of the request URI matching process. If we add filters into picture, we get:
>>>
>>> request -> pre-match filters -> [subresource-locator [-> ... -> subresource-locator] -> ] post-match global & name-bound filters -> resource method
>>>
>>> The name-bound filters are selected based on the resource method and it's owner instance that was matched to ultimately handle the request (with or without help of sub-resource locators).
>>>
>>>> IMO, the spec needs to be more clear about Filter contract.
>>>
>>> It would be good if you could come up with concrete suggestions for improvements. It's hard to see what does "more clear" mean in general.
>>
>> Sure. How about adding the below to clarify:
>>
>> – post-match global filters are invoked before any of the root-resource methods are called.
>> – name bound filters are invoked before a bound method is called.
>
> Have you seen the Appnedix C in the spec? The processing pipeline diagram is there.

Yes, I have. It suggests that ContainerRequest chain is completed before Method Invocation. It means to me that ContainerRequest chain is completed before the vert first method invocation (method on a root-resource).

>>
>> IMO, the current wording in the spec suggests that all filters (including the method bound filters) finish executing before root-resource is invoked.
>
> What does it mean "before root-resource is invoked"??? JAX-RS root resource is an instance of a class, it cannot be invoked.

It means "Before a matched method on root-resource is invoked".

Now, that we spell everything out, I think that spec needs to introduce a method filter (not request filter). Name *RequestFilter suggests that the filter is invoked on RequestContext before any processing takes place.

@Logged at FooBean can only be resolved *after* a round of invocation takes place.

It would be nice to abstract this behaviour in a totally new class MethodFilter or something like that. And make *RequestFilter use idiomatic with use of Filters in Servlet spec. ( I believe this was the idea originally )

Alex

>
> Marek
>
>>
>> Alex
>>
>>>
>>> Marek
>>>
>>>>
>>>> Alex
>>>>>
>>>>> HTH,
>>>>> Marek
>>>>>
>>>>>>
>>>>>> Thanks,
>>>>>> Alex
>>>>>>
>>>>>>>
>>>>>>> Marek
>>>>>>>
>>>>>>> On Feb 5, 2013, at 3:59 AM, Alex Rojkov <alex_at_caucho.com> wrote:
>>>>>>>
>>>>>>>> Hi All,
>>>>>>>>
>>>>>>>> Given the mapping below, should LoggingFilter get invoked?
>>>>>>>>
>>>>>>>> @Provider
>>>>>>>> @Logged
>>>>>>>> class LoggingFilter implements ContainerRequestFilter,
>>>>>>>> ContainerResponseFilter {
>>>>>>>> …
>>>>>>>> }
>>>>>>>>
>>>>>>>> @Path("/")
>>>>>>>> public class MyResourceClass {
>>>>>>>> @Path("{name}")
>>>>>>>> public Foo hello(@PathParam("name") String name) {
>>>>>> if (name.contains("bogus"))
>>>>>> return new FooBean2();
>>>>>> else
>>>>>>>> return new FooBean();
>>>>>>>> }
>>>>>>>> }
>>>>>>>>
>>>>>>>> public interface Foo {
>>>>>>>> }
>>>>>>>>
>>>>>>>> public class FooBean implements Foo {
>>>>>>>> @Logged
>>>>>>>> @GET
>>>>>>>> public String hello() {
>>>>>>>> return "FooBean[]";
>>>>>>>> }
>>>>>>>> }
>>>>>>
>>>>>> public class FooBean2 implements Foo {
>>>>>> @GET
>>>>>> public String hello() {
>>>>>> return "FooBean2[]";
>>>>>> }
>>>>>> }
>>>>>>
>>>>>>>>
>>>>>>>> Thanks,
>>>>>>>> Alex
>>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>
>>>>>
>>>>>
>>>>
>>>
>>
>