Hi gravy, nyrose.
First I'll try to describe what I have:
A web application 'wp' which serves up XML content (from a CMS [Content Management System]), via a spring webservice, on the url http://cmcdev2018/wp/soapservices. This is the server. In order to obtain content from the CMS I need a valid session, which is obtained via a JSESSIONID cookie.
I have a secondary web application on my local machine, which wishes to talk to the above webapp to obtain xml content. This is the client. The client has previously authenicated itself with the web application 'wp' on cmcdev2018. In order to call the web service, I need to pass info that says I've authenticated myself. This done by passing the authenicated JSESSION id; via a cookie. Unfortunately, the spring CommonsHttpMessageSender doesn't read the cookies set on a the HttpClient it uses; so I extended the spring CommonsHttpMessageSender; to do this:
Code:
package com.bbc.cmc.services.spring;
import org.apache.commons.httpclient.methods.PostMethod;
import org.springframework.ws.transport.http.CommonsHttpConnection;
import org.springframework.ws.transport.WebServiceConnection;
import org.springframework.ws.transport.http.CommonsHttpConnection;
import java.io.IOException;
import org.apache.commons.httpclient.Cookie;
/**
*
* @author tooted31
*/
public class CommonsHttpMessageSender extends org.springframework.ws.transport.http.CommonsHttpMessageSender
{
public WebServiceConnection createConnection(String uri) throws IOException
{
CommonsHttpConnection conn = (CommonsHttpConnection)super.createConnection(uri);
PostMethod pm = conn.getPostMethod();
Cookie[] cookies = getHttpClient().getState().getCookies();
int numberOfCookies = cookies.length;
for(int i = 0;i<numberOfCookies;i++)
{
pm.addRequestHeader("Cookie",cookies[i].toString());
}
return conn;
}
}
In the client's application context I have the following configuration:
Code:
<bean id="webServiceTemplate" class="org.springframework.ws.client.core.WebServiceTemplate">
<property name="messageFactory">
<bean class="org.springframework.ws.soap.saaj.SaajSoapMessageFactory"/>
</property>
<property name="messageSender" ref="urlMessageSender"/>
<property name="marshaller" ref="getcontent_unmarshaller"/>
<property name="unmarshaller" ref="getcontent_marshaller"/>
<property name="defaultUri" value="http://cmcdev2018/wp/soapservices"/>
</bean>
<bean id="urlMessageSender" class="com.bbc.cmc.services.spring.CommonsHttpMessageSender"/>
<bean id="httpclient" class="org.apache.commons.httpclient.HttpClient" scope="prototype"/>
You can see from this client configuration. The webServiceTemplate is given the customized CommonsHttpMessageSender.
In the client's code which calls the web service on cmcdev2018's webapp 'wp'. I obtain the 'webServiceTemplate' from the application context, which is using my customized CommonsHttpMessageSender. I need set on the HttpClient, that the CommonsHttpMessageSender uses, the JSESSIONID cookie; before I call the web service via the template.marshalSendAndReceive(..). This is what the following code is doing:
Code:
WebServiceTemplate template = (WebServiceTemplate) context.getBean("webServiceTemplate");
// get the custom CommonsHttpMessageSender, of which I know there is only 1 set, and it is my custom CommonsHttpMessageSender
WebServiceMessageSender[] senders = template.getMessageSenders();
CommonsHttpMessageSender commons = (CommonsHttpMessageSender) senders[0];
// Build the JSESSIONID cookie I need to send to my web service
HttpServletRequest srequest = (HttpServletRequest) ((this.getPageContext()).getRequest());
javax.servlet.http.Cookie cookies[] = srequest.getCookies();
//Obtain a org.apache.commons.httpclient.HttpClient. And set the JSESSIONID cookie on a HttpState object.
HttpClient client = (HttpClient) context.getBean("httpclient");
HttpState state = new HttpState();
for (int i = 0; i < cookies.length; i++) {
javax.servlet.http.Cookie c = cookies[i];
if (c.getName().equals("JSESSIONID")) {
org.apache.commons.httpclient.Cookie newCookie = new org.apache.commons.httpclient.Cookie();
newCookie.setDomain(c.getDomain());
newCookie.setPath(c.getPath());
newCookie.setName(c.getName());
newCookie.setValue(c.getValue());
state.addCookie(newCookie);
}
}
state.setCookiePolicy(org.apache.commons.httpclient.cookie.CookiePolicy.COMPATIBILITY);
client.setState(state);
commons.setHttpClient(client);
After the above code on the client I just call the WebServiceTemplate.marshallSendAndRecieve(..) method to call the webservice.
All the above code to Set the cookie on a the HttpClient object used by the CommonsHttpMessageSender should really be made into a utility/factory method.
I hope that makes it easier to understand.
/dom