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(".")
Джейк Уортон