1

我在这个网站上阅读了几个主题如何保持会话活跃并尝试遵循建议,但我的客户不断失去与服务器的连接。与 erv​​er 的通信实现 JSONParser 类,JSONParser 从 UILApplication 获取 HttpClient ,如果互联网连接被丢弃,它会设置和恢复 cookie。不幸的是,这不起作用。请帮我解决这个问题。

UIL应用程序

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;

    }
}

JSON解析器

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 清除了,但是如果它是应用程序类的静态字段,为什么会出现这种情况?

4

2 回答 2

1

听起来您从服务器返回的 cookie 是一个会话 cookie,为了简单起见,这意味着当您停止应用程序并再次运行它时,cookie 将被丢弃。

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

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

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

于 2013-07-19T22:53:23.580 回答
0

我会使用HttpURLConnection它,这是推荐的。

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

CookieHandler.setDefault(new CookieManager());

然后 Cookie 仅存储在内存中,但您可以根据需要实现自己的CookieStore

HttpURLConnection 您可以在此处阅读有关 cookie 的更多信息。

于 2013-07-20T09:43:48.633 回答