Intereting Posts
Тестирование на Android: целевое приложение против тестового приложения? Проигрыватель RTMP / RTSP в реальном времени без использования веб-браузера (WOWZA-сервера) на Android Как создать набор тестов для Android, который запускает только определенные тесты в одном или нескольких классах? Установка плагина ADT в разработке Eclipse для Android Показать ImageView программно Защита паролем Android Keystore GPS-акселерометр для расчета расстояния Реализация ластика в приложении для рисования Android – черный след, а затем прозрачный Где просмотреть параметры событий в приложениях Facebook Analytics? Исправлено TabLayout и Content overlap AppBar Как разместить кнопку внутри текста редактирования Как получить дополнительные разрешения для Facebook с Android-бета-версией sdk 3.0? Отправка запущенного приложения на задний план программно Невозможно разрешить символ «контекст» Как получить тему Holo Light, работающую в моем приложении Xamarin

Android Volley, дубликат Set-Cookie отменен

Попытка использовать Volley lib в качестве сетевой оболочки для моего приложения для Android. У меня есть соединение вверх и работает, но проблема в том, что каждый раз, когда в ответе Volley используется несколько заголовков «Set-Cookie», Volley использует Map, у которых нет дубликатов ключей, и будет хранить только последний заголовок Set-cookie и перезаписать остальные ,

Есть ли обходной путь для этой проблемы?

Есть ли другой lib для использования?

    Я попытался преодолеть классы, чтобы исправить это, но когда мне пришлось редактировать NetworkResponse , я спускался слишком далеко вниз по раввиту. Поэтому я решил просто отредактировать Volley напрямую, чтобы захватить все заголовки ответов в массиве, а не в Map.

    Моя вилка находится на GitHub, и я включил пример использования .

    Я внес изменения в 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); } 

    Это грязный маленький взлом, но, похоже, для меня сейчас хорошо.

    Первое, что вам нужно – это изменить метод 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>> 

    Для этого используйте вашу среду IDE.

    Вы можете переопределить класс волейбола. Возможно, вам помогут методы executeRequest и convertHeaders BasicNetwork . Затем, передав реализацию вашей сети разработчику RequestQueue, например:

    Новый RequestQueue (новый NoCache (), новый YourOwnNetwork ());