dev@jersey.java.net

Re: [Jersey] How to get encoded entity in filter?

From: Paul C. Bryan <pbryan_at_sun.com>
Date: Tue, 12 May 2009 08:45:21 -0700

Right, as it's serialized. I don't see a way to get the entity in its
encoded form when in the handle() method.

So, I could assume the entity is a MultivaluedMap, which I think the
majority of the time, it will be when it's POST
application/x-www-form-urlencoded. But it could be other types, up to
the caller of the client library, correct? For example, String
(pre-encoded) seems to work if I pass that in as the entity to the
client library.

What I'm trying to do: I want to get the entity body to extract form
parameters, in order to calculate a digital signature.

I considered just assuming it's MultivaluedMap, and throwing exception
otherwise, but was hoping there could be a way I could get the encoded
entity (which I would then decode) to allow virtually any object type to
be provided -- flexibility.

Thoughts?

On Tue, 2009-05-12 at 17:28 +0200, Paul Sandoz wrote:
> On May 12, 2009, at 5:15 PM, Paul C. Bryan wrote:
>
> > Thanks for the info.
> >
> > My apologies, I wasn't clear, in my case I was referring to Jersey
> > client filter. The client logging filter only reports on the response
> > entity, not the request entity.
>
> It reports both. The request side of the filter sets a
> ClientRequestAdapter to log the output as it is being serialized.
>
>
> > What's the easy way to get the entity
> > there?
> >
>
> ClientRequest.getEntity();
>
> https://jersey.dev.java.net/nonav/apidocs/1.1.0-ea/jersey/com/sun/jersey/api/client/ClientRequest.html
> #getEntity()
>
> Since the entity of the request will be an object, you can check in
> this case for an instance of the form type you are utilizing,
> essentially/ an instance of MultivaluedMap.
>
> If you need access to this entity to do something specific with it
> then you are going to have to make some assumptions about the type.
> Difficult for me to offer advice in this respect without knowing more
> about what you want to do with the entity.
>
> Paul.
>
> > Paul
> >
> > On Tue, 2009-05-12 at 11:15 +0200, Paul Sandoz wrote:
> >> On May 12, 2009, at 2:33 AM, Paul C. Bryan wrote:
> >>
> >>> What is the best way to access the request entity when a filter is
> >>> invoked?
> >>>
> >>> A bit of background:
> >>>
> >>> 1. The filter needs to access the entity because it may be POST of
> >>> application/x-www-form-urlencoded content.
> >>>
> >>> 2. The filter probably shouldn't assume the object type of the
> >>> entity
> >>> (e.g. MultivaluedMapImpl), because any type of Java object could
> >>> represent the message body, to be encoded in a deeper layer
> >>> (MessageBodyWriter?)
> >>>
> >>
> >> Correct.
> >>
> >>
> >>> So, what's the best way to get the encoded version of the entity in
> >>> the
> >>> filter handle method, without inadvertently changing other states
> >>> (e.g.
> >>> prematurely writing headers, etc.)?
> >>>
> >>> Alternately, is it a safe enough assumption that POST of
> >>> x-www-form-urlencoded will ALWAYS have an entity type of
> >>> MultivaluedMapImpl?
> >>>
> >>
> >> No. Because it may be processed as a String for byte[] if say the
> >> request is forwarded to something else.
> >>
> >> The best way is on a POST request with the content type
> >> "application/x-
> >> www-form-urlencoded" is to buffer the request entity to a byte array,
> >> the logging filter does this:
> >>
> >> https://jersey.dev.java.net/nonav/apidocs/1.1.0-ea/jersey/com/sun/jersey/api/container/filter/LoggingFilter.html
> >>
> >> public ContainerRequest filter(ContainerRequest request) {
> >> // Check if a POST and a content type of "application/x-www-
> >> form-urlencoded"
> >>
> >> ByteArrayOutputStream out = new ByteArrayOutputStream();
> >> InputStream in = request.getEntityInputStream();
> >> try {
> >> // Buffer the request
> >> int read;
> >> final byte[] data = new byte[2048];
> >> while ((read = in.read(data)) != -1)
> >> out.write(data, 0, read);
> >>
> >> byte[] requestEntity = out.toByteArray();
> >> ByteArrayInputStream bais = new
> >> ByteArrayInputStream(requestEntity));
> >> request.setEntityInputStream(bais);
> >>
> >> // Get the request as an instance of Form
> >> Form f = request.getEntity(Form.class);
> >> // Do some checking
> >>
> >> // reset the input stream so it can be re-read
> >> bais.reset();
> >>
> >> return request;
> >> } catch (IOException ex) {
> >> throw new ContainerException(ex);
> >> }
> >>
> >> }
> >>
> >>
> >> What i think the above implies is we could make it easier to perform
> >> such operations.
> >>
> >> Paul.
> >>
> >> ---------------------------------------------------------------------
> >> To unsubscribe, e-mail: dev-unsubscribe_at_jersey.dev.java.net
> >> For additional commands, e-mail: dev-help_at_jersey.dev.java.net
> >>
> >
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: dev-unsubscribe_at_jersey.dev.java.net
> > For additional commands, e-mail: dev-help_at_jersey.dev.java.net
> >
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe_at_jersey.dev.java.net
> For additional commands, e-mail: dev-help_at_jersey.dev.java.net
>