axis-java-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Walker, Jeff" <Jeff.Wal...@fmr.com>
Subject RE: cookies for out-of-band data
Date Fri, 08 Jun 2007 13:42:24 GMT
Ouch!
I ran into this on my project too. I got one cookie to work well, but
multiple cookies simply do not work for me. There is some sort of
hashtable used, the HTTPConstants.HEADER_COOKIE constant is used as the
key, I think. If you try to add multiple cookies, then the value seems
to get overwritten. At least, that is the behavior I've noticed. Now,
below you also tried what I tried, that is, using the strange
HTTPConstants.HEADER_COOKIE2 constant for the 2nd cookie. But alas,
neither of us got the result we intended.

On the service side, my approach is somewhat different than yours. I
used a handler class that extends from JAXRPCHandler. In it, I set the
cookie on the response. The response carries the cookie back to the
client. I then use that in the next invocation call, as a way to keep a
seesion going.

In summary:
1. You're not supposed to use stateful web services. So, people like you
and I are 'up the creek'. Few people interested in helping with cookies.
2. One cookie defintiely works (my code below). Multiple cookies do not
seem possible.
3. There are three main approaches to cookies that I have seen:
   a). Use getProperty() and setProperty() on the MessageContext, which
is what axis seems to imply you need to do. It didn't work for me, not
even for one cookie.
   b). Then there are these strange classes in Axis:
org.apache.axis.transport.http.AxisHttpSession and
org.apache.axis.session.SimpleSession which implements
org.apache.axis.session.Session. No examples given, and I couldn't get
them to work, but I suspect they would help a lot with multiple cookies.
   c). Finally, there is my approach. See below.


My Objective:
To create a cookie on the service side first, pass it to a client and
then have the client pass it back in each subsequent method invocation
on the service interface.

Service side: Use a JAXRPCHandler
public class CookieHandler extends JAXRPCHandler {
	
  public static final String COOKIE_NAME1 = "JSESSIONID";
  public static final String COOKIE_VALUE1 = "09876Jeffrey";
  public static final String COOKIE_NAME2 = "GROUPID";
  public static final String COOKIE_VALUE2 = "JWalker-123PJ";

  public CookieHandler() {
    System.out.println("Inside CookieHandler.constructor.");
  }
    
