Re: Implementing a two pass HttpEntity
On Mon, 2015-02-09 at 19:55 +0100, Michael Osipov wrote: Am 2015-02-09 um 14:26 schrieb Oleg Kalnichevski: On Sun, 2015-02-08 at 22:26 +0100, Michael Osipov wrote: Hi folks, I am in a need to implement a two-pass HttpEntity. This is related to my previous question [1]. Say, I have a PayloadEntity which extends StringEntity and contains XML content. This is being put into the HttpPost. Unfortunately, this isn't enough for a complete request. I need to wrap that with a RequestEnvelope entity. My idea was to do that with an request interceptor which would do new RequestEnvelopeEntity(String xml, PayloadEntity payload)... The interceptor would add some specific information to the envelope entity which are bound to a session and pooled by Commons Pool. The template for that is always: Envelope session information from pool... Body![CDATA[${payload}]] /Body /Envelope Note: No, this is not SOAP, this is a custom, braindead, sort of RPC over REST protocol. My first idea was to have both extend StringEntity and filter the payload as in a two-pass Velocity template. The issue is that #getContent returns an input stream backed by a byte array which I would need to convert back to a string, filter the template and pass the string which in turn would be converted to a byte array. Not very smart and waste of operations. Preconditions are that PayloadEntity is complete, the XML string passed to RequestEnvelopeEntity is already complete but for the ${payload}. Filtering is performed by org.apache.commons.lang3.text.StrSubstitutor. The best approach I came up with is to abuse the PayloadEntity as a container and add a #getPayload method. I would get the string here, pass that to the filter, consume the getContent stream and construct a new StringEntity, avoiding a custom RequestEnvelopeEntity in the interceptor. Any (better) ideas? Thanks, Michael Michael Is there any good reason for using two phase approach to generating entity content? What exactly are you winning by doing so? My intention is to leave session handling off the client code and have the interceptor set appropriate headers and the runtime information to the request envelope. The approach I am using for this would a custom session objected described here: http://www.mail-archive.com/user@commons.apache.org/msg09844.html I should be completely opaque to the repository code. Does that make sense or do you think the interceptor is just overhead? The altenative would be that I write some prive method in my repo which does all that, not very elegant. Protocol interceptors work well when one needs to apply a binary content transformation such as content compression / decompression. They are less convenient for pattern search and replace operations. However, at the end of the day it is a matter of personal taste. Both approaches have advantages and disadvantages. Oleg Michael - To unsubscribe, e-mail: httpclient-users-unsubscr...@hc.apache.org For additional commands, e-mail: httpclient-users-h...@hc.apache.org - To unsubscribe, e-mail: httpclient-users-unsubscr...@hc.apache.org For additional commands, e-mail: httpclient-users-h...@hc.apache.org
Re: Implementing a two pass HttpEntity
Am 2015-02-09 um 14:26 schrieb Oleg Kalnichevski: On Sun, 2015-02-08 at 22:26 +0100, Michael Osipov wrote: Hi folks, I am in a need to implement a two-pass HttpEntity. This is related to my previous question [1]. Say, I have a PayloadEntity which extends StringEntity and contains XML content. This is being put into the HttpPost. Unfortunately, this isn't enough for a complete request. I need to wrap that with a RequestEnvelope entity. My idea was to do that with an request interceptor which would do new RequestEnvelopeEntity(String xml, PayloadEntity payload)... The interceptor would add some specific information to the envelope entity which are bound to a session and pooled by Commons Pool. The template for that is always: Envelope session information from pool... Body![CDATA[${payload}]] /Body /Envelope Note: No, this is not SOAP, this is a custom, braindead, sort of RPC over REST protocol. My first idea was to have both extend StringEntity and filter the payload as in a two-pass Velocity template. The issue is that #getContent returns an input stream backed by a byte array which I would need to convert back to a string, filter the template and pass the string which in turn would be converted to a byte array. Not very smart and waste of operations. Preconditions are that PayloadEntity is complete, the XML string passed to RequestEnvelopeEntity is already complete but for the ${payload}. Filtering is performed by org.apache.commons.lang3.text.StrSubstitutor. The best approach I came up with is to abuse the PayloadEntity as a container and add a #getPayload method. I would get the string here, pass that to the filter, consume the getContent stream and construct a new StringEntity, avoiding a custom RequestEnvelopeEntity in the interceptor. Any (better) ideas? Thanks, Michael Michael Is there any good reason for using two phase approach to generating entity content? What exactly are you winning by doing so? My intention is to leave session handling off the client code and have the interceptor set appropriate headers and the runtime information to the request envelope. The approach I am using for this would a custom session objected described here: http://www.mail-archive.com/user@commons.apache.org/msg09844.html I should be completely opaque to the repository code. Does that make sense or do you think the interceptor is just overhead? The altenative would be that I write some prive method in my repo which does all that, not very elegant. Michael - To unsubscribe, e-mail: httpclient-users-unsubscr...@hc.apache.org For additional commands, e-mail: httpclient-users-h...@hc.apache.org
Re: Implementing a two pass HttpEntity
On Sun, 2015-02-08 at 22:26 +0100, Michael Osipov wrote: Hi folks, I am in a need to implement a two-pass HttpEntity. This is related to my previous question [1]. Say, I have a PayloadEntity which extends StringEntity and contains XML content. This is being put into the HttpPost. Unfortunately, this isn't enough for a complete request. I need to wrap that with a RequestEnvelope entity. My idea was to do that with an request interceptor which would do new RequestEnvelopeEntity(String xml, PayloadEntity payload)... The interceptor would add some specific information to the envelope entity which are bound to a session and pooled by Commons Pool. The template for that is always: Envelope session information from pool... Body![CDATA[${payload}]] /Body /Envelope Note: No, this is not SOAP, this is a custom, braindead, sort of RPC over REST protocol. My first idea was to have both extend StringEntity and filter the payload as in a two-pass Velocity template. The issue is that #getContent returns an input stream backed by a byte array which I would need to convert back to a string, filter the template and pass the string which in turn would be converted to a byte array. Not very smart and waste of operations. Preconditions are that PayloadEntity is complete, the XML string passed to RequestEnvelopeEntity is already complete but for the ${payload}. Filtering is performed by org.apache.commons.lang3.text.StrSubstitutor. The best approach I came up with is to abuse the PayloadEntity as a container and add a #getPayload method. I would get the string here, pass that to the filter, consume the getContent stream and construct a new StringEntity, avoiding a custom RequestEnvelopeEntity in the interceptor. Any (better) ideas? Thanks, Michael Michael Is there any good reason for using two phase approach to generating entity content? What exactly are you winning by doing so? Oleg - To unsubscribe, e-mail: httpclient-users-unsubscr...@hc.apache.org For additional commands, e-mail: httpclient-users-h...@hc.apache.org