【问题标题】:Android is ignoring cookies in my HTTP POSTAndroid 忽略了我的 HTTP POST 中的 cookie
【发布时间】:2015-11-13 08:22:58
【问题描述】:

我的应用程序执行 HTTP POSTS,通常该应用程序可以工作,但我遇到了 cookie 问题。我的代码似乎通过 HttpClient 变量并输出了 cookie,但 POST 的结果显示我的应用程序(作为客户端)没有记住任何内容。 (当我在我的电脑上使用网络浏览器时,它工作正常,cookie 记住了我的名字) 此外,如果重新启动应用程序,cookie 就会消失(...但首先要做的事)

这是我的代码:

static DefaultHttpClient httpclient;
static HttpPost httppost;
static CookieStore cookiestore;

new Thread(new Runnable() {
        public void run() {

            String URI_FOR_DOMAIN="http://chatbot.t.com/cgi-bin/elbot.cgi";

            httppost = new HttpPost(URI_FOR_DOMAIN);
            try {
                HttpResponse resp = httpclient.execute(httppost);
            } catch (IOException e) {
                e.printStackTrace();
            }

            cookiestore = ((DefaultHttpClient) httpclient).getCookieStore();
            List<Cookie> list = cookiestore.getCookies();
            app.logy("COOKIE STORE 1: " + cookiestore.toString());
            app.logy("COOKIE LIST  1: "+list.toString());
            for (int i=0;i<list.size();i++) {
                Cookie cookie = list.get(i);
                app.logy("COOKIE "+i+": "+cookie.toString());
            }

            HttpContext context = new BasicHttpContext();
            context.setAttribute(  ClientContext.COOKIE_STORE, cookiestore);

            httppost = new HttpPost(url);
            try {
                // Add your data
                List<NameValuePair> nameValuePairs = new ArrayList<>(2);
                nameValuePairs.add(new BasicNameValuePair("ENTRY", userInput));
                nameValuePairs.add(new BasicNameValuePair("IDENT", userIDENT));
                nameValuePairs.add(new BasicNameValuePair("USERLOGID", userLOGID));
                httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));

                // Execute HTTP Post Request
                app.logy("COOKIE STORE 2: "+cookiestore.toString());
                app.logy("COOKIE CONTEXT: " + context.toString());
                HttpResponse response = httpclient.execute(httppost, context);

                cookiestore = ((DefaultHttpClient) httpclient).getCookieStore();
                List<Cookie> list2 = cookiestore.getCookies();
                app.logy("COOKIE STORE 2: " + cookiestore.toString());
                app.logy("COOKIE LIST  2: "+list2.toString());
                for (int i=0;i<list2.size();i++) {
                    Cookie cookie = list2.get(i);
                    app.logy("COOKIE2 i="+i+": "+cookie.toString());
                }

                HttpEntity entity = response.getEntity();
}


                    }
                    app.logy(sb.toString());
                }
                catch (IOException e) { e.printStackTrace(); }
                catch (Exception e) { e.printStackTrace(); }


            } catch (ClientProtocolException e) {
                app.logy("HttpPOST (ClientProtocol) error: "+e);
            } catch (IOException e) {
                app.logy("HttpPOST (I/O) error: "+e);
            }

        }
    }).start();

这是从上述代码中反映在 Logcats 中的值。 cookie 似乎在那里,但 HttpResponse response = httpclient.execute(httppost, context);似乎忽略了他们。

COOKIE STORE 2: [[version: 0][name: cookie_user_name][value: Albert][domain: elbot-e.artificial-solutions.com][path: /][expiry: Thu Oct 08 22:26:54 GMT+02:00 2015]]
COOKIE LIST  2: [[version: 0][name: cookie_user_name][value: Albert][domain: elbot-e.artificial-solutions.com][path: /][expiry: Thu Oct 08 22:26:54 GMT+02:00 2015]]
COOKIE2 i=0: [version: 0][name: cookie_user_name][value: Albert][domain: elbot-e.artificial-solutions.com][path: /][expiry: Thu Oct 08 22:26:54 GMT+02:00 2015]

