2013-09-25 6 views
19

私のAndroidアプリケーションのネットワークラッパーとしてVolleyのlibを使用しようとしています。私は接続を確立しているが、問題は複数の「Set-Cookie」ヘッダーがレスポンスに存在するたびにVolleyがMapを使用して重複キーを持つことができず、最後のSet-cookieヘッダーを格納して残りを上書きする。AndroidのVolley、重複したセットクッキーがオーバーライドされます

この問題の回避策はありますか?

別のライブラリがありますか?

+2

これは私自身、これはGoogleからばかげていることに気づくでしょう。このライブラリは非常に軽量なものを対象としていることは明らかです。 – georgiecasey

+0

Android Volleyには問題ありません。 Webサーバーの問題です。 Set-Cookieは複数にすることはできません。 http://stackoverflow.com/questions/11533867/set-cookie-header-with-multiple-cookies –

+0

http://stackoverflow.com/a/25388897/2819864は、最速のソリューションです – RominaV

答えて

16

私はこの問題を解決するためにoveridingクラスを試してみましたが、私はNetworkResponseを編集するために持っていたとき、私はあまりにも遠くラビットダウン降順ました。そこで私はVolleyを直接編集して、Mapではなく配列内のすべての応答ヘッダーを取得することにしました。

私のフォークは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メソッドとconvertHeadersメソッドを参照すると、BasicNetworkが役に立ちます。次に、ネットワーク実装をRequestQueueのコンストラクタに渡します。

新しいRequestQueue(新しいNoCache()、新しいYourOwnNetwork());

+0

こんにちは@カズキ、そして例?私は、perfomRequestとNetwork(CustomNetwork)の独自のインターフェイスを作成しました。それから私はそれの実装を変更するが、私は新しいRequestQueue(...)でCustomNetworkを渡すことはできません。私たちを手伝ってくれますか? –

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

をしたり変更したり、最新のものは、これを行うには、あなたのIDEを使用し

Map<String, List<String>> 

Map<String, String> 

を交換する場所の束です。

+0

こんにちは@ ruslan - yanchyshyn、例を見るために完全なコードを置くことができますか?私はあなたの手順に従おうとしていますが、BasicNetworkをオーバーライドしようとすると、私はたくさんの依存関係があります。私たちを手伝ってくれますか? –

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); 
} 
関連する問題