【问题标题】:Confused with different methods of creating cookie in HttpClient对在 HttpClient 中创建 cookie 的不同方法感到困惑
【发布时间】:2013-07-20 17:17:33
【问题描述】:

在 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.

【问题讨论】:

标签: java cookies struts2 apache-commons-httpclient


【解决方案1】:

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

这意味着您需要提供所有相关信息,以便客户端决定是否将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 指出这个解决方案)

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

  • 在您的Action 中实现ServletRequestAware 并从HttpServletRequest 读取cookie
  • 在您的Action 中引入CookieInterceptor 并实现CookiesAwaresetCookieMap 方法允许读取cookie。

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

【讨论】:

  • 我已添加 setDomain 并将其更改为 localhost、localhost:8080 和 localhost:8080,但均未成功。
  • 对于您提供的代码,答案应该有效(我在Github 上发布了测试)。我想知道您如何验证 cookie 是否正确发送(也许 Struts2 标记是指服务器应用程序?)。问题是如何使用 Struts2 向客户端发送 cookie 还是 如何使用 commons-httpclient 向服务器发送自定义 cookie
  • @CarloPellegrini 那么你应该在答案中解释它,而不是在 cmets 中。
  • @RomanC 我相信我已经做到了。无论如何,我编辑了答案以强调信息。
  • @CarloPellegrini 但是你错了,cookie-provider 拦截器呢?
【解决方案2】:

首先你可能不想使用 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);

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

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

我会说它(servlet API)也是最容易用 java 解决这个确切问题的一种,尽管它不是很容易开始使用 Web 应用程序。

【讨论】:

    猜你喜欢
    • 2013-07-27
    • 2017-03-20
    • 2013-07-19
    • 2018-04-25
    • 1970-01-01
    • 2021-03-30
    • 1970-01-01
    • 1970-01-01
    • 2017-06-06
    相关资源
    最近更新 更多