it-swarm.com.de

Wie mache ich eine http-Anfrage mit Cookies auf Android?

Ich möchte eine http-Anfrage an einen Remote-Server senden, während Cookies ordnungsgemäß behandelt werden (z. B. vom Server gesendete Cookies speichern und diese Cookies senden, wenn ich nachfolgende Anfragen stelle). Es wäre schön, alle Cookies aufzubewahren, aber das Einzige, was mich interessiert, ist das Session-Cookie.

Bei Java.net scheint die bevorzugte Methode die Verwendung von Java.net.CookieHandler (abstrakte Basisklasse) und Java.net.CookieManager (konkrete Implementierung) zu sein. Android hat Java.net.CookieHandler, aber es scheint Java.net.CookieManager nicht zu haben.

Ich könnte alles von Hand codieren, indem ich die http-Header inspiziere, aber es scheint, als gäbe es einen einfacheren Weg.

Was ist der richtige Weg, um http-Anfragen auf Android unter Beibehaltung von Cookies zu stellen?

115
emmby

Es stellt sich heraus, dass Google Android mit Apache HttpClient 4.0 ausgeliefert wird, und ich konnte anhand des Beispiels "Form based Logon" in HttpClient docs herausfinden, wie das geht =:

http://svn.Apache.org/repos/asf/httpcomponents/httpclient/trunk/httpclient/src/examples/org/Apache/http/examples/client/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();        
    }
}
90
emmby

Ein Cookie ist nur ein weiterer HTTP-Header. Sie können es jederzeit festlegen, während Sie einen HTTP-Aufruf mit der Apache-Bibliothek oder mit HTTPUrlConnection durchführen. In beiden Fällen sollten Sie in der Lage sein, HTTP-Cookies auf diese Weise zu lesen und zu setzen.

Sie können diesen Artikel für weitere Informationen lesen.

Ich kann meinen Code-Frieden teilen, um zu demonstrieren, wie einfach Sie es machen können.

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;
    }
8
Hesam

Da die Apache-Bibliothek veraltet ist , habe ich diese Klasse für diejenigen geschrieben, die HttpURLConncetion verwenden möchten, um Get and Post Request mit der Hilfe zu senden von diese Antwort :

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");
    /*
    * https://stackoverflow.com/questions/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()));
    }

    /*
    * https://stackoverflow.com/questions/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;
}
}
4
Milad Faridnia

Ich arbeite nicht mit google Android, aber ich denke, Sie werden feststellen, dass es nicht so schwer ist, dies zum Laufen zu bringen. Wenn Sie das entsprechende Bit des Lernprogramms Java lesen , werden Sie feststellen, dass ein registrierter Cookie-Handler Rückrufe vom HTTP-Code erhält.

Wenn es also keine Standardeinstellung gibt (haben Sie überprüft, ob CookieHandler.getDefault() wirklich null ist?), Können Sie CookieHandler einfach erweitern, put/get implementieren und es so ziemlich automatisch funktionieren lassen. Vergessen Sie nicht, den gleichzeitigen Zugriff und dergleichen in Betracht zu ziehen, wenn Sie diesen Weg gehen.

edit: Natürlich müssten Sie eine Instanz Ihrer benutzerdefinierten Implementierung über CookieHandler.setDefault() als Standardhandler festlegen, um die Rückrufe zu erhalten. Ich habe vergessen, das zu erwähnen.

1
wds