混淆了在HttpClient中创建cookie的不同方法

时间:2013-07-22 03:50:21

标签: java cookies struts2 apache-commons-httpclient

在HttpClient中创建cookie有不同的方法,我很困惑哪一个是最好的。 我需要创建,检索和修改cookie。

例如,我可以使用以下代码查看cookie列表并修改它们但是如何创建它们?

这是检索它们的正确方法吗?我需要它们可以在所有类中访问。

  • 另外我发现的方法通常需要httpresponse,httprequest对象将cookie发送到浏览器,但如果我不想使用它们怎么样?

代码

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

我尝试使用以下代码创建cookie,但它不是

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

输出如下,但不会创建Cookie。

SEVERE: Creating the cookie
SEVERE: cookie

方案

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.

2 个答案:

答案 0 :(得分:3)

在第二个示例中,您正在创建客户端Cookie(即您正在模拟浏览器并将Cookie 发送到服务器)。

这意味着您需要提供所有相关信息,以便客户可以决定是否将Cookie发送到服务器。

在您的代码中,您正确设置了路径,名称和值,但缺少信息。

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

如果你想要实现的是将cookie发送到http服务器,这是有效的。

你的第二个例子来自execute方法,因为你在你的标签中暗示了struts2,也许包含它的类是struts2 Action

如果是这种情况,您要实现的目标是向浏览器发送新Cookie

第一种方法是抓住HttpServletResponse,如下所示:

所以你的Action必须如下:

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

}

使用CookieProviderInterceptor可以获得另一种方法(没有HttpServletResponse)。

struts.xml

中启用它
<action ... >
  <interceptor-ref name="defaultStack"/>
  <interceptor-ref name="cookieProvider"/>
  ...
</action>

然后将CookieProvider实现为:

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

}

(归功于@RomanC指出这个解决方案)

如果您以后需要阅读它,您有两种选择:

  • ServletRequestAware中实施Action并阅读HttpServletRequest
  • 中的Cookie
  • CookieInterceptor中引入CookiesAware并实施Action,方法setCookieMap允许读取Cookie。

在这里您可以找到一些相关信息:

答案 1 :(得分:1)

首先,你可能不希望使用HttpClient,它是一个客户端(例如模拟浏览器)而不是服务器(可以创建用户浏览器将存储的cookie)。

那就是说,我首先要解释你的第一个代码示例中发生了什么:

  • 您向服务器发送GET请求
  • 服务器会向您发送一些Cookie及其响应(内容)
  • 您修改HttpClient实例中的Cookie
  • 您将这些Cookie发送回服务器
  • 服务器对您更改的cookie的处理完全取决于该服务器的编程方式
  • 在下一个请求时,服务器可能会将这些更改后的cookie发回给您,正如我所说的那样取决于它的编程方式。

至于你的第二个例子:

  • 您创建了一个Cookie
  • 您在Cookie上设置了一些信息
  • 您将cookie发送到服务器(在GET请求中)
  • 服务器现在使用您的cookie对其进行编程。 服务器可以忽略您的Cookie (例如,不会将其发回给您)。

另一方面您可能想要做的是编写一个 Web应用程序(例如服务器端),创建cookie并根据客户端的不同进行更改输入(浏览器)。

为此您可以使用Servlet API。一些事情:

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

创建一个Web应用程序超出范围简单的stackoverflow答案,但网上有很多很好的教程。

如果用户应使用浏览器查看您的产品,则无法创建Web应用程序。创建一个不同的框架有不同的方法。 servlet API(例如HttpServletResponseHttpServletResponse)是最基本的。

我会说它(servlet API)也是最简单的一个,你可以找到解决这个问题的java,即使它不是很容易开始使用Web应用程序。