Retrofit 2 usuwa znaki po nazwie hosta z podstawowego adresu URL

121

Używam Retrofit, aby uzyskać dostęp do interfejsu API RESTful. Podstawowy adres URL to:

http://api.example.com/service

Oto kod interfejsu:

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

a tak wysyłam zapytanie i otrzymuję odpowiedź:

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();

dziennik, który otrzymuję, jest dziwną rzeczą:

V / Przykład ﹕ Odpowiedź {protokół = http / 1.1, kod = 404, wiadomość = nie znaleziono, url = http://api.example.com/album/featured-albums }

Co tu się dzieje?

Ashkan Sarlak
źródło
czy mógłbyś rozwiązać ten problem? ponieważ mam również ten sam problem. i nawet po wypróbowaniu poprawnej odpowiedzi zawsze popełniam błąd
Parth Anjaria

Odpowiedzi:

283

Retrofit 2 wykorzystuje te same zasady, co w <a href="">przypadku.

Początek /w Twoim względnym adresie URL informuje Retrofit, że jest to ścieżka bezwzględna na hoście. Oto przykład z prezentacji, którą przedstawiłem, pokazując to:

wprowadź opis obrazu tutaj

Zwróć uwagę na nieprawidłowy adres URL, który został rozwiązany na dole.

Po usunięciu początkowego /adresu URL staje się on względny i łączy się z segmentami ścieżki, które są częścią podstawowego adresu URL. Poprawiony w prezentacji końcowy URL jest teraz poprawny:

wprowadź opis obrazu tutaj

W twoim przykładzie nie masz końcowego /adresu URL. Prawdopodobnie chcesz dodać jeden, aby ścieżki względne były rozwiązywane na jego szczycie, a nie jako jego siostra.

Jake Wharton
źródło
12
Naprawdę nie rozumiem, dlaczego ten nowy typ rozpoznawania adresów URL jest korzystniejszy. Wszystko, co można z niego uzyskać, to ukryte błędy (jak wskazuje to pytanie) i sprzeczne z intuicją wyniki ( http://api.example.com/service+ /album/featured-albumsnie jest http://api.example.com/album/featured-albums). I ten cichy błąd wynika z niczego innego, jak tylko z tego, czy umieścisz /na końcu podstawowego adresu URL, czy na początku adresu URL interfejsu API. Czy są jakieś przypadki użycia, w których to obcięcie jest przydatne?
EpicPandaForce
1
Tutaj masz wideo z prezentacji
Albert Vila Calvo
11
Ma to dla mnie sens po obejrzeniu prezentacji, ale fajnie byłoby dodać małą notatkę do strony internetowej. Zajęło mi kilka minut, aby dowiedzieć się, co się dzieje.
Albert Vila Calvo
8
@JakeWharton jak mam @POSTdo baseUrl(bez dodawania pathSegment? S Przykład: baseUrljest http://api.example.com/album/featured-albumsi chcę moje @POSTwezwanie, aby przejść do http://api.example.com/album/featured-albums. (Tej samej zawartości jako zasady) @POST("") rzucajava.lang.IllegalArgumentException: Missing either @POST URL or @Url parameter.
ZakTaccardi
17
Użyj@Post(".")
Jake Wharton