Confused with different methods of creating cookie in HttpClient
Asked Answered
T

2

7

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.
Turboprop answered 22/7, 2013 at 3:50 Comment(1)
You need to create a CookieStore and set it on context every time you are making a request.Like this.. #6273075Marinelli
O
3

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:

Outgoing answered 22/7, 2013 at 8:25 Comment(16)
I've added setDomain and changed it to localhost, localhost:8080 and localhost:8080 but neither worked.Turboprop
For the code you provided, the answer should work (I posted the test on Github). I'm wondering how do you verify that the cookie is correctly sent (maybe the Struts2 tag refers to the server application ?). Is the question how can I send a cookie to a client using Struts2 or how can I send a custom cookie to the server using commons-httpclient ?Outgoing
I am not sure about those namings but I suppose httpclient as I need to create,modify and delete cookies without request and response object. Question is updatedTurboprop
I tried to use the other code as well but it does not recognize "this" in server.setHandler(this); although I've used org.mortbay.jetty.Server and I am not sure if that causes the problem.Turboprop
I'm sorry but I'm still puzzled. Maybe if you would explain the overall scenario we can be more helpful. Are you trying to connect to an existing server from a standalone application?Outgoing
@CarloPellegrini OP says, not to use request and response.Jeroldjeroma
@RomanC I know, but there's simply no other way around it (in a Servlet or Struts2 environment)Outgoing
@CarloPellegrini Then you should explain it in the answer, not in comments.Jeroldjeroma
@RomanC I believed I've already done it. In any case I edited the answer to emphasize the information.Outgoing
@CarloPellegrini But you are wrong, what about cookie-provider interceptor?Jeroldjeroma
let us continue this discussion in chatOutgoing
I have already added the interceptor definitions to my struts.xml but when I implement the CooKieProvider interface it shows it does not existsTurboprop
@RomanC what are the pros and cons of each approach ? I have a action class which need to call a method of another class and that method is going to access the cookie, thats why I am not interested in request response objects as the second method is extending another class so it cant extend the ActionSuper classTurboprop
@TimNorman You should clarify #7 in your scenario, it's unclear what are you trying to achieve.Jeroldjeroma
@TimNorman You should be able to find org.apache.struts2.interceptor.CookieProvider (it's quite new, available in struts since 2.3.15)Outgoing
@TimNorman In #7 you could create the cookie in 2 ways: * client-side: via JavaScript, see document.cookie * server-side: the button will sumbit to an action like the one in the answer Which scenario are you pursuing?Outgoing
A
1

First of all you propably do not want to use HttpClient, which is a client (e.g. emulates a browser) and not a server (which can create cookies, that the user's browser will store).

That said, I'm first explaining what happens in your first code example:

  • You send a GET request to a server
  • The server sends you some cookies alongside it's response (the content)
  • You modify the cookies in your HttpClient instance
  • You send those cookies back to the server
  • What the server does with your changed cookies entirely depends on what that server is programmed to do
  • At the next request the server might send those changed cookies back to you or not, which as I allraedy said depends on what it is programmed to do.

As for you second example:

  • You create a cookie
  • You set some information on the cookie
  • You send the cookie to the server (inside your GET request)
  • The server now does with your cookie what it is programmed to do with it. Propably the server ignores your cookie (e.g. does not send it back to you).

On the other hand what you propably want to do is write a web application (e.g. the server side), that creates the cookie and changes it depending on the client's input (the browser).

For that you can use the Servlet API. Something along the lines:

javax.servlet.http.Cookie cookie = new 
    javax.servlet.http.Cookie("your cookie's name", "your cookie's value");
//response has type javax.servlet.http.HttpServletResponse
response.addCookie(cookie);

Creating a web application is way out of scope of a simple stackoverflow answer, but there are many good tutorials out there in the web.

There is no way around creating a web application if the user should use a browser to see your products. There are just different ways to create one, different frameworks. The servlet API (e.g. HttpServletResponse and HttpServletResponse) is the most basic one.

I'd say it (the servlet API) is also the easiest one you can find to solve this exact problem with java, even though it is not exactly easy to get started with web applications at all.

Aweigh answered 22/7, 2013 at 3:50 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.