  /**
   * The invoke will add the cookie to the outgoing response message
   */
  public void invoke(MessageContext context) throws AxisFault
  {    
    System.out.println("Inside of invoke()..");
    System.out.println((context.getPastPivot()) ? "	past pivot
point" : "	before pivot point");
    
    // If true, then we are dealing with response handling
    if (context.getPastPivot()) {
      context.setMaintainSession(true);
      HttpServletResponse resp =
(HttpServletResponse)context.getProperty(HTTPConstants.MC_HTTP_SERVLETRE
SPONSE);
      
      // 1st cookie
      Cookie cookie1 = new Cookie(COOKIE_NAME1, COOKIE_VALUE1);
      cookie1.setComment("Just a comment");
      cookie1.setMaxAge(10000);
      cookie1.setDomain("PaG");
      resp.addCookie(cookie1);
      
      // 2nd cookie - Doesn't work!
      //Cookie cookie2 = new Cookie(COOKIE_NAME2, COOKIE_VALUE2);
      //resp.addCookie(cookie2);
    }
    else {
      HttpServletRequest req =
(HttpServletRequest)context.getProperty(HTTPConstants.MC_HTTP_SERVLETREQ
UEST);
      if (req != null) {
        Cookie[] cookies = req.getCookies();
        if (cookies != null && cookies.length != 0) {
          // We got one or more cookies from the client in the request
          System.out.println("CookieHandler.invoke(): received cookies
are: ");
          for (int i = 0; i < cookies.length; i++) {
            System.out.println("		cookie = " +
cookies[i].getName() + ", value = " + cookies[i].getValue());
          }
        }
      }
    }
    System.out.println("leaving invoke().");
 }
	
 public boolean canHandleBlock(QName qname) {
   System.out.println("inside canHandleBlock(): QName = " +
qname.toString());
   /*
   return (HEADER_NS.equals(qname.getNamespaceURI()) && 
           HEADER_STR.equals(qname.getLocalPart())) ? true : false;
   */
   return true;
 }
}

On the client side, I simple get the single cookie like this:
(most code not given since it is not relevent to the task).
...
org.apache.axis.MessageContext msgContext = null;
org.apache.axis.client.Call call = null;
try {
  call = stub._getCall();
  msgContext = call.getMessageContext();
  String cookieStr =
(String)msgContext.getProperty(HTTPConstants.HEADER_COOKIE);
  if (cookieStr != null && !cookieStr.equals("")) {
    cookie = getCookie(cookieStr);
    System.out.println("cookieStr = " + cookieStr);
  }
  else
    System.out.println("no cookie found.");
} catch (Exception e) {
  System.out.println("some Exception: " + e.getMessage());
}
...

...
public static Cookie getCookie(String cookieStr) {
  // We assume that cookieStr is a name value pair, like this:
name=value
  StringTokenizer stkr = new StringTokenizer(cookieStr, "=");
  String name = stkr.nextToken();
  String value = stkr.nextToken();
  Cookie cookie = new Cookie(name, value);
  return cookie;
}
..
Good luck!
-jeff






-----Original Message-----
From: StanleyAllen [mailto:stanley@nehushtan.com] 
Sent: Thursday, June 07, 2007 6:59 PM
To: axis-user@ws.apache.org
Subject: cookies for out-of-band data


I have what seems to me to be a relatively simple problem.  I have a
web service implemented in Axis (1.2) for which I cannot easily change
the interface.  The service needs to be able to receive out-of-band
(OOB) data for each call -- that is, extra data beyond the parameters
normally passed through the method invocation.  The service is
stateful and it should set the cookie; the client needs to maintain
the session and send the cookie for all future invocations of the
service.
The OOB data is a string

For some reason, I can't seem to find the right combination of
service/client
code to make this work.

This is what I've got on the client side:

	XYZServiceLocator locator = new XYZServiceLocator();
	XYZ WSport = (XYZ) locator.getXYZService();
	locator.setMaintainSession(true);
	WSPort.call1(a,b);
	MessageContext mc = locator.getCall().getMessageContext();
	String cookie1 = (String)
mc.getProperty(HTTPConstants.HEADER_COOKIE);
	String cookie2 = (String)
mc.getProperty(HTTPConstants.HEADER_COOKIE2);
	System.out.println("cookie1 : '" + cookie1 + "'");
	System.out.println("cookie2 : '" + cookie2 + "'");

and later in the client:

	// this cookie value may be different than the one received from
call1()
	mc.setProperty
		(HTTPConstants.HEADER_COOKIE2, "ExerciseName=" +
exerciseNameStr);
	WSPort.call2();

And on the service side, I have this skeleton:

      public class XYZSoapBindingSkeleton implements
		XYZinterface, org.apache.axis.wsdl.Skeleton,
ServiceLifecycle
      {
		public static ServletEndpointContext sec;

		..... normal generated skeleton code  ....

		public void init(Object context) throws ServiceException
		{
			try
			{
				if (sec == null)
				{
					System.out.println("RHIND
skeleton getting fresh endpoint context");
					sec = (ServletEndpointContext)
context;
				}
			}
			catch (Exception e)
			{
				e.printStackTrace();
			}
		}

		public void destroy()
		{
		}
	}

Also on the service sode, I've got this Impl:

	public class XYZSoapBindingImpl implements XYZInterface
	{
		public void call1 (String a, String b)
		{
			... other logic ...

			HttpSession ssn =
XYZSoapBindingSkeleton.sec.getHttpSession();

			// This prints a JSESSIONID value.  It is the
same as the one
			// printed by the next-to-last line of the
client snippet above
			System.out.println("Http Session id = " +
ssn.getId());

			// use ssn to set ExerciseName cookie to
forExercise.   but HOW!?!?!?!

			// logic below doesn't work -- on the client,
the value of cookie2 is
			// always null (the printout from the last line
of the client snippet
above)
			javax.xml.rpc.handler.MessageContext localMc =
	
XYZSoapBindingSkeleton.sec.getMessageContext();
			localMc.setProperty
				(HTTPConstants.HEADER_COOKIE2,
"ExerciseName=" + a);

			... other logic ...
		}

		public void call2 ()
		{
			... other logic ...

			HttpSession ssn =
XYZSoapBindingSkeleton.sec.getHttpSession();

			// this prints the same JSESSIONID value as
call1 and the client
			System.out.println("Http Session id = " +
ssn.getId());

			String Exname;

			//  use ssn to get ExerciseName cookie.
HOW!?!?!?!

			// This prints null
			javax.xml.rpc.handler.MessageContext localMc =
	
XYZSoapBindingSkeleton.sec.getMessageContext();
			String exCookie =
				(String) localMc.getProperty
(HTTPConstants.HEADER_COOKIE2);
			System.out.println("localMc cookie2 = " +
exCookie);

			// This prints null also
			MessageContext mc =
MessageContext.getCurrentContext();
			String exCookieB =
				(String)
mc.getProperty(HTTPConstants.HEADER_COOKIE2);
			System.out.println("mc cookie2 = " + exCookieB);

			... other logic

		}
	}

Apparently what I'm trying to do on the service side will not set the
cookie so that the client can read it.  And the cookie I'm sending from
the client is not being seen by the service.  What am I missing?

Thanks,

Stanley


-- 
View this message in context:
http://www.nabble.com/cookies-for-out-of-band-data-tf3886854.html#a11017
805
Sent from the Axis - User mailing list archive at Nabble.com.


---------------------------------------------------------------------
To unsubscribe, e-mail: axis-user-unsubscribe@ws.apache.org
For additional commands, e-mail: axis-user-help@ws.apache.org




---------------------------------------------------------------------
To unsubscribe, e-mail: axis-user-unsubscribe@ws.apache.org
For additional commands, e-mail: axis-user-help@ws.apache.org


Mime
View raw message