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 09:08:50 -0700

Unfortunately, the side effect of this would be that the headers would
already be written. Too late for me. :(

On Tue, 2009-05-12 at 12:06 -0400, Marc Hadley wrote:
> On May 12, 2009, at 11:45 AM, Paul C. Bryan wrote:
>
> > 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.
> >
> Ideally then you'd like to be able to get the entity after the message
> body writer has done its work. That way you'd always be working with a
> stream of bytes.
>
> Marc.
>
> >
> > 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
> >>
> >
> >
> > ---------------------------------------------------------------------
> > 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
>