Подтвердить что ты не робот

Ошибка андроида - волейбола

Я пытаюсь работать с некоторым устаревшим кодом и сталкивался с проблемой при использовании volley.

Я пытаюсь добраться до api, что наш главный сайт имеет, и он отлично работает для одной учетной записи, но не другой. Я пытаюсь разобраться, какие различия могут быть в URL-адресах запроса, а также о том, что возвращается в ответ, но я не могу найти способ в коде волейбола напечатать это в журнале.

Ошибка, которую я получаю,

com.android.volley.NoConnectionError: java.io.IOException: No authentication challenges found

Я читал, что это может быть связано с ответом 401, но я действительно не знаю, что это значит или, по крайней мере, как это доказать/проверить. Я действительно смущен тем, что он работает для одного аккаунта, а не другого.

URL-адрес немного отличается, как и для нашего сайта в Великобритании, а другой наш AM, но кроме этого нет никакой разницы.

Спасибо

4b9b3361

Ответ 1

Эта ошибка возникает, потому что сервер отправляет 401 (неавторизованный), но не дает "WWW-Authenticate", который является подсказкой для клиента, что делать дальше. Заголовок "WWW-Authenticate" сообщает клиенту, какой тип аутентификации необходим (Basic или Digest). Обычно это не очень полезно в безгласных http-клиентах, но это то, как определяется стандарт. Ошибка возникает из-за того, что lib пытается проанализировать заголовок "WWW-Authenticate", но не может.

Возможные решения, если вы можете изменить сервер:

  • Добавьте поддельный заголовок "WWW-Authenticate", например: WWW-Authenticate: Basic realm="fake". Это просто обходное решение, а не решение, но оно должно работать, и клиент http удовлетворен.
  • Используйте код состояния HTTP 403 вместо 401. Это семантика не то же самое и обычно при работе с логином 401 это правильный ответ (см. Здесь для подробного обсуждения), но его достаточно близко.

Возможные решения, если вы не можете изменить сервер:

Как писал @ErikZ в своем сообщении , вы можете использовать try & catch

HttpURLConnection connection = ...;
try {
    // Will throw IOException if server responds with 401.
    connection.getResponseCode(); 
} catch (IOException e) {
    // Will return 401, because now connection has the correct internal state.
    int responsecode = connection.getResponseCode(); 
}

Я также разместил это здесь: java.io.IOException: не найдено проблем с проверкой подлинности

Ответ 2

В самом деле, я решил эту проблему, включив заголовок WWW-Authenticate в ответ сервера.

Однако, если вы добавите заголовок WWW-Authenticate: Basic realm="", и ваш API также будет использоваться веб-клиентами, некоторые веб-браузеры вызовут всплывающее окно с запросом на основные учетные данные.

Для меня правильное решение использует пользовательскую схему. Как объяснено в этом сообщении в блоге, я использую xBasic вместо Basic в ответе заголовка.

WWW-Authenticate: xBasic realm=""

С этим заголовком не только Volley корректно анализирует ответ, но также избегаю веб-браузеров, показывающих, что аутентификация всплывает.

Ответ 3

Я смог поймать эту клиентскую сторону при инициализации волейбола RequestQueue:

Volley.newRequestQueue(getApplicationContext(), new HurlStack() {
        @Override
        public HttpResponse performRequest(Request<?> request, Map<String, String> additionalHeaders) {
            try {
                return super.performRequest(request, additionalHeaders);
            } catch (AuthFailureError authFailureError) {
                authFailureError.printStackTrace();
                // Log out / whatever you need to do here
            } catch (IOException e) {
                e.printStackTrace();
                if (e.getMessage().equals("No authentication challenges found")) {
                    // This is the error.  You probably will want to handle any IOException, not just those with the same message.
                }
            }
            return null;
        }
});

Ответ 4

Если сервер разбился, вы можете столкнуться с этой проблемой. Шаги:

  • Остановить сервер tomcat

  • goto Run → Services → перезапустить вашу базу данных (например: postgres)

  • Запустите сервер tomcat.

Ответ 5

Вы можете проверить, что e является экземпляром AuthFailureError.

Log.e(TAG, "AuthFailureError: " + (e instanceof AuthFailureError));