1

My service:

@POST
public String setData(@QueryParam("id") Long is, MyObject payload) {
...
}

or

@POST
public String setData(@PathParam("id") Long is, MyObject payload) {
...
}

My interceptor on the server:

Object read(MessageBodyReaderContext context) throws IOException, WebApplicationException {

Class mypayloadtype = context.getType;

InputStream mypayloadinpustream = context.getInputStream();


Long myidparam = ???????? // how to get the query or path param here?

}

EDIT: To be a bit more concrete:

What I'd like to do is to grab the XML and store it based on the parameters in a separate audit system. Maybe PreProcessInterceptor / PostProcessInterceptor are the better choices?

Any hints or alternative ways to get the param when the xml is still available for preprocessing?

Miguel

Miguel ZP
  • 61
  • 1
  • 4
  • I wasn't under the impression that you were supposed to use an interceptor to do body deserialization; I thought that was done with a JAX-RS `MessageBodyReader` subclass, and that's not supposed to know about the _other_ arguments. That's what the main service method ought to know about dealing with. – Donal Fellows Feb 15 '13 at 20:47
  • I edited the question to make clear why I want to use an interceptor. – Miguel ZP Feb 20 '13 at 08:17

2 Answers2

1

I just stumbled over the same problem today. I needed the @PathParams and @QueryParams in the read() method and ended up with something like this:

public class MyInterceptor implements PreProcessInterceptor, MessageBodyReaderInterceptor
{
    private static ThreadLocal<UriInfo> uri = new ThreadLocal<UriInfo>();

    public ServerResponse preProcess(HttpRequest request, ResourceMethod method)
    {
         uri.set(request.getUri);
         ...
    }

    public Object read(MessageBodyReaderContext context)
    {
        String param = uri.get().getPathParameters().getFirst("myidparam");
        ...
    }
}

Although when thinking about it now - I'm not quite sure, if just using PreProcessInterceptor/PostProcessInterceptor will also do the trick for my (and maybe your) problem. I'll have another look tomorrow.

carstor
  • 11
  • 2
  • What a hack! Maybe PreProcessInterceptor/PostProcessInterceptor are the better choices. However I'd have to figure out how to get the payload from the HttpRequest without interfering the request processing... – Miguel ZP Feb 26 '13 at 09:13
0

I am not an expert on the topic but to me it seems as if the MessageBodyReaderContext interface does not really know if it is on the server or the client side, so it cannot expose the request or its parameters / path parts etc.

So as far as I know this is not possible.

If your code knows that it lives on the server side of the rest communication, maybe you can use a servlet filter to store the request in a ThreadLocal and then access it from there while the request is handled, somewhat similar to RequestContextFilter / RequestContextHolder from the spring framework? (Then the request object does not know anything about the annotations of your service, but instead one has to extract the information manually from the request. This means to have the same information in two places, so there has to be a better solution ...)

Edit: after looking at some examples I get the vague feeling that if you want to read the input stream to create an object and add path parameters to it, MessageBodyReaderInterceptor is simply not the way to go. Instead set up a MessageBodyReader which constructs the object from the request body data, and this then will be passed into the public String setData(@PathParam("id") Long is, MyObject payload), assuming that this method is annotated with a @Consumes which matches the @ConsumeMime annotation for the MessageBodyReader. There you might be able in the setData to set the missing id on the object read from the request body. Some examples related to this seem to be here: How to get full REST request body using Jersey? (but for Jersey, not jBoss :-/)

However I am not sure if that works for you, and I also feel I completely overestimated my ability to answer this question appropriately, so I hope someone more knowledgeable comes in with a better solution.

Community
  • 1
  • 1
Clemens Klein-Robbenhaar
  • 3,457
  • 1
  • 18
  • 27
  • Thanks Clemens for trying to clarify this. I think from the @ServerInterceptor annotations it would be possible to know on which side the interceptor is used. In case of a client reader interceptor I would expect always 0 query/path params as only payload is returned. – Miguel ZP Feb 14 '13 at 09:09
  • The interceptor sure knos on which side the code lives, but not the `MessageBodyReaderContext` is unfortunately agnostic to server/client side, and even if assuming the passed in context is a ` ServerMessageBodyReaderContext` does not help, as that class does not allow access to the request, either. I have to admit that I am no JBoss expert (not even a novice) and just send any answer in hope someone else comes along and say "I can do that better", but so far this did not work, sorry. – Clemens Klein-Robbenhaar Feb 14 '13 at 20:24