Page 1 of 2 12 LastLast
Results 1 to 10 of 16

Thread: JSESSIONID and setting cookie for WebServiceTemplate

  1. #1
    Join Date
    Dec 2007
    Posts
    3

    Default JSESSIONID and setting cookie for WebServiceTemplate

    Our existing application (Documentum CMS) Web App, has it's own authenication system which authenticates users; after the initial login the JSESSIONID in the cookie is the key way in which it authenticates users. We can then work with the CMS as that user.

    What I'm trying to do is call a Spring Web Service (within the same webapp), from a Page within the Documentum Web App. The Web Service I'm calling is a simple service that returns content from the CMS to the user. In order to obtain the content; we need to obtain the JSESSIONID.

    However, I cannot figure out how to set the JSESSIONID in a cookie on the WebServiceTemplate's MessageSender.

    The message sender is of type CommonsHttpMessageSender, on which I've obtained the HttpClient and set on the HttpState the cookies from the original request (including the JSESSIONID).

    However, when the doService(...) of MessageDispatcherServlet, the request object it has access to hasn't got any cookies set on it; and the HttpSession is new, and not the session that the JSESSIONID from the originating request references.

    Basically the HttpServletRequest of the MessageDispatcherServlet I which to have the same HttpSession as the one the WebServiceTemplate's marshalSendAndReceive is called from.

    I'm a bit stumped on how to do it. Can anyone help?

    Using Tomcat 5.5, Spring 2.5, Spring WS 1.02, Apache Http Commons 3.1

    Thanks Dom

  2. #2
    Join Date
    Dec 2007
    Posts
    3

    Default

    I had another play around with this today, and got it to work by extending the CommonsHttpMessageSender as follows:

    public class CommonsHttpMessageSender extends org.springframework.ws.transport.http.CommonsHttpM essageSender
    {

    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;
    }
    }

    The cookie is now set when the request is sent from the WebServiceTemplate's marshalSendAndReceive(...) method. The doService on MessageDispatcherServlet now has access to the cookie, and the correct (already authenicate) HttpSession is being returned from the HttpServletRequest.getSession() rather than a new one created...


    code on the client side before the marshalSendAndRecieve() is the same as I had before subclassing CommonsHttpMessageSender:

    WebServiceMessageSender[] senders = template.getMessageSenders();

    CommonsHttpMessageSender commons = (CommonsHttpMessageSender) senders[0];
    HttpServletRequest srequest = (HttpServletRequest) ((this.getPageContext()).getRequest());
    javax.servlet.http.Cookie cookies[] = srequest.getCookies();


    HttpClient client = (HttpClient) SpringAppContextMgr.getWebServiceBean("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.httpclien t.cookie.CookiePolicy.COMPATIBILITY);


    client.setState(state);
    commons.setHttpClient(client);

  3. #3
    Join Date
    Sep 2007
    Posts
    14

    Default

    Hello,

    i want to do something similar. At first time, when client connects to service it has no JSESSIONID. Server creates session, and responses with JSESSIONID stored in response cookie. Next calls to web services are identified using created JSESSIONID.

    I created custom MessageSender like you. My question is, where to put this code:

    Code:
    WebServiceMessageSender[] senders = template.getMessageSenders();
    
    CommonsHttpMessageSender commons = (CommonsHttpMessageSender) senders[0];
    HttpServletRequest srequest = (HttpServletRequest) ((this.getPageContext()).getRequest());
    javax.servlet.http.Cookie cookies[] = srequest.getCookies();
    
    
    HttpClient client = (HttpClient) SpringAppContextMgr.getWebServiceBean("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.httpclien t.cookie.CookiePolicy.COMPATIBILITY);
    
    
    client.setState(state);
    commons.setHttpClient(client);
    Thanks

  4. #4
    Join Date
    Dec 2007
    Posts
    3

    Default Apologies, I'll try to clear up any misunderstandings

    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

  5. #5
    Join Date
    Sep 2007
    Posts
    14

    Default

    Hi Dom,

    thx for answer, it is clear to me now what u meaned. In meanwhile i figured what i wanted. I wanted to create session for ws client. I did it by subclassing MessageDispatcherServlet and opening a session on accepted request in servlet's doService method. Now when the client connects to the service for the first time, server creates session for him, and when i use more calls with the same client, the cookie JsessionId is set By the way, i used CommonsHttpMessageSender and he sends all cookies that have been set. I only needed to setMessageSender into my client. Your code will be needed for authenticating different instances of clients in the same session.

    Thanks

    Gravy

  6. #6
    Join Date
    May 2008
    Posts
    3

    Default

    Hi gravy,

    How do you access the session id from within the service end point?

  7. #7
    Join Date
    Sep 2007
    Posts
    14

    Default

    I do not access it in the endpoint, i can access it in the DispatcherServlet's doService method. I don't know if/how it can be accessed in the endpoint.

    Gravy

  8. #8
    Join Date
    Oct 2008
    Posts
    19

    Default

    Hey Gravy,

    After opening a session in the doService method, how did you reference it or get a handle to it in your Endpoint class?

    thanks

  9. #9
    Join Date
    Oct 2008
    Posts
    19

    Default

    ok, I think I know what u did. thanks.

  10. #10
    Join Date
    Sep 2007
    Posts
    14

    Default

    Ok, im happy

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •