On Mar 10, 2009, at 2:27 PM, Jaka Jančar wrote:
> On 10. Mar 2009, at 11:07, Paul Sandoz wrote:
>> On Mar 9, 2009, at 8:03 PM, Jaka Jančar wrote:
>>> On 9. Mar 2009, at 18:10, Paul Sandoz wrote:
>>>
>>> I can achieve it at Servlet level with either a custom servlet or
>>> a servlet filter, but I'd have to manually be parsing resource
>>> URLs, which I *REALLY* don't want. So that's why I want to do it
>>> *within* JAX-RS boundaries.
>>>
>>> Any ideas? Pretty please? :)
>>>
>>
>> You could obtain something from the servlet context that creates
>> and manages the EntityManager instances. The filter can then
>> cleanup those instances.
>>
>
> Yup, that solves the initialization nastiness, but it doesn't solve
> cleanup nastiness. E.g. any exceptions thrown while commiting the
> transaction get thrown outside JAX-RS and I have to manually build a
> 500 response, which should IMO always be Jersey's job.
>
>> For a more elegant solution you will need to use something Jersey
>> specific with resource specific filters, or use an IoC framework
>> like Spring+AOP.
>
> Hmm... resource specific filters. Looks _VERY_ interesting! I don't
> like that it's not standard, but neither would be my own
> implementation, so I might as well use it. And perhaps it one day
> becomes standard :)
>
> It seems this would also solve the above problem with exceptions
> during cleanup.
>
> I have a couple of questions regarding resource specific filters:
>
> 1)
> I'm looking at WebApplicationImpl and HttpMethodRule but am not
> entirely sure about the order of the execution of the filters.
>
> For example, when doing GET /first/second/third:
>
> - FirstResource.getSecondResource() (@Path("/second"))
> - SecondResource.getThirdResource() (@Path("/third"))
> - ThirdResource.handleGet() (@GET)
>
> Would this be the order of calls with filters added:
>
> - FirstResourceRequestFilter.filter()
> - FirstResource.getSecondResource()
> - SecondResourceRequestFilter.filter()
> - SecondResource.getThirdResource()
> - ThirdResourceRequestFilter.filter()
> - ThirdResource.handleGet()
> - FirstResourceResponseFilter.filter();
> - SecondResourceResponseFilter.filter();
> - ThirdResourceResponseFilter.filter();
>
The order is as follows:
- FirstResourceRequestFilter.filter()
- FirstResource.getSecondResource()
- SecondResourceRequestFilter.filter()
- SecondResource.getThirdResource()
- ThirdResourceRequestFilter.filter()
- ThirdResource.handleGet()
- ThirdResourceResponseFilter.filter();
- SecondResourceResponseFilter.filter();
- FirstResourceResponseFilter.filter();
See:
https://jersey.dev.java.net/source/browse/*checkout*/jersey/tags/jersey-1.0.2/api/jersey/com/sun/jersey/api/container/filter/package-summary.html
https://jersey.dev.java.net/source/browse/*checkout*/jersey/tags/jersey-1.0.2/api/jersey/com/sun/jersey/spi/container/ResourceFilterFactory.html
> If so, is there a way to reverse the Response filters?
>
> 2)
> Will Resource(Request|Response)Filters be added for resource classes
> annotated with @ResourceFilters which I instantiate myself in sub-
> resource locators?
>
Yes.
> If so, will multiple instances of the resource filter be added for
> multiple instances of the resource? That is, would request "GET /
> resource-of-class-a/resource-of-class-b/resource-of-class-a" add two
> instances of the filter defined for the class A? (this I don't
> actually need, but am just curious)
>
Yes.
> If so (heheh), is it possible for the resource specific filter
> instance to know because of which resource instance it was created?
>
Yes, if you use the ResourceFilterFactory:
https://jersey.dev.java.net/source/browse/*checkout*/jersey/tags/jersey-1.0.2/api/jersey/com/sun/jersey/spi/container/ResourceFilterFactory.html
>
> Thanks again, you've been extraordinarily helpful!
>
Thanks.
I think there may be just one issue. The response filter chain is
broken if an exception is thrown by a response filter.
In other discussion we need a way to handle "closeable" resources, a
bit like managing @PreDestroy on per-request resources. This is
something that is easy to do, have an injectable CloseableManager that
registers closeable instances for the request, that then get closed in
a finally block.
Paul.