使用javaurlconnection进行Cookie管理

使用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方

我对android编程相当陌生,最近实现了一个成功的HTTP Post请求,但后来才知道我的cookie没有在后续Post/Get请求之间存储。我环顾了一下interweb,找到了一些Android的Apache客户端和Java的HttpURLConnection的示例。我在当前类中实现这两种方法都不成功,所以我想知道是否有经验丰富的人可以查看我的代码并提供建议

概述:

  • 我的初始POST请求已成功并经过验证
  • 我的第二个POST请求没有保留最初POST请求中的cookies
  • 有人选择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实现都是一样的

    根据我的经验,它比内置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的示例?