7

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

2 回答 2

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

第一种方法是获取 a 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;
    }

}

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

启用它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
  • 在你的 中引入一个CookieInterceptor并实现,该方法允许读取 cookie。CookiesAwareActionsetCookieMap

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

于 2013-07-22T08:25:42.347 回答
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.

于 2013-07-29T14:04:34.700 回答