gpt4 book ai didi

java - 使用 HttpClient 时跨 Activity 使用 Cookie

转载 作者:IT老高 更新时间:2023-10-28 21:18:45 25 4
gpt4 key购买 nike

我正在尝试一个简单的应用程序来读取网站的 HTML,并将其转换为在 Android 中创建易于阅读的 UI(这是学习 android 的练习,而不是制作可用的应用程序)。我遇到的问题是跨 Activity 保持用户 session ,然后在 HttpClient 中使用 session 曾经记忆。

我想“正确地”这样做,推荐的方法似乎是使用 CookieManager .但是我遇到了问题 - 我似乎找不到“正确”的方式来获取 Cookie来自 CookieManager并在 HttpClient 的后续实例化中使用它在单独的 Activity 中。

使用 CookieManager 时我可以保存 CookieCookie然后在其他 Activity 的范围内(参见代码 fragment 2)。在请求页面时,我还没有找到稍后如何使用它(参见代码 fragment 3)。

废话不多说,这里有一些代码。首先是我的登录操作和 Cookie 存储:

private OnClickListener loginActionListener = new OnClickListener() 
{
public void onClick(View v)
{
EditText usernameTextView = (EditText) findViewById(R.id.Username);
EditText passwordTextView = (EditText) findViewById(R.id.Password);
String username = usernameTextView.getText().toString();
String password = passwordTextView.getText().toString();

try {
HttpPost postMethod = new HttpPost(URI);
HttpParams params = new BasicHttpParams();

params.setParameter("mode", "login");
params.setParameter("autologin", true);
params.setParameter("username", username);
params.setParameter("password", password);
postMethod.setParams(params);

DefaultHttpClient httpClient = new DefaultHttpClient();
HttpResponse response = httpClient.execute(postMethod);
List<Cookie> cookies = httpClient.getCookieStore().getCookies();

if(cookies != null)
{
for(Cookie cookie : cookies)
{
String cookieString = cookie.getName() + "=" + cookie.getValue() + "; domain=" + cookie.getDomain();
CookieManager.getInstance().setCookie(cookie.getDomain(), cookieString);
}
}
CookieSyncManager.getInstance().sync();

Intent intent = new Intent(v.getContext(), IndexAction.class);
startActivity(intent);
} catch (Exception e) {...}
}

决定是让用户登录还是进入索引的启动 Activity 如下。从这段代码可以看出cookie在作用域内,可以读取:

public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
CookieSyncManager.createInstance(this);

if(CookieManager.getInstance().getCookie(URI) == null)
{
Intent intent = new Intent(this, LoginAction.class);
startActivity(intent);
}
else
{
Intent intent = new Intent(this, IndexAction.class);
startActivity(intent);
}
}

但是从我的代码阅读索引页面我希望你能提出我所缺少的:

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
CookieSyncManager.createInstance(this);

try
{
HttpGet getMethod = new HttpGet(URI_INDEX);

HttpParams params = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(params, 30000);
HttpConnectionParams.setSoTimeout(params, 30000);

// This code results in a ClassCastException, I'm assuming i've found a red herring with this solution.
// HttpContext localContext = new BasicHttpContext();
// localContext.setAttribute(ClientContext.COOKIE_STORE, CookieManager.getInstance().getCookie(URI));

DefaultHttpClient httpClient = new DefaultHttpClient(params);
HttpResponse response = httpClient.execute(getMethod);

if(response.getStatusLine().getStatusCode() > 299 && response.getStatusLine().getStatusCode() < 400)
{
// Not logged in doesn't give a redirect response. Very annoying.
}

final char[] buffer = new char[0x10000];
StringBuilder out = new StringBuilder();
Reader in = new InputStreamReader(response.getEntity().getContent(), "UTF-8");
int read = 0;
while (read>=0)
{
read = in.read(buffer, 0, buffer.length);
if (read>0) {
out.append(buffer, 0, read);
}
}

String returnString = out.toString();
} catch (ClientProtocolException e) {...}
}

HttpClientexecute(getMethod)没有使用 Cookie(在调试中仔细检查)来拉回页面。如果有人能填补我知识的这个空白,那就太好了。

提前致谢。

编辑

当注释代码被重新添加(将 httpClient.execute(getMethod) 方法更改为 httpClient.execute(getMethod, localContext) )时,将生成此轨迹跟踪 - 假设是因为我正在填充属性 ClientContext.COOKIE_STORECookie String而不是 CookieStore :

*org.apache.http.client.protocol.RequestAddCookies.process(RequestAddCookies.java:88), org.apache.http.protocol.BasicHttpProcessor.process(BasicHttpProcessor.java:290), org.apache.http.protocol.HttpRequestExecutor.preProcess(HttpRequestExecutor.java:160), org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:401)
org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555), org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487),
com.testapp.site.name.IndexAction.onCreate(IndexAction.java:47),
android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047),
android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1611),
android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1663),
android.app.ActivityThread.access$1500(ActivityThread.java:117),
android.app.ActivityThread$H.handleMessage(ActivityThread.java:931),
android.os.Handler.dispatchMessage(Handler.java:99),
android.os.Looper.loop(Looper.java:123),
android.app.ActivityThread.main(ActivityThread.java:3683),
java.lang.reflect.Method.invokeNative(Native Method),
java.lang.reflect.Method.invoke(Method.java:507),
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839),
com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597),
dalvik.system.NativeStart.main(Native Method)*

最佳答案

CookieManager 由 Java 的内部 HTTP 客户端使用。它与 Apache HttpClient 无关。

在您的代码中,您总是为每个请求创建一个新的 HttpClient 实例,因此创建一个新的 CookieStore 实例,这显然会收集垃圾以及存储为的所有 cookie一旦该 HttpClient 实例超出范围。

你应该

(1) 对所有逻辑相关的 HTTP 请求重复使用相同的 HttpClient 实例,并在所有逻辑相关的线程之间共享(这是推荐的使用方式Apache HttpClient)

(2) 或者,至少,在逻辑相关的线程之间共享相同的 CookieStore 实例

(3) 或者,如果您坚持使用 CookieManager 来存储所有 cookie,创建一个由 CookieManager CookieStore 实现

关于java - 使用 HttpClient 时跨 Activity 使用 Cookie,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5802595/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com