Monday, October 6, 2008

Axis2 - Setting custom HTTP Headers on a response

There may be instances where users would want to add a custom HTTP header to the response message in Apache Axis2. The following shows how this could be achieved,

MessageContext responseMessageContext =
MessageContext.getCurrentMessageContext().getOperationContext().getMessageContext(
WSDLConstants.MESSAGE_LABEL_OUT_VALUE);
List headers = new ArrayList();
headers.add(new Header(HTTPConstants.HEADER_CONTENT_ENCODING, "identity"));
responseMessageContext.setProperty(HTTPConstants.HTTP_HEADERS, headers);

This method could be used to add multiple headers to the response message. This also should how a service could get hold of the response message context.

17 comments:

Anonymous said...

Thank you Keith. Your blog helped me at time. I was searching for help to set the SOAP Header on axis2 response.

Unknown said...

Why not use the TRANSPORT_HEADERS property in the msg ctx to set the response headers as well. The axis2 http sender can just read the values from this property and add it to the underlying HTTPClient as HTTPHeader instances instead of exposing this detail to the user. To me this seems like a case of Leaky Abstraction (http://en.wikipedia.org/wiki/Leaky_abstraction)

indian said...

Hi,Keith, i ned to edit the Content-Type header of the request message. Currently the Content-Type is text/xml as oi am using soap 1.1. But i want to change it to application/x-gzip while sending the request as the .NET client expects the Content-type header to be "application/x-gzip" instead of text/xml. I tried adding a header as per your logic but it as adding another Content-Type header with "application/x-gzip" as value causing duplicate header problem. Could you please let me know how to override the Content-Type header in my soap request using axis2 ADB generated stub without having a duplicate header? You can mail me at naveenkvm"@gmail.com

Thanks,
naveen

indian said...

i am using axis2 1.4.1

indian said...

thanks in advance for your help.

indian said...

org.apache.axis2.AxisFault: Transport error: 415 Error: Cannot process the message because the content type 'text/xml; charset=UTF-8' was not the expected type 'application/x-gzip'.


This is the eror i ma getting.

Keith Chapman said...

Well this is a special case and just setting the content-type header to application/x-gzip will not help. Cause the content-type header describes the format of the message hence of u are setting the contentType to application/x-gzip you would want the request to be compressed.

indian said...

Hi Ketih, thanks for reply. My problem is i am getting the following error if i don't add a header for content-Type with value application/x-gzip.

org.apache.axis2.AxisFault: Transport error: 415 Error: Cannot process the message because the content type 'text/xml; charset=UTF-8' was not the expected type 'application/x-gzip'.


But if i add a header for Content-Type with a value "application/x-gzip" ,i am getting bad request error becoz of duplicate header for Content-Type.


Is there anyway for me to override the content type header value?

I have already enabled the gzip compression and it is compressing the body with gzip encoding correctly ni the request.

serviceClient.getOptions().setProperty(org.apache.axis2.transport.http.HTTPConstants.MC_ACCEPT_GZIP, Boolean.TRUE);
_serviceClient.getOptions().setProperty(org.apache.axis2.transport.http.HTTPConstants.MC_GZIP_REQUEST, Boolean.TRUE);
_serviceClient.getOptions().setProperty(org.apache.axis2.transport.http.HTTPConstants.MC_GZIP_RESPONSE, Boolean.TRUE);

_operationClient.getOperationContext().getMessageContext(
WSDLConstants.MESSAGE_LABEL_OUT_VALUE).setProperty(org.apache.axis2.transport.http.HTTPConstants.HEADER_ACCEPT_ENCODING, "gzip");
_operationClient.getOperationContext().getMessageContext(
WSDLConstants.MESSAGE_LABEL_OUT_VALUE).setProperty(org.apache.axis2.transport.http.HTTPConstants.HEADER_CONTENT_ENCODING, "gzip");

Is there anyway to override the Content-type header with a value "application/x-gzip"?

I am running my webservice with axis2 1.4.1 and tomcat as unit test container.

Thanks for your help.

indian said...

Sorry for the mistake while posting my code. It is:

_operationClient.getOperationContext().getMessageContext(WSDLConstants.MESSAGE_LABEL_OUT_VALUE).setProperty(org.apache.axis2.transport.http.HTTPConstants.MC_ACCEPT_GZIP, Boolean.TRUE);
_operationClient.getOperationContext().getMessageContext(WSDLConstants.MESSAGE_LABEL_OUT_VALUE).setProperty(org.apache.axis2.transport.http.HTTPConstants.MC_GZIP_REQUEST, Boolean.TRUE);
_operationClient.getOperationContext().getMessageContext(WSDLConstants.MESSAGE_LABEL_OUT_VALUE).setProperty(org.apache.axis2.transport.http.HTTPConstants.MC_GZIP_RESPONSE, Boolean.TRUE);

_operationClient.getOperationContext().getMessageContext(WSDLConstants.MESSAGE_LABEL_OUT_VALUE).setProperty(org.apache.axis2.transport.http.HTTPConstants.HEADER_ACCEPT_ENCODING, "gzip");
_operationClient.getOperationContext().getMessageContext(WSDLConstants.MESSAGE_LABEL_OUT_VALUE).setProperty(org.apache.axis2.transport.http.HTTPConstants.HEADER_CONTENT_ENCODING, "gzip");

Regards,
Naveen.

indian said...

_operationClient.getOperationContext().getMessageContext(
WSDLConstants.MESSAGE_LABEL_OUT_VALUE).setProperty(
org.apache.axis2.transport.http.HTTPConstants.MC_ACCEPT_GZIP,
Boolean.TRUE);
_operationClient.getOperationContext().getMessageContext(
WSDLConstants.MESSAGE_LABEL_OUT_VALUE).setProperty(
org.apache.axis2.transport.http.HTTPConstants.MC_GZIP_REQUEST,
Boolean.TRUE);
_operationClient.getOperationContext().getMessageContext(
WSDLConstants.MESSAGE_LABEL_OUT_VALUE).setProperty(
org.apache.axis2.transport.http.HTTPConstants.MC_GZIP_RESPONSE,
Boolean.TRUE);

_operationClient
.getOperationContext()
.getMessageContext(WSDLConstants.MESSAGE_LABEL_OUT_VALUE)
.setProperty(
org.apache.axis2.transport.http.HTTPConstants.HEADER_ACCEPT_ENCODING,
"gzip");
_operationClient
.getOperationContext()
.getMessageContext(WSDLConstants.MESSAGE_LABEL_OUT_VALUE)
.setProperty(
org.apache.axis2.transport.http.HTTPConstants.HEADER_CONTENT_ENCODING,
"gzip");



My problem is that the .NET client doesn't accept the content-type other than "application/x-gzip". For any other content-type it is throwing exception.

So Content-Type header needs to be changed for the .NET client to receive my request and give response.

indian said...

Also my request soap message has no attachments.

indian said...

Hi Keith,

Any idea on how to override the Content-type Header?

Regards,
Naveen.

Unknown said...

Hi Keith,
the request message is sent as soap xml with media type as application/x-gzip. It's sending chunked response also. But i want it to send only compressed request instead of soap request. I made all req settigns in client and server code.

Noherceykar said...

Hi Keith,

I need to add few custome http headers to the request. How to do so with Axis2. I have got the java stubs by running wsdl2java.

Thanks
Irum

sriraj said...

Thank you for the post. This helped me a lot

Smoothe19 said...
This comment has been removed by the author.
Smoothe19 said...

Keith i hope you still look at this blog.. How can i use axis2 to send an http header that contains an sso cookie?