【问题讨论】:

    标签: android cookies http-post androidhttpclient android-cookiemanager


    【解决方案1】:

    首先,您应该将 AsyncTask 用于任何类型的 api 调用。创建单独的线程是可行的,但这是不好的做法,而不是 android 方式。 其次,在您的 api 调用中使用 HttpUrlConnection 而不是 HTTPPost。这是进行 api 交互的新方法。 尝试这两种方法,看看您的 cookie 问题会发生什么。

    @Josh 编辑: 事实证明,@cj1090 向我发送了他的建议的正确方向,因此我将编辑他的答案以添加实现并将其标记为绿色。 按照他的建议,我改变了策略并实现了基于 HttpURLConnection 的 AsyncTask,而不是 Thread+HTTPpost 解决方案。代码完美运行,cookie 由 HttpURLConnection 对象在内部处理。但是,如果应用程序被销毁,cookie 就会消失,但这是另一天的话题。 享受代码! BASE_URL 是一个老式的 HTML 网站 url,用户通过将字符串发送到 params[0] 与它进行通信:

      //Call the AsyncTask like this:
    final String BASE_URL = "http://elba.artisol.com/cgi/bot.cgi";
    String fromUserTextbox="hello"
    new elbotHttpTask().execute(url);
    
    
       public class elbotHttpTask extends AsyncTask<String, Void, Integer> {
    
            @Override
            protected Integer doInBackground(String... params) {
                InputStream inputStream = null;
                HttpURLConnection urlConnection = null;
                Integer result = 0;
                try {
                    URL obj = new URL(BASE_URL);
                    HttpURLConnection con = (HttpURLConnection) obj.openConnection();
                    con.setRequestMethod("POST");
                    con.setDoInput(true);
                    con.setDoOutput(true);
                    //con.setRequestProperty("User-Agent", USER_AGENT);
    
                    app.userInput=params[0];
    
                    List<NameValuePair> parameters = new ArrayList<NameValuePair>();
                    parameters.add(new BasicNameValuePair("ENTRY", params[0]));
                    parameters.add(new BasicNameValuePair("IDENT", app.sessionIDENT));
                    parameters.add(new BasicNameValuePair("USERLOGID", app.sessionUSERLOGID));
    
    
                    // For POST only - START
                    app.logy("pp.getQuery(parameters): "+app.getQuery(parameters));
                    OutputStream os = con.getOutputStream();
                    BufferedWriter writer = new BufferedWriter(
                            new OutputStreamWriter(os, "UTF-8"));
                    writer.write(app.getQuery(parameters));
                    writer.flush();
                    writer.close();
                    os.close();
    
                    con.connect();
    
                    int responseCode = con.getResponseCode();
                    System.out.println("POST Response Code :: " + responseCode);
    
                    if (responseCode == HttpURLConnection.HTTP_OK) { //success
                        BufferedReader in = new BufferedReader(new InputStreamReader(
                                con.getInputStream()));
                        String inputLine;
                        StringBuffer response = new StringBuffer();
    
                        while ((inputLine = in.readLine()) != null) {
                            response.append(inputLine);
                        }
                        in.close();
                        consumeHTMLresponse(response.toString());
                        result = 1;
                    } else {
                        System.out.println("POST request not worked");
                        result = 0;
                    }
                } catch (Exception e) {
                    app.logy(e.getLocalizedMessage());
                }
                return result; //"Failed to fetch data!";
            }
    
    
    
            @Override
            protected void onPostExecute(Integer result) {
                if(result == 1){
                    app.logy("onPostEXECUTE SUCCESS");
                }else{
                    app.logy("Failed to fetch data!");
                }
            }
        }
    

    【讨论】:

    • 在我目前的方法中,我打开 response.getEntity() 并提取网页 URL 的整个 HTML 字符串。我可以对您建议的 HrrpUrlConnection 方法做同样的事情吗?
    • 我不明白为什么不这样做。 httpUrlConnection 有一个 get response(),所以我确定它与您正在使用的响应对象相同。
    • 谢谢,我试试再回来
    • 成功了,@cj1098,我已经编辑了你的答案,添加了我编写的代码并将其标记为绿色,谢谢!
    • 谢谢伙计! :) 很高兴为您提供帮助
    猜你喜欢
    • 1970-01-01
    • 2013-02-08
    • 2017-08-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-03
    • 2011-12-22
    • 2017-12-09
    相关资源
    最近更新 更多