Hi Anthony
On 05/07/12 12:50, Muller, Anthony wrote:
Thx Sergey, that seems fine!

I'm trying using UriInfo injection and I'm trying to detect the case where I 
must lock my resource.

I hope to get the {bookId} easily, but there is nothing into path parameters... 
Normal?

I wrote something like:

@Override
public Response handleRequest(final Message m, final ClassResourceInfo 
resourceClass) {
        System.out.println("BookHandler.handleRequest: " + uriInfo.getPath());
        
        if(uriInfo.getPath().contains("/books/")) {
                final MultivaluedMap<String, String>  pathParameters = 
uriInfo.getPathParameters();
                final Set<String>  pathParameterNames = pathParameters.keySet();
                for (final String pathParameterName : pathParameterNames) {
                        System.out.println(pathParameterName + " : " + 
pathParameters.getFirst(pathParameterName));
                }       
        }
        
        return null;
}


I'm looking at the CXF code and I can confirm that the operation matching is attempted before the filters are run. So if you have a method such as

@POST
@Path("{index}")
public void addBook(@PathParam("index") int index, Book book) {}

and a request URI ending with something like /books/123

then UriInfo should return an "index":123 pair

Can you confirm please that in your above case the request URI is expected to match a method with @PathParam annotations ?

By the way, perhaps there's one option for this case.
Instead of doing the filters, consider creating a custom invoker which gets the control immediately before and after the matched method is invoked. For example:

http://svn.apache.org/repos/asf/cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/CustomJAXRSInvoker.java

Custom invokers are registered using a jaxrs:invoker extension. However, I recall you might be using CXFNonSpringJaxrsServlet - so is not possible to register invokers from this servlet yet unless you extend the servlet class and set the invoker on JAXRSServerFactoryBean. I'll get this specific issue fixed,

But using the filters should also do OK

Sergey




-----Original Message-----
From: Sergey Beryozkin [mailto:[email protected]]
Sent: jeudi 5 juillet 2012 12:49
To: [email protected]
Cc: Muller, Anthony
Subject: Re: JAX-RS services - Interceptor

Hi Anthony
On 05/07/12 11:17, Muller, Anthony wrote:
Hello,

I have a use case when I need to intercept some REST calls to lock a used 
resource (underlying code doesn't support concurrent access). I wish to use an 
CXF interceptor to implement the lock mechanism (something else can help ?)

Example of concurrent calls:
Client 1 : [POST]<baseurl>/books/1234/chapters/ -->   Book<  1234>  must be 
locked to avoid concurrent modifications
Client 2 : [POST]<baseurl>/books/1234/chapters/56/paragraph -->   Webservice must 
wait because book<  1234>  is currently locked

So, I wish to add a CXF interceptor on URL starting by<  /books/{bookId}/...>, 
but I don't see how can I do...

(In my case, I can not use Servlet API...)


I think the simplest way is to create a class implementing both
RequestHandler and ResponseHandler interfaces and have a '@Context
UriInfo' injected (which is thread safe).

You can use UriInfo.getPath() method to get values like
'books/1234/chapters', etc.  Perhaps, even simpler, is to do
RequestHandler'message.get(Message.REQUEST_URI)', where 'message' is of
type Message and is available as a method parameter.

This implementation will 'lock' by updating the concurrent cache of some
sort (Colm done few Ehcache based implementations in CXF for example) in
its handleRequest method and 'unlock' in its handleResponse if it is
'books/1234/chapters'. It can be registered as a jaxrs:provider



Hope that helps :-)

Sergey

Can you help ?

Thanks and regards,
Anthony




Reply via email to