Retrofit 2 удаляет символы после имени хоста из базового URL


121

Я использую Retrofit для доступа к RESTful api. Базовый URL-адрес:

http://api.example.com/service

Это код интерфейса:

public interface ExampleService {
    @Headers("Accept: Application/JSON")
    @POST("/album/featured-albums")
    Call<List<Album>> listFeaturedAlbums();
}

и вот как я отправляю запрос и получаю ответ:

new AsyncTask<Void, Void, Response<List<Album>>>() {

        @Override
        protected Response<List<Album>> doInBackground(Void... params) {
            Retrofit retrofit = new Retrofit.Builder()
                    .baseUrl("http://api.example.com/service")
                    .addConverterFactory(GsonConverterFactory.create())
                    .build();

            ExampleService service = retrofit.create(ExampleService.class);

            try {
                return service.listFeaturedAlbums().execute();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return null;
        }

        @Override
        protected void onPostExecute(Response<List<Album>> listCall) {
            Log.v("Example", listCall.raw().toString());
        }
    }.execute();

журнал, который я получаю, - это странная вещь:

V / Пример ﹕ Ответ {протокол = http / 1.1, код = 404, сообщение = не найдено, url = http://api.example.com/album/featured-albums }

Что тут происходит?


не могли бы вы решить проблему? поскольку я тоже сталкиваюсь с той же проблемой. и даже после того, как я пробую правильный ответ, я всегда терплю неудачу
— Парт Анджария

Ответы:


283

В Retrofit 2 используются те же правила, что и в Retrofit 2 <a href="">.

Начало /в вашем относительном URL-адресе сообщает Retrofit, что это абсолютный путь на хосте. Вот пример из презентации, которую я показал, показывая это:

введите описание изображения здесь

Обратите внимание на неправильный URL-адрес, который был разрешен внизу.

После удаления ведущего /URL-адрес становится относительным и объединяется с сегментами пути, которые являются частью базового URL-адреса. Исправлено в презентации, теперь конечный URL верен:

введите описание изображения здесь

В вашем примере у вас нет конца /базового URL. Вероятно, вы захотите добавить один, чтобы относительные пути разрешались поверх него, а не как его брат.


12
Я действительно не понимаю, почему этот новый тип разрешения URL более выгоден. Все, что вы можете получить от этого, - это скрытые ошибки (как указано в этом вопросе) и противоречивые результаты ( http://api.example.com/service+ /album/featured-albums- нет http://api.example.com/album/featured-albums). И эта скрытая ошибка возникает только из-за того, помещаете ли вы /в конец базового URL-адреса или перед URL-адресом API. Есть ли какие-либо варианты использования, в которых это усечение полезно?
— EpicPandaForce


11
Для меня это имеет смысл после просмотра презентации, но было бы здорово добавить небольшую заметку на сайт. Мне потребовалось несколько минут, чтобы понять, что пошло не так.
— Альберт Вила Кальво

8
@JakeWharton, как мне @POSTперейти к baseUrl(без добавления pathSegments? Пример: baseUrlесть, http://api.example.com/album/featured-albumsи я хочу, чтобы мой @POSTзвонок шел http://api.example.com/album/featured-albums(тот же URL-адрес, что и база). @POST("")java.lang.IllegalArgumentException: Missing either @POST URL or @Url parameter.
— Выдает

17
Использование@Post(".")
— Джейк Уортон
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.