2013-09-25 11 views
19

मेरे एंड्रॉइड एप्लिकेशन के लिए वॉली लिब को नेटवर्क रैपर के रूप में उपयोग करने का प्रयास कर रहा है। मेरे पास एक कनेक्शन है और चल रहा है, लेकिन समस्या यह है कि प्रतिक्रिया में कई "सेट-कुकी" शीर्षलेख होते हैं, वॉली उस मानचित्र का उपयोग करता है जिसमें डुप्लिकेट कुंजी नहीं हो सकती हैं, और केवल अंतिम सेट-कुकी शीर्षलेख को स्टोर करेगी और बाकी को ओवरराइट करेगी ।एंड्रॉइड वॉली, डुप्लिकेट सेट-कुकी ओवरराइड

क्या इस मुद्दे के लिए कोई समाधान है?

क्या उपयोग करने के लिए कोई और lib है?

+2

बस इसे स्वयं देखें, यह Google से हास्यास्पद है। यह स्पष्ट है कि यह पुस्तकालय बहुत हल्के सामान के लिए है। – georgiecasey

+0

एंड्रॉइड वॉली के साथ कोई समस्या नहीं है। यह वेब सर्वर की एक समस्या है। सेट-कुकी एकाधिक नहीं हो सकता है। http://stackoverflow.com/questions/11533867/set-cookie-header-with-multiple-cookies –

+0

http://stackoverflow.com/a/25388897/2819864 सबसे तेज़ समाधान – RominaV

उत्तर

16

मैंने इसे ठीक करने के लिए कक्षाओं को पार करने की कोशिश की लेकिन जब मुझे NetworkResponse संपादित करना पड़ा, तो मैं खरगोश के नीचे बहुत नीचे उतर रहा था। तो मैंने एक सरणी में सभी प्रतिक्रिया शीर्षकों को पकड़ने के लिए सीधे वॉली को संपादित करने का फैसला किया, न कि मानचित्र।

मेरा कांटा GitHub पर है और मैंने example usage activity शामिल किया है।

मैंने this commit में विस्तृत के रूप में NetworkResponse.java, BasicNetwork.java और HurlStack.java में परिवर्तन किए हैं।

फिर अपने वास्तविक क्षुधा में उपयोग करने के लिए आप इस

protected Response<String> parseNetworkResponse(NetworkResponse response) { 
      // we must override this to get headers. and with the fix, we should get all headers including duplicate names 
      // in an array of apache headers called apacheHeaders. everything else about volley is the same 
      for (int i = 0; i < response.apacheHeaders.length; i++) { 
       String key = response.apacheHeaders[i].getName(); 
       String value = response.apacheHeaders[i].getValue(); 
       Log.d("VOLLEY_HEADERFIX",key + " - " +value); 
      } 

      return super.parseNetworkResponse(response); 
     } 

की तरह कुछ करना यह एक गंदे छोटे से हैक है लेकिन इस समय मेरे लिए अच्छी तरह से काम करने लगता है।

+1

मुझे आश्चर्य है कि यह अभी तक आधिकारिक रिलीज में नहीं है। तुम जानते हो क्यों? –

1

आप Network वॉली के वर्ग को ओवरराइड कर सकते हैं। PerformRequest और कनवर्ट करना देख रहे हैं BasicNetwork के हेडर विधियों में मदद मिल सकती है। फिर, RequestQueue के नियंत्रक को अपने नेटवर्क कार्यान्वयन को पास करना:

नया RequestQueue (नया NoCache(), नया YourOwnNetwork());

+0

हाय @ कज़ुकी, क्या आप डाल सकते हैं और उदाहरण? मैंने perfomRequest के साथ नेटवर्क (कस्टमनेटवर्क) का अपना इंटरफ़ेस बनाया है। फिर मैं इसके कार्यान्वयन को संशोधित करता हूं लेकिन मैं नए अनुरोधक्यू (...) में कस्टमनेटवर्क पास नहीं कर सकता। क्या तुम मेरी मदद कर सकते हो? –

3

आपको पहली चीज़ की आवश्यकता है BasicNetwork.convertHeaders विधि को कई मानचित्र मानों का समर्थन करने के लिए संशोधित करना है।

protected static Map<String, List<String>> convertHeaders(Header[] headers) { 
    Map<String, List<String>> result = new TreeMap<String, List<String>>(String.CASE_INSENSITIVE_ORDER); 
    for (int i = 0; i < headers.length; i++) { 
     Header header = headers[i]; 
     List<String> list = result.get(header.getName()); 
     if (list == null) { 
      list = new ArrayList<String>(1); 
      list.add(header.getValue()); 
      result.put(header.getName(), list); 
     } 
     else list.add(header.getValue()); 

    } 
    return result; 
} 

अगला बात आप की जरूरत DiskBasedCache.writeStringStringMap और DiskBasedCache.readStringStringMap तरीकों को संशोधित करने के लिए है: यहाँ संशोधित विधि का उदाहरण है। उन्हें कई मूल्यों का समर्थन करना चाहिए। यहाँ सहायक तरीकों के साथ-साथ पद्धति में सुधार किया जाता है:

static void writeStringStringMap(Map<String, List<String>> map, OutputStream os) throws IOException { 
    if (map != null) { 
     writeInt(os, map.size()); 
     for (Map.Entry<String, List<String>> entry : map.entrySet()) { 
      writeString(os, entry.getKey()); 
      writeString(os, joinStringsList(entry.getValue())); 
     } 
    } else { 
     writeInt(os, 0); 
    } 
} 

static Map<String, List<String>> readStringStringMap(InputStream is) throws IOException { 
    int size = readInt(is); 
    Map<String, List<String>> result = (size == 0) 
      ? Collections.<String, List<String>>emptyMap() 
      : new HashMap<String, List<String>>(size); 
    for (int i = 0; i < size; i++) { 
     String key = readString(is).intern(); 
     String value = readString(is).intern(); 
     result.put(key, parseNullStringsList(value)); 
    } 
    return result; 
} 

static List<String> parseNullStringsList(String str) { 
    String[] strs = str.split("\0"); 
    return Arrays.asList(strs); 
} 

static String joinStringsList(List<String> list) { 
    StringBuilder ret = new StringBuilder(); 
    boolean first = true; 
    for (String str : list) { 
     if (first) first = false; 
     else ret.append("\0"); 
     ret.append(str); 
    } 
    return ret.toString(); 
} 

और अंत में HttpHeaderParser वर्ग है। आपको parseCacheHeaders विधि एकाधिक मानों का समर्थन करना चाहिए। इस के लिए निम्नलिखित सहायक विधि का उपयोग करें:

public static String getHeaderValue(List<String> list) { 
    if ((list == null) || list.isEmpty()) return null; 
    return list.get(0); 
} 

और नवीनतम बात को संशोधित करने के स्थानों का एक समूह को बदलने के लिए

Map<String, String> 

को

Map<String, List<String>> 

यह करने के लिए अपने आईडीई का उपयोग है।

+0

हाय @ रुस्लान-यांच्याशिन, क्या आप उदाहरण देखने के लिए पूरा कोड डाल सकते हैं? मैं आपके चरणों का पालन करने की कोशिश कर रहा हूं, लेकिन जब मैं बेसिकनेटवर्क को ओवरराइड करने का प्रयास करता हूं तो मेरे पास बहुत निर्भरताएं होती हैं। क्या तुम मेरी मदद कर सकते हो? –

0

प्रश्न बहुत पुराना है, लेकिन अगर किसी की मदद करता है।नवीनतम वॉली में आपके पास है:

protected Response<String> parseNetworkResponse(NetworkResponse response) 
{ 
    List<Header> headers = response.allHeaders; 

    String sessionId = null; 

    for (Header header : headers) 
    { 
     // header.getName(); 
     // header.getValue(); 
    } 

    return super.parseNetworkResponse(response); 
} 
संबंधित मुद्दे