使用Java URLConnection进行Cookie管理

我对Android编程很新,最近获得了成功的HTTP Post请求,只是为了得知我的cookie没有存储在后续的Post / Get请求之间。 我浏览了一下interweb,并找到了Android的Apache客户端和Java的HttpURLConnection的几个例子。 我没有成功地将这两种方法应用到我当前的课程中,所以我想知道有经验的人是否可以查看我的代码并提供建议。

概括:

  1. 我的初始POST请求成功并经过身份validation。
  2. 我的第二个POST请求不会保留初始POST请求中的cookie。
  3. 是否有人为可能选择Apache方法或Java实现的具体实例或原因? 两者都是平等的,还是一个提供比另一个更多的能力和灵活性?

感谢任何帮助,谢谢。

webCreate.java

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的实现,这都是相同的。

根据我的经验, Apache的HTTP组件比内置的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并建议使用它,所以我也会给出一个大纲。

HttpURLConnectionHttpsURLConnection自动且透明地使用CookieHandler设置的CookieManagerCookieHandler是VM范围的,因此必须只设置一次。 如果您为每个请求创建一个新的CookieManager ,就像您在代码中所做的那样,它将清除先前请求中设置的任何Cookie。

您不需要自己创建HttpCookie 。 当HttpURLConnection从服务器接收cookie时, CookieManager将接收cookie并存储它。 对同一服务器的未来请求将自动发送先前设置的cookie。

因此,将此代码移动到您的应用程序设置,以便它只发生一次:

 CookieManager cookieManager = new CookieManager(); CookieHandler.setDefault(cookieManager);