Android'de çerezleri kullanarak nasıl http talebinde bulunabilirim?


121

Tanımlama bilgilerini düzgün bir şekilde işlerken (örn. Sunucu tarafından gönderilen tanımlama bilgilerini depolamak ve daha sonra istekte bulunduğumda bu tanımlama bilgilerini göndermek) uzak bir sunucuya bir http talebinde bulunmak istiyorum. Tüm çerezleri korumak güzel olurdu, ama gerçekten önemsediğim tek şey oturum çerezi.

Java.net ile bunu yapmanın tercih edilen yolu java.net.CookieHandler (soyut temel sınıf) ve java.net.CookieManager (somut uygulama) kullanmaktır. Android'de java.net.CookieHandler var, ancak java.net.CookieManager'a sahip görünmüyor.

Http başlıklarını inceleyerek hepsini elle kodlayabilirim, ancak daha kolay bir yolu olmalı gibi görünüyor.

Çerezleri korurken Android'de http isteklerinde bulunmanın doğru yolu nedir?



3
İki yıldan daha uzun bir süre sonra bir not olarak: java.net.CookieManagerartık Android'de 2.3 sürümünden beri destekleniyor (API seviyesi 9): developer.android.com/reference/java/net/CookieManager.html
Slauma

Yanıtlar:


92

Google Android'in Apache HttpClient 4.0 ile birlikte geldiği ortaya çıktı ve HttpClient belgelerinde "Form tabanlı oturum açma" örneğini kullanarak bunu nasıl yapacağımı bulabildim :

https://github.com/apache/httpcomponents-client/blob/master/httpclient5/src/test/java/org/apache/hc/client5/http/examples/ClientFormLogin.java


import java.util.ArrayList;
import java.util.List;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.cookie.Cookie;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;

/**
 * A example that demonstrates how HttpClient APIs can be used to perform
 * form-based logon.
 */
public class ClientFormLogin {

    public static void main(String[] args) throws Exception {

        DefaultHttpClient httpclient = new DefaultHttpClient();

        HttpGet httpget = new HttpGet("https://portal.sun.com/portal/dt");

        HttpResponse response = httpclient.execute(httpget);
        HttpEntity entity = response.getEntity();

        System.out.println("Login form get: " + response.getStatusLine());
        if (entity != null) {
            entity.consumeContent();
        }
        System.out.println("Initial set of cookies:");
        List<Cookie> cookies = httpclient.getCookieStore().getCookies();
        if (cookies.isEmpty()) {
            System.out.println("None");
        } else {
            for (int i = 0; i < cookies.size(); i++) {
                System.out.println("- " + cookies.get(i).toString());
            }
        }

        HttpPost httpost = new HttpPost("https://portal.sun.com/amserver/UI/Login?" +
                "org=self_registered_users&" +
                "goto=/portal/dt&" +
                "gotoOnFail=/portal/dt?error=true");

        List <NameValuePair> nvps = new ArrayList <NameValuePair>();
        nvps.add(new BasicNameValuePair("IDToken1", "username"));
        nvps.add(new BasicNameValuePair("IDToken2", "password"));

        httpost.setEntity(new UrlEncodedFormEntity(nvps, HTTP.UTF_8));

        response = httpclient.execute(httpost);
        entity = response.getEntity();

        System.out.println("Login form get: " + response.getStatusLine());
        if (entity != null) {
            entity.consumeContent();
        }

        System.out.println("Post logon cookies:");
        cookies = httpclient.getCookieStore().getCookies();
        if (cookies.isEmpty()) {
            System.out.println("None");
        } else {
            for (int i = 0; i < cookies.size(); i++) {
                System.out.println("- " + cookies.get(i).toString());
            }
        }

        // When HttpClient instance is no longer needed, 
        // shut down the connection manager to ensure
        // immediate deallocation of all system resources
        httpclient.getConnectionManager().shutdown();        
    }
}

11
Oturumun geçerli olup olmadığını kontrol etmek için çerezleri İstek URL'sine nasıl ayarlayacağımı öğrenebilir miyim?
Praveen

Beni BasicNameValuePairs ile tanıştırdığınız için TEŞEKKÜR EDERİZ. Bana yardım ettiler.
bhekman

3
Anlıyorum The method getCookieStore() is undefined for the type HttpClient, değiştirmek zorunda List<Cookie> cookies = ((AbstractHttpClient) httpclient).getCookieStore().getCookies();mıyım? Çünkü yaparsam işe yarıyor.
Francisco Corrales Morales

@Praveen Çerezleri kaydetmek için buraya bir göz atın: stackoverflow.com/a/5989115/2615737
Francisco Corrales Morales

@emmby: unfortunateley android apache modülünü kullanımdan kaldırdı. Yani şu anda cevabı yardımcı değil. HttpURLConnection ile bunu yapmanın başka bir yolu var mı?
Milad Faridnia

9

Çerez, yalnızca başka bir HTTP başlığıdır. Apache kitaplığı veya HTTPUrlConnection ile bir HTTP çağrısı yaparken bunu her zaman ayarlayabilirsiniz. Her iki durumda da HTTP çerezlerini bu şekilde okuyup ayarlayabilmelisiniz.

Daha fazla bilgi için bu makaleyi okuyabilirsiniz .

Bunu ne kadar kolaylaştırabileceğinizi göstermek için kod rahatlığımı paylaşabilirim.

public static String getServerResponseByHttpGet(String url, String token) {

        try {
            HttpClient client = new DefaultHttpClient();
            HttpGet get = new HttpGet(url);
            get.setHeader("Cookie", "PHPSESSID=" + token + ";");
            Log.d(TAG, "Try to open => " + url);

            HttpResponse httpResponse = client.execute(get);
            int connectionStatusCode = httpResponse.getStatusLine().getStatusCode();
            Log.d(TAG, "Connection code: " + connectionStatusCode + " for request: " + url);

            HttpEntity entity = httpResponse.getEntity();
            String serverResponse = EntityUtils.toString(entity);
            Log.d(TAG, "Server response for request " + url + " => " + serverResponse);

            if(!isStatusOk(connectionStatusCode))
                return null;

            return serverResponse;

        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }

Bu bana çok yardımcı oluyor, +1 get.setHeader ("Cookie", "PHPSESSID =" + token + ";"); do the work
Oussaki

@Hesam: unfortunatley android apache modülünü kullanımdan kaldırdı. Yani şu anda cevabı yardımcı olmuyor. HttpURLConnection ile bunu yapmanın başka bir yolu var mı?
Milad Faridnia

7

Yana Apache kütüphane itiraz edildi , kullanmak isteyenler için HttpURLConncetion, ben Alın ve yardımıyla Mesaj İsteği göndermek için bu sınıf yazdım bu cevap :

public class WebService {

static final String COOKIES_HEADER = "Set-Cookie";
static final String COOKIE = "Cookie";

static CookieManager msCookieManager = new CookieManager();

private static int responseCode;

public static String sendPost(String requestURL, String urlParameters) {

    URL url;
    String response = "";
    try {
        url = new URL(requestURL);

        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setReadTimeout(15000);
        conn.setConnectTimeout(15000);
        conn.setRequestMethod("POST");

        conn.setRequestProperty("Content-Type", "application/json; charset=utf-8");

        if (msCookieManager.getCookieStore().getCookies().size() > 0) {
            //While joining the Cookies, use ',' or ';' as needed. Most of the server are using ';'
            conn.setRequestProperty(COOKIE ,
                    TextUtils.join(";", msCookieManager.getCookieStore().getCookies()));
        }

        conn.setDoInput(true);
        conn.setDoOutput(true);

        OutputStream os = conn.getOutputStream();
        BufferedWriter writer = new BufferedWriter(
                new OutputStreamWriter(os, "UTF-8"));

        if (urlParameters != null) {
            writer.write(urlParameters);
        }
        writer.flush();
        writer.close();
        os.close();

        Map<String, List<String>> headerFields = conn.getHeaderFields();
        List<String> cookiesHeader = headerFields.get(COOKIES_HEADER);

        if (cookiesHeader != null) {
            for (String cookie : cookiesHeader) {
                msCookieManager.getCookieStore().add(null, HttpCookie.parse(cookie).get(0));
            }
        }

        setResponseCode(conn.getResponseCode());

        if (getResponseCode() == HttpsURLConnection.HTTP_OK) {

            String line;
            BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            while ((line = br.readLine()) != null) {
                response += line;
            }
        } else {
            response = "";
        }
    } catch (Exception e) {
        e.printStackTrace();
    }

    return response;
}


// HTTP GET request
public static String sendGet(String url) throws Exception {

    URL obj = new URL(url);
    HttpURLConnection con = (HttpURLConnection) obj.openConnection();

    // optional default is GET
    con.setRequestMethod("GET");

    //add request header 
    con.setRequestProperty("User-Agent", "Mozilla");
    /*
    * /programming/16150089/how-to-handle-cookies-in-httpurlconnection-using-cookiemanager
    * Get Cookies form cookieManager and load them to connection:
     */
    if (msCookieManager.getCookieStore().getCookies().size() > 0) {
        //While joining the Cookies, use ',' or ';' as needed. Most of the server are using ';'
        con.setRequestProperty(COOKIE ,
                TextUtils.join(";", msCookieManager.getCookieStore().getCookies()));
    }

    /*
    * /programming/16150089/how-to-handle-cookies-in-httpurlconnection-using-cookiemanager
    * Get Cookies form response header and load them to cookieManager:
     */
    Map<String, List<String>> headerFields = con.getHeaderFields();
    List<String> cookiesHeader = headerFields.get(COOKIES_HEADER);
    if (cookiesHeader != null) {
        for (String cookie : cookiesHeader) {
            msCookieManager.getCookieStore().add(null, HttpCookie.parse(cookie).get(0));
        }
    }


    int responseCode = con.getResponseCode();

    BufferedReader in = new BufferedReader(
            new InputStreamReader(con.getInputStream()));
    String inputLine;
    StringBuffer response = new StringBuffer();

    while ((inputLine = in.readLine()) != null) {
        response.append(inputLine);
    }
    in.close();

    return response.toString();
}

public static void setResponseCode(int responseCode) {
    WebService.responseCode = responseCode;
    Log.i("Milad", "responseCode" + responseCode);
}


public static int getResponseCode() {
    return responseCode;
}
}

2
Güzel Sınıf Milad! Bana çok yardımcı oldu! Ben kullanıcının uygulamayı öldürdü eğer kullanılabilmesi için çerez kaydetmek istedim ve tekrar başlattı Şimdi, eğer ben merak ediyorum, tam olarak ne ben saklamalısınız ve nerede (nasıl)
Ki JEY

1

Google android ile çalışmıyorum ama bence bunu çalıştırmanın o kadar da zor olmadığını göreceksiniz. Java öğreticisinin ilgili kısmını okursanız , kayıtlı bir çerez işleyicisinin HTTP kodundan geri aramalar aldığını göreceksiniz.

Öyleyse varsayılan yoksa (kontrol ettiniz mi? CookieHandler.getDefault() gerçekten boş mi?) O zaman CookieHandler'ı genişletebilir, put / get uygulayabilir ve hemen hemen otomatik olarak çalışmasını sağlayabilirsiniz. Bu rotaya giderseniz eşzamanlı erişimi ve benzerlerini dikkate aldığınızdan emin olun.

edit: Açıkçası CookieHandler.setDefault(), geri aramaları almak için özel uygulamanızın bir örneğini varsayılan işleyici olarak ayarlamanız gerekir . Bunu söylemeyi unuttum.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.