使用javaurlconnection进行Cookie管理
我对android编程相当陌生,最近实现了一个成功的HTTP Post请求,但后来才知道我的cookie没有在后续Post/Get请求之间存储。我环顾了一下interweb,找到了一些Android的Apache客户端和Java的HttpURLConnection的示例。我在当前类中实现这两种方法都不成功,所以我想知道是否有经验丰富的人可以查看我的代码并提供建议 概述:使用javaurlconnection进行Cookie管理,java,android,cookies,http-post,httpurlconnection,Java,Android,Cookies,Http Post,Httpurlconnection,我对android编程相当陌生,最近实现了一个成功的HTTP Post请求,但后来才知道我的cookie没有在后续Post/Get请求之间存储。我环顾了一下interweb,找到了一些Android的Apache客户端和Java的HttpURLConnection的示例。我在当前类中实现这两种方法都不成功,所以我想知道是否有经验丰富的人可以查看我的代码并提供建议 概述: 我的初始POST请求已成功并经过验证 我的第二个POST请求没有保留最初POST请求中的cookies 有人选择Apache方
import android.util.Log;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.net.CookieHandler;
import java.net.CookieManager;
import java.net.HttpCookie;
import java.net.HttpURLConnection;
import java.net.URL;
import javax.net.ssl.HttpsURLConnection;
public class webCreate {
private final String USER_AGENT = "Mozilla/5.0";
// HTTP GET request
public void sendGet(String url) throws Exception {
CookieManager cookieManager = new CookieManager();
CookieHandler.setDefault(cookieManager);
HttpCookie cookie = new HttpCookie("lang", "en");
URL obj = new URL(url);
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
// optional default is GET
con.setRequestMethod("GET");
//add request header
con.setRequestProperty("User-Agent", USER_AGENT);
int responseCode = con.getResponseCode();
Log.d("sendGet", "\nSending 'GET' request to URL : " + url);
BufferedReader in = new BufferedReader(
new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
//print result
System.out.println(response.toString());
Log.d("Response Code", response.toString());
}
// HTTP POST request
String sendPost(String url, String urlParams) throws Exception {
CookieManager cookieManager = new CookieManager();
CookieHandler.setDefault(cookieManager);
HttpCookie cookie = new HttpCookie("lang", "en");
URL obj = new URL(url);
HttpsURLConnection con = (HttpsURLConnection) obj.openConnection();
//add request header
con.setRequestMethod("POST");
con.setRequestProperty("User-Agent", USER_AGENT);
con.setRequestProperty("Accept-Language", "en-US,en;q=0.5");
// Send post request
con.setDoOutput(true);
DataOutputStream wr = new DataOutputStream(con.getOutputStream());
wr.writeBytes(urlParams);
wr.flush();
wr.close();
int responseCode = con.getResponseCode();
System.out.println("\nSending 'POST' request to URL : " + url);
System.out.println("Post parameters : " + urlParams);
System.out.println("Response Code : " + responseCode);
BufferedReader in = new BufferedReader(
new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
System.out.println("Response Code : " + response);
return response.toString();
}
}
您需要在每个调用外部维护cookie上下文,并在后续get和post中提供相同的cookie存储。这对于Java实现和Apache实现都是一样的 根据我的经验,它比内置Java实现要好。我花了大量时间尝试使用Java的实现编写实用程序,我最大的问题是超时。坏的web服务器将挂起,导致连接无限期挂起。切换到Apache后,超时是可调的,我们没有更多挂起的线程
我将给出一个使用Apache的示例 在父方法中创建
CookieStore
实例:
CookieStore cookieStore = new BasicCookieStore();
然后在GET或POST实现中,传入CookieStore
实例,并在构建HttpClient时使用它:
public void sendGet(String url, CookieStore cookieStore) throws Exception {
...
HttpClient client = HttpClientBuilder.create().setDefaultCookieStore(cookieStore).build();
HttpGet request = new HttpGet(uri); // or HttpPost...
request.addHeader("User-Agent", USER_AGENT);
HttpResponse response = client.execute(request);
BufferedReader br = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
...
}
Android已经扩展了
java.net.HttpURLConnection
,并建议使用它,因此我也将对此给出一个概要
HttpURLConnection
和HttpsURLConnection
自动透明地使用CookieHandler
中设置的CookieManager
CookieHandler
是虚拟机范围的,因此必须只设置一次。如果您为每个请求创建一个新的CookieManager
,就像您在代码中所做的那样,它将清除以前请求中设置的任何cookie
您不需要自己创建HttpCookie
的实例。当HttpURLConnection
从服务器接收cookie时,CookieManager
将接收cookie并存储它。将来对同一服务器的请求将自动发送以前设置的cookie
因此,将此代码移动到应用程序设置中,使其仅发生一次:
CookieManager cookieManager = new CookieManager();
CookieHandler.setDefault(cookieManager);
谢谢你的回复,我还没有机会测试代码。我确实审阅了您的反馈,它提出了另一个问题,您可能无法解决,也可能无法解决。使用您的示例并假设sendGet也是类的名称:sendGet webReq=new sendGet();webReq.sendGet(“www.google.com”,cookieStore);如果我要发送第二个webReq.sendGet,那么如果只有一个sendGet类的新实例,为什么必须再次发送cookie?我希望这个问题有意义。此文本框中的格式设置有点困难。
sendGet
是方法的名称,而不是类的名称。如果愿意,可以在类中存储对CookieStore
的引用。但是,不管怎样,每次创建一个新的HttpClient
实例时,都必须提供与以前请求相同的CookieStore
实例。哦,好的。我希望您的示例能够奏效,但Android studio拒绝承认“HttpClientBuilder”,因为它确实重构了HttpClient。HttpClientBuilder是Apache HTTP组件的一部分。你有没有把它整合到你的项目中并导入到你的课堂上?这可能会让人困惑,因为Java类的名称类似。我发现了Apache库的一个移植版本,但经过进一步研究,似乎android实际上建议使用HttpUrlConnection,而不是HttpClient---您能否提供一个使用HttpUrlConnection而不是HttpClient通过post/get设置/获取cookie的示例?