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?


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.


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


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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.