2012-09-10 10 views
21

मैंने अनुशंसित HTTPUrlConnection का उपयोग करना शुरू कर दिया है और DefaultHTTPClient से दूर चले गए हैं। उन चीजों में से एक जो मैं एक साथ वापस गोंद करने में सक्षम नहीं हूं, एक सतत कुकी स्टोर का उपयोग है। मैं कुकीज को स्टोर करने के लिए अपने कनेक्शन में कस्टम कुकी हैंडलर/मैनेजर को बस संलग्न करना चाहता हूं। एंड्रॉइड प्रलेखन बहुत उपयोगी नहीं रहा है क्योंकि यह दो लाइनों में कुकीज़ के विषय को लपेटता है।HTTPUrlConnection का उपयोग करते समय मैं कुकीज़ कैसे बना सकता हूं?

मैं पहले लूपजे के PersistentCookieStore का उपयोग कर रहा हूं और यह खूबसूरती से काम करता है।

एंड्रॉइड में एक सतत कुकी स्टोर कैसे स्थापित किया जा सकता है, इस पर कोई विचार है कि मैं अपने HTTPUrlConnection से संलग्न कर सकता हूं जो कुकीज़ को स्वचालित रूप से सहेजता है और पुनर्प्राप्त करता है?

धन्यवाद

उत्तर

23

इसकी 'मुझे कुछ घंटों लिया लेकिन मैं एक कस्टम कुकी भंडारण अपने आप का निर्माण करने में कामयाब रहे।

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); 
     } 
    } 

यहाँ वास्तविक भंडारण है::

आप ऐसा करके इस संलग्न करना

/* 
* 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); 

    } 

} 
+0

यह अच्छी तरह से परीक्षण नहीं किया गया है, लेकिन मैं संपादन कर देंगे के रूप में मैं साथ जाने। कृपया सुधार का सुझाव दें। –

+25

कभी-कभी मुझे आश्चर्य होता है कि क्या मैं एसडीके में लगातार कुकीज़ के रूप में मौलिक के रूप में कुछ उम्मीद करने के लिए पागल हूं ... अगर मैं किसी भी सुधार का सुझाव दे सकता हूं तो मुझे वापस पोस्ट करना होगा।इस कार्यान्वयन के साथ –

+8

, यह सटीक यूआरआई में कुकीज़ जोड़ देगा, जिससे वे आएंगे, जिसका अर्थ है कि वे उस होस्ट पर किसी भी अन्य यूआरआई को नहीं भेजे जाएंगे। मैं उम्मीद करता हूं कि यह व्यवहार करने के लिए उत्तीर्ण यूआरआई को एक नए यूआरआई के साथ बदलने के लिए केवल मेजबान नाम शामिल है। पूर्व: वर्तमान कार्यान्वयन के साथ, यदि आप yourdomain.com/pageOne.htm पर जाते हैं, तो जब आप यूआरआई अलग होते हैं तो yourdomain.com/pageTwo.htm पर जाने पर कोई भी कुकी सेट नहीं भेजा जाएगा। कार्यान्वयन (i) के रूप में व्यवहार करने के लिए कार्यान्वयन को केवल yourdomain.com पर यूआरआई पैरामीटर को ट्रिम करना चाहिए। – Keith

0

मैं ऊपर जवाब थे, लेकिन एक से अधिक को संभालने के लिए निम्नलिखित करने के लिए अपने ऐड पद्धति को बदल कर एक ही यूआरआई से कुकी (जीएई के साथ यह कुकी स्टोर सत्र टोकन का इलाज कर रहा था और कुछ कारणों से उसी यूआरआई से दो अलग-अलग कुकीज़ के रूप में याद रखना टोकन):

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(); 
} 

और का उपयोग और एक संयुक्त कुकी बनाना:

MyCookieStore store = new MyCookieStore(this.context, false); 
String cookie = TextUtils.join(",", store.get(new URI(URLString))); 

कनेक्शन करने के लिए संलग्न करें:

URL urlToRequest = new URL(stringPath); 
HttpURLConnection urlConnection = (HttpURLConnection) urlToRequest.openConnection(); 
urlConnection.setRequestProperty("Cookie", cookie); 
1

कई कस्टम CookieStore कार्यान्वयन में कुछ बुनियादी समस्याएं हैं।

पहली समस्या स्ट्रिंग में HttpCookie serialization है - HttpCookie.toString() विधि इसके लिए स्वीकार्य नहीं है क्योंकि इसका परिणाम HttpCookie.parse (स्ट्रिंग हेडर) विधि के लिए उपयुक्त नहीं है।

दूसरी समस्या: कुकीस्टोर कार्यान्वयन के अधिकांश (उदाहरण के लिए यहां https://codereview.stackexchange.com/questions/61494/persistent-cookie-support-using-volley-and-httpurlconnection) HttpCookie.maxAge फ़ील्ड के प्रारूप को ध्यान में रखता नहीं है। कुकी लाइव करने के लिए यह कई सेकंड है। लेकिन अगर आप बस इसके मूल्य को बरकरार रखते हैं और कुछ समय बाद इसे अप्रचलित करते हैं, तो यह गलत होगा। आपको maxAge फ़ील्ड को "expire_at" जैसे कुछ में परिवर्तित करना होगा और maxAge के बजाय इसे जारी रखना होगा।

1

नीचे दिए गए लिंक में कार्यान्वयन चेकआउट करें। यह मेजबाननाम द्वारा कुकीज़ को मूल java.net की तरह सहेजता है। इनमेमरीकुकीस्टोर कार्यान्वयन करता है।

इसके अलावा इसमें एक SerializableHttpCookie शामिल है जो पूर्ण HashMap को SharePreferences में क्रमबद्ध करने में सक्षम है।

https://gist.github.com/jacobtabak/78e226673d5a6a4c4367