¿Cómo se persisten las cookies cuando se utiliza HTTPUrlConnection?
He comenzado a usar la HTTPUrlConnection
recomendada y me he alejado del DefaultHTTPClient
. Una de las cosas que no he sido capaz de pegar de nuevo juntos es el uso de una tienda de galletas persistentes. Me gustaría simplemente adjuntar un gestor / gestor de cookies personalizado a mi conexión para almacenar las cookies. La documentación de Android no ha sido de gran ayuda ya que incluye el tema de las cookies en dos líneas.
He estado usando LoopJ PersistentCookieStore
anterior y que funcionó maravillosamente.
- Inicialización estática en OpenCV Android
- Android Google Play Service Visión Explorador de códigos de barras Biblioteca no encontrada
- Error al iniciar Android Studio: Error al crear JVM: código de error-6
- Java.lang.NoSuchMethodError en la compilación
- Cómo enviar el archivo binario y el texto usando el mismo socket
¿Alguna idea de cómo puedo configurar una tienda de galletas persistentes en Android que puedo adjuntar a mi HTTPUrlConnection
que guarda y recupera las cookies automáticamente?
Gracias
- Android reconocimiento de voz API.System siempre reconoce el idioma predeterminado
- Android.view.InflateException: Línea de archivo XML binario # 33: Error al inflar fragmento de clase
- Error: Gradle: la ejecución falló para la tarea ': app: preDexDebug'
- Facturación de Android v3 - sin firma
- Fuerza detener un bloqueo de lectura AsyncTask
- Cómo crear matriz de objetos con For Loop en Android
- Strange InputDispatcher error "Canal de entrada cerrado del consumidor o se produjo un error. eventos = 0x8 "
- ¿Cómo puedo importar una biblioteca de Android y usarla tanto en el código de producción como en las pruebas?
Su 'me tomó un par de horas, pero me las arreglé para construir un almacenamiento de cookies personalizado a mí mismo.
Tienes que adjuntar esto haciendo esto:
public class application extends Application { @Override public void onCreate() { super.onCreate(); CookieManager cmrCookieMan = new CookieManager(new MyCookieStore(this.objContext), CookiePolicy.ACCEPT_ALL); CookieHandler.setDefault(cmrCookieMan); } }
Aquí está el almacenamiento real:
/* * This is a custom cookie storage for the application. This * will store all the cookies to the shared preferences so that it persists * across application restarts. */ class MyCookieStore implements CookieStore { /* * The memory storage of the cookies */ private Map<URI, List<HttpCookie>> mapCookies = new HashMap<URI, List<HttpCookie>>(); /* * The instance of the shared preferences */ private final SharedPreferences spePreferences; /* * @see java.net.CookieStore#add(java.net.URI, java.net.HttpCookie) */ public void add(URI uri, HttpCookie cookie) { System.out.println("add"); System.out.println(cookie.toString()); List<HttpCookie> cookies = mapCookies.get(uri); if (cookies == null) { cookies = new ArrayList<HttpCookie>(); mapCookies.put(uri, cookies); } cookies.add(cookie); Editor ediWriter = spePreferences.edit(); HashSet<String> setCookies = new HashSet<String>(); setCookies.add(cookie.toString()); ediWriter.putStringSet(uri.toString(), spePreferences.getStringSet(uri.toString(), setCookies)); ediWriter.commit(); } /* * Constructor * * @param ctxContext the context of the Activity */ @SuppressWarnings("unchecked") public MyCookieStore(Context ctxContext) { spePreferences = ctxContext.getSharedPreferences("CookiePrefsFile", 0); Map<String, ?> prefsMap = spePreferences.getAll(); for(Map.Entry<String, ?> entry : prefsMap.entrySet()) { for (String strCookie : (HashSet<String>) entry.getValue()) { if (!mapCookies.containsKey(entry.getKey())) { List<HttpCookie> lstCookies = new ArrayList<HttpCookie>(); lstCookies.addAll(HttpCookie.parse(strCookie)); try { mapCookies.put(new URI(entry.getKey()), lstCookies); } catch (URISyntaxException e) { e.printStackTrace(); } } else { List<HttpCookie> lstCookies = mapCookies.get(entry.getKey()); lstCookies.addAll(HttpCookie.parse(strCookie)); try { mapCookies.put(new URI(entry.getKey()), lstCookies); } catch (URISyntaxException e) { e.printStackTrace(); } } System.out.println(entry.getKey() + ": " + strCookie); } } } /* * @see java.net.CookieStore#get(java.net.URI) */ public List<HttpCookie> get(URI uri) { List<HttpCookie> lstCookies = mapCookies.get(uri); if (lstCookies == null) mapCookies.put(uri, new ArrayList<HttpCookie>()); return mapCookies.get(uri); } /* * @see java.net.CookieStore#removeAll() */ public boolean removeAll() { mapCookies.clear(); return true; } /* * @see java.net.CookieStore#getCookies() */ public List<HttpCookie> getCookies() { Collection<List<HttpCookie>> values = mapCookies.values(); List<HttpCookie> result = new ArrayList<HttpCookie>(); for (List<HttpCookie> value : values) { result.addAll(value); } return result; } /* * @see java.net.CookieStore#getURIs() */ public List<URI> getURIs() { Set<URI> keys = mapCookies.keySet(); return new ArrayList<URI>(keys); } /* * @see java.net.CookieStore#remove(java.net.URI, java.net.HttpCookie) */ public boolean remove(URI uri, HttpCookie cookie) { List<HttpCookie> lstCookies = mapCookies.get(uri); if (lstCookies == null) return false; return lstCookies.remove(cookie); } }
Hay algunos problemas básicos en la implementación personalizada de CookieStore.
El primer problema es HttpCookie serialización en cadena – HttpCookie.toString () método no es aceptable para esto porque su resultado no es adecuado para HttpCookie.parse (encabezado de encabezado) método.
El segundo problema: la mayor parte de la implementación de CookieStore (por ejemplo aquí https://codereview.stackexchange.com/questions/61494/persistent-cookie-support-using-volley-and-httpurlconnection ) no tiene en cuenta el formato de HttpCookie. Campo maxAge. Este es un número de segundos para cookie en vivo. Pero si usted simplemente persiste su valor y después de algún tiempo el unpersist él, será incorrecto. Debe convertir el campo maxAge en algo como "expire_at" y persistir en lugar de maxAge.
Utilicé la respuesta anterior, pero cambié mi método de agregar a lo siguiente para manejar más de una cookie desde el mismo URI (este almacén de cookies con GAE estaba tratando el token de sesión y el token de recuerdo como dos cookies separadas del mismo URI por alguna razón) :
public void add(URI uri, HttpCookie cookie) { List<HttpCookie> cookies = mapCookies.get(uri); if (cookies == null) { cookies = new ArrayList<HttpCookie>(); mapCookies.put(uri, cookies); } cookies.add(cookie); Editor ediWriter = spePreferences.edit(); HashSet<String> setCookies = new HashSet<String>(); setCookies.add(cookie.toString()); HashSet<String> emptyCookieSet = new HashSet<String>(); if(spePreferences.contains(uri.toString())){ emptyCookieSet = (HashSet<String>) spePreferences.getStringSet(uri.toString(), emptyCookieSet); if(!emptyCookieSet.isEmpty()){ if(!emptyCookieSet.contains(cookie.toString())){ emptyCookieSet.add(cookie.toString()); ediWriter.putStringSet(uri.toString(), emptyCookieSet); } } } else{ ediWriter.putStringSet(uri.toString(), setCookies); } ediWriter.commit(); }
Y para acceder y crear una cookie combinada:
MyCookieStore store = new MyCookieStore(this.context, false); String cookie = TextUtils.join(",", store.get(new URI(URLString)));
Adjuntar a la conexión:
URL urlToRequest = new URL(stringPath); HttpURLConnection urlConnection = (HttpURLConnection) urlToRequest.openConnection(); urlConnection.setRequestProperty("Cookie", cookie);
Compruebe la implementación en el siguiente enlace. Guarda las cookies por nombre de host como lo hace la implementación original de java.net.InMemoryCookieStore.
Además de que contiene un SerializableHttpCookie para poder serializar el HashMap completo en SharedPreferences.
- Android 4.4 KitKat accidente aleatorio
- No se puede detectar ABI de aplicación al intentar depurar NDK