【问题标题】:Trying setting session cookie using HttpClient尝试使用 HttpClient 设置会话 cookie
【发布时间】:2013-02-07 19:16:22
【问题描述】:

帮助设置 cookie 到 HttpClient

创建了一个登录到外部网络服务的程序。但是,要从 一个 HTTP GET,我无法传入 cookie(从登录生成)。

public class ClientHelper {
    private final static String PROFILE_URL = 
                               "http://externalservice/api/profile.json";
    private final static String LOGIN_URL = "http://externalservice/api/login";

    public static Cookie login(final String username, final String password) {
        DefaultHttpClient client = new DefaultHttpClient();
        HttpPost post = new HttpPost(LOGIN_URL);
        HttpContext localContext = new BasicHttpContext();
        client.getParams().setParameter("http.useragent", "Custom Browser");
        client.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, 
                                        HttpVersion.HTTP_1_1);
        List<Cookie> cookies = null;
        BasicClientCookie cookie = null;

        try {
            List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(3);
            nameValuePairs.add(new BasicNameValuePair("user", username));
            nameValuePairs.add(new BasicNameValuePair("passwd", password));
            UrlEncodedFormEntity entity = 
                    new UrlEncodedFormEntity(nameValuePairs, HTTP.UTF_8);
            entity.setContentType("application/x-www-form-urlencoded");

            post.setEntity(new UrlEncodedFormEntity(nameValuePairs));
            HttpResponse response = client.execute(post, localContext);
            cookies = client.getCookieStore().getCookies();
            System.out.println(cookies.get(1));

            cookie = new BasicClientCookie(cookies.get(1).getName(), cookies.get(1).getValue());
            cookie.setVersion(cookies.get(1).getVersion());
            cookie.setDomain(cookies.get(1).getDomain());
            cookie.setExpiryDate(cookies.get(1).getExpiryDate());
            cookie.setPath(cookies.get(1).getPath());               
            BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));

            String line = "";
            while ((line = rd.readLine()) != null) {
                System.out.println(line);
            }
        } 
        catch (Throwable e) {
            e.printStackTrace();
        }
        return cookie;
   }

   public static void getProfile(Cookie cookie) {
      DefaultHttpClient client = new DefaultHttpClient();
      HttpContext context = new BasicHttpContext();
      CookieStore cookieStore = new BasicCookieStore();
      cookieStore.addCookie(cookie);
      client.setCookieStore(cookieStore);
      context.setAttribute(ClientContext.COOKIE_STORE, cookieStore);
      HttpGet get = new HttpGet(PROFILE_URL);
      HttpResponse response;

      try {
          response = client.execute(get, context);
          BufferedReader rd = 
             new BufferedReader(
                    new InputStreamReader(response.getEntity().getContent()));

          String line = "";
          while ((line = rd.readLine()) != null) {
              System.out.println(line);
          }
       } 
       catch (ClientProtocolException e) {
           e.printStackTrace();
       } 
       catch (IOException e) {
           e.printStackTrace();
       }
   }
}

App.java(使用 ClientHelper 的类):

public class App {
   private static final String USER = "myusername";
   private static final String PASSWD = "mypassword";

   public static void main(String[] args) {
       Cookie cookie = ClientHelper.login(USER, PASSWD);
       ClientHelper.getProfile(cookie);
   }
}

当我运行 App 时,我可以登录(我看到生成的 JSON),但 getProfile() 方法返回一个空的 JSON 对象:

 {}

从命令行,使用 curl 我试图模拟这个:

curl -b Cookie.txt http://externalservice/api/profile.json

这确实有效,但不是我的 Java 程序。

【问题讨论】:

  • Erm,你认为你在发送登录请求之前 有一个 cookie 吗?
  • 谢谢布赖恩!我刚刚编辑了我的代码(见上文),并且能够看到“cookie”引用的值是相同的。不知何故,它仍然无法在 getProfile() 中工作。

标签: java json cookies curl apache-httpclient-4.x


【解决方案1】:

尝试执行这部分代码:

List<Cookie> cookies = client.getCookieStore().getCookies();
        for (Cookie cookie : cookies) {
             singleCookie = cookie;
        }

之后

 HttpResponse response = client.execute(post, localContext);

【讨论】:

  • 根据 Brian 的建议更改了我的代码。见上文。
【解决方案2】:

在更改您的代码以在登录请求后获取 cookie 之后,您实际上是从请求中获取所有 cookie。

我怀疑问题在于,无论CookieCookieStore 中的索引1 处是什么,这都不是您需要的,显然,因为当您这样做时它不会引发IndexOutOfBounds 异常,所以至少有另一个Cookie 在那里(在索引0)。返回 cookie 列表,并在您的个人资料请求中发送所有个。

获取您的代码,将所有这些索引从 1 更改为 0 并指向这个简单的 PHP 脚本表明它正在接收然后发送 cookie:

<?php
    setcookie("TestCookie", "Some value");
    print_r($_COOKIE);        
?>

输出:

[version: 0][name: TestCookie][value: Some+value][domain: www.mydomain.org][path: /][expiry: null]
Array
(
)
Array
(
    [TestCookie] => Some value
)

【讨论】:

    【解决方案3】:

    我想通了...我正在创建两个不同的 HTTP 客户端,而不是使用同一个。

    @Brian Roach 和 Raunak Agarwal 非常感谢你们的帮助!

    解决方法如下:

    public static HttpClient login(final String username, final String password) 
    {
        HttpClient client = new DefaultHttpClient();
        HttpPost post = new HttpPost(LOGIN_URL);
        client.getParams().setParameter("http.useragent", "Custom Browser");
        client.getParams().setParameter(
                 CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);
    
        try 
        {
            List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(3);
            nameValuePairs.add(new BasicNameValuePair("user", username));
            nameValuePairs.add(new BasicNameValuePair("passwd", password));
            UrlEncodedFormEntity entity = 
                  new UrlEncodedFormEntity(nameValuePairs, HTTP.UTF_8);
            entity.setContentType("application/x-www-form-urlencoded");
    
            post.setEntity(new UrlEncodedFormEntity(nameValuePairs));
            HttpResponse response = client.execute(post);
    
            BufferedReader reader = 
                  new BufferedReader(
                  new InputStreamReader(response.getEntity().getContent()));
    
            String line = "";
            while ((line = reader.readLine()) != null) 
            {
                System.out.println(line);
            }
        } 
        catch (Throwable e) { e.printStackTrace(); }
        return client;
    }
    
    public static void getProfile(HttpClient client) 
    {
        HttpGet get = new HttpGet(PROFILE_URL);
        HttpResponse response;
        try 
        {
            response = client.execute(get);
            BufferedReader reader = 
                   new BufferedReader(
                   new InputStreamReader(response.getEntity().getContent()));
    
            String line = "";
            while ((line = reader.readLine()) != null) 
            {
                System.out.println(line);
            }
        } 
        catch (ClientProtocolException e) { e.printStackTrace(); } 
        catch (IOException e) { e.printStackTrace(); }  
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-01-27
      • 1970-01-01
      • 2019-11-18
      • 1970-01-01
      • 2013-11-19
      • 2015-12-27
      • 1970-01-01
      • 2012-11-01
      相关资源
      最近更新 更多