Search code examples
javacookiesstruts2apache-commons-httpclient

Confused with different methods of creating cookie in HttpClient


There are different methods to create cookies in HttpClient, I am confused which one is the best. I need to create,retrieve and modify cookies.

For example , I can use the following code to see a list of cookies and modify them but how to create them ?

Is this a proper method for retrieving them? I need them to be accessible in all classes.

  • In addition methods that I have found usually require httpresponse, httprequest objects to send the cookie to browser, but how about if I do not want to use them?

Code

import org.apache.commons.httpclient.Cookie;
import org.apache.commons.httpclient.HttpState;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.GetMethod;

public class GetCookiePrintAndSetValue {

  public static void main(String args[]) throws Exception {

    HttpClient client = new HttpClient();
    client.getParams().setParameter("http.useragent", "My Browser");

    GetMethod method = new GetMethod("http://localhost:8080/");
    try{
      client.executeMethod(method);
      Cookie[] cookies = client.getState().getCookies();
      for (int i = 0; i < cookies.length; i++) {
        Cookie cookie = cookies[i];
        System.err.println(
          "Cookie: " + cookie.getName() +
          ", Value: " + cookie.getValue() +
          ", IsPersistent?: " + cookie.isPersistent() +
          ", Expiry Date: " + cookie.getExpiryDate() +
          ", Comment: " + cookie.getComment());

        cookie.setValue("My own value");
      }
      client.executeMethod(method);
    } catch(Exception e) {
      System.err.println(e);
    } finally {
      method.releaseConnection();
    }
  }
}

AND I've tried to create a cookie using following code but it does not

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.GetMethod;

....

public String execute() {
try{

     System.err.println("Creating the cookie");
     HttpClient httpclient = new HttpClient();
     httpclient.getParams().setParameter("http.useragent", "My Browser");

     GetMethod method = new GetMethod("http://localhost:8080/");
     httpclient.executeMethod(method);
     org.apache.commons.httpclient.Cookie cookie = new 
                                                org.apache.commons.httpclient.Cookie();
     cookie.setPath("/");
     cookie.setName("Tim");
     cookie.setValue("Tim");
     cookie.setDomain("localhost");
     httpclient.getState().addCookie(cookie);
     httpclient.executeMethod(method);
     System.err.println("cookie");

  }catch(Exception e){
     e.printStackTrace();
  }

Output is as following but no cookie will be created.

SEVERE: Creating the cookie
SEVERE: cookie

Scenario

1)User has access to a form to search for products (example.com/Search/Products)
2)User fills up the form and submit it to class Search
3)Form will be submitted to Search class 
4)Method Products of Search class returns and shows the description of product        
  (example.com/Search/Products)
5)User clicks on "more" button for more description about product 
6)Request will be sent to Product class (example.com/Product/Description?id=4)
7)User clicks on "add to cookie" button to add the product id to the cookie 

Product class is subclasse of another class. So it can not extend any more class.

Solution

  • In the second example, you are creating a new client-side cookie (i.e. you are impersonating a browser and are sending the cookie to the server).

    This means that you need to provide all the relevant information, so that the client can decide whether to send the cookie to the server or not.

    In your code you correctly set the path,name and value, but the domain information is missing.

    org.apache.commons.httpclient.Cookie cookie 
      = new org.apache.commons.httpclient.Cookie();
    cookie.setDomain("localhost");
    cookie.setPath("/");
    cookie.setName("Tim");
    cookie.setValue("Tim");
    

    This works if what you are trying to achieve is to send a cookie to an http server.

    Your second example, though, spans from an execute method, an since you are hinting at struts2 in your tag, maybe the class containing it is meant to be a struts2 Action.

    If this is the case, what you are trying to achieve is to send a new cookie to a browser.

    The first approach is to get hold of a HttpServletResponse as in:

    So your Action must look like:

    public class SetCookieAction 
        implements ServletResponseAware  // needed to access the 
                                         // HttpServletResponse
    {
    
        HttpServletResponse servletResponse;
    
        public String execute() {
            // Create the cookie
            Cookie div = new Cookie("Tim", "Tim");
            div.setMaxAge(3600); // lasts one hour 
            servletResponse.addCookie(div);
            return "success";
        }
    
    
        public void setServletResponse(HttpServletResponse servletResponse) {
            this.servletResponse = servletResponse;
        }
    
    }
    

    Another approach (without HttpServletResponse) could be obtained using the CookieProviderInterceptor.

    Enable it in struts.xml

    <action ... >
      <interceptor-ref name="defaultStack"/>
      <interceptor-ref name="cookieProvider"/>
      ...
    </action>
    

    then implement CookieProvider as:

    public class SetCookieAction 
        implements CookieProvider  // needed to provide the coookies
    {
    
        Set<javax.servlet.http.Cookie> cookies=
                new HashSet<javax.servlet.http.Cookie>();
    
        public Set<javax.servlet.http.Cookie> getCookies() 
        {
                return cookies;
        }
    
        public String execute() {
            // Create the cookie
            javax.servlet.http.Cookie div = 
                    new javax.servlet.http.Cookie("Tim", "Tim");
            div.setMaxAge(3600); // lasts one hour 
            cookies.put(cookie)
            return "success";
        }
    
    }
    

    (credits to @RomanC for pointing out this solution)

    If you subsequently need to read it you have two options:

    • implement ServletRequestAware in your Action and read the cookies from the HttpServletRequest
    • introduce a CookieInterceptor and implement CookiesAware in your Action, the method setCookieMap allows to read the cookies.

    Here you can find some relevant info: