为什么Cookie会话会继续死亡

时间:2013-07-10 09:27:08

标签: android http

我在这个网站上阅读了几个topis如何让会话保持活跃状态​​,并且愿意遵循建议,但我的客户端不断失去与服务器的连接。 通过erver实现JSONParser类的通信,JSONParser从UILApplication获取HttpClient,如果互联网连接被删除,则设置和恢复cookie。不幸的是,这不起作用。请帮我解决这个问题。

UILApplication

public class UILApplication extends Application {
private static Object mLock = new Object();
    private static CookieStore mCookie = null;
public static HttpClient getHttpClient() {
        final DefaultHttpClient httpClient = HttpClientFactory
                .getThreadSafeClient();
        synchronized (mLock) {
            if (mCookie == null) {
                mCookie = httpClient.getCookieStore();
            } else {
                httpClient.setCookieStore(mCookie);
            }

        }
        List<Cookie> cookies = mCookie.getCookies();
        if (cookies.isEmpty()) {
            Log.d("COOK", "none");
        } else {
            for (int i = 0; i < cookies.size(); i++) {
                Log.d("COOK", "- " + cookies.get(i).toString());
            }
        }
        return httpClient;
    }

HttpClientFactory

public class HttpClientFactory {
    private static DefaultHttpClient client=null;
//  private static CookieStore mCookie = null;


    public boolean isNetworkConnected(Context context) {
        ConnectivityManager conMgr = (ConnectivityManager) context
                .getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo i = conMgr.getActiveNetworkInfo();
        if (i == null) {
            return false;
        }
        if (!i.isConnected()) {
            return false;
        }
        if (!i.isAvailable()) {
            return false;
        }
        return true;
    }

    public synchronized static DefaultHttpClient getThreadSafeClient() {

        if (client != null) {
            Log.d("HTTPCLIEN", "REUSE");

            // return client;
        } else {
            Log.d("HTTPCLIEN", "new");
            client = new DefaultHttpClient();

            ClientConnectionManager mgr = client.getConnectionManager();

            HttpParams params = client.getParams();
            HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);
            HttpProtocolParams.setHttpElementCharset(params, HTTP.UTF_8);

            client = new DefaultHttpClient(new ThreadSafeClientConnManager(
                    params, mgr.getSchemeRegistry()), params);


            // return client;
        }
//      synchronized (mLock) {

        return client;
    }

    public synchronized static DefaultHttpClient killSession() {

        client = new DefaultHttpClient();

        ClientConnectionManager mgr = client.getConnectionManager();

        HttpParams params = client.getParams();
        client = new DefaultHttpClient(new ThreadSafeClientConnManager(params,
                mgr.getSchemeRegistry()), params);
//      
        return client;

    }
}

JSONParser

public class JSONParser {
    public JSONObject getJSONFromUrl(String url, List<NameValuePair> params) {

        if (isOnline()) {
            try {

                String u = url;
                u = u + "?";

                httpClient = UILApplication.getHttpClient();

                HttpPost httpPost = new HttpPost(url);
                httpPost.setEntity(new UrlEncodedFormEntity(params, HTTP.UTF_8));
                for (int i = 0; i < params.size(); i++) {
                    u = u + params.get(i).getName() + "="
                            + params.get(i).getValue() + "&";
                }
                Log.d("your url is", u);
                HttpResponse httpResponse = httpClient.execute(httpPost);
                List<Cookie> cookies = ((AbstractHttpClient) httpClient).getCookieStore().getCookies();
                UILApplication.setCoockies(((AbstractHttpClient) httpClient).getCookieStore());
                if (cookies.isEmpty()) {
                    System.out.println("None");
                } else {
                    for (int i = 0; i < cookies.size(); i++) {

                        System.out.println("- " + cookies.get(i).toString());
                    }
                }
                HttpEntity httpEntity = httpResponse.getEntity();
                is = httpEntity.getContent();
                Log.d("data is sent", "true");

            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
                return null;
            } catch (ClientProtocolException e) {
                e.printStackTrace();
                return null;
            } catch (IOException e) {
                e.printStackTrace();
                return null;

            }
            Log.d("wait", "true");
            try {

                BufferedReader reader = new BufferedReader(
                        new InputStreamReader(is, "UTF-8"), 8);
                StringBuilder sb = new StringBuilder();
                String line = null;
                while ((line = reader.readLine()) != null) {

                    sb.append(line + "\n");
                }
                is.close();
                json = sb.toString();
                if (json.contains("error:2")) {
                    return null;
                }
                Log.d("JSON", json);
            } catch (Exception e) {
                Log.e("Buffer Error", "Error converting result " + e.toString());
                return null;
            }
            // try parse the string to a JSON object
            try {
                jObj = new JSONObject(json);
            } catch (JSONException e) {
                Log.e("JSON Parser", "Error parsing data " + e.toString());
                return null;
            }
            // dialog.dismissDialog();
            // pd.dismiss();
            return jObj;
        }
        // pd.dismiss();
        // dialog.dismissDialog();

//      error();
        return null;

    }
}

编辑:看起来mCookie在一段时间后会被GC发现,但为什么如果它是应用程序类的静态字段呢?

2 个答案:

答案 0 :(得分:1)

听起来你从服务器返回的cookie是session cookie,保持简单,意味着当你停止应用程序并再次运行它时,cookie就会被丢弃。

我建议在服务器端为cookie设置Max-Age or an Expire。这应该可以解决问题。

调试此类问题的另一种方法是打印出从服务器返回的HTTP标头。事实上可能存在一个错误,它没有正确设置cookie过期或Max-Age。

另一个非常重要的事情是设置cookie的Secure属性,如果您使用它来验证HTTP客户端/请求,否则您的cookie将在每次执行对域的HTTP请求时发送在cookie中指定,即使请求是关于同一域的图像下载。这样,如果攻击者嗅探网络流量,就可以劫持用户会话。

答案 1 :(得分:0)

我会使用HttpURLConnectionrecommended

然后,您可以像这样启用VM范围的Cookie管理:

CookieHandler.setDefault(new CookieManager());

然后,Cookie会存储在内存中,但如果需要,您可以实现自己的CookieStore

您可以阅读有关Cookie和HttpURLConnection here的更多信息。