Retrofit 2 entfernt Zeichen nach dem Hostnamen aus der Basis-URL

121

Ich verwende Retrofit, um auf eine RESTful-API zuzugreifen. Die Basis-URL lautet:

http://api.example.com/service

Dies ist der Code für die Schnittstelle:

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

und so sende ich eine Anfrage und erhalte die Antwort:

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

Das Protokoll, das ich bekomme, ist das Seltsame:

V / Beispiel ﹕ Antwort {Protokoll = http / 1.1, Code = 404, Nachricht = Nicht gefunden, URL = http://api.example.com/album/featured-albums }

Was ist denn hier los?

Ashkan Sarlak
quelle
Könnten Sie das Problem lösen? da ich auch vor dem gleichen Problem stehe. und selbst nachdem ich die richtige Antwort versucht habe, bekomme ich immer einen Fehler
Parth Anjaria

Antworten:

283

Nachrüstung 2 verwendet die gleichen Regeln wie ein Nachrüsten <a href="">.

Der führende /Wert in Ihrer relativen URL teilt Retrofit mit, dass es sich um einen absoluten Pfad auf dem Host handelt. Hier ist ein Beispiel aus einer Präsentation, die ich gegeben habe:

Geben Sie hier die Bildbeschreibung ein

Beachten Sie die falsche URL, die unten behoben wurde.

Durch Entfernen der führenden /URL wird die URL dann relativ und wird mit den Pfadsegmenten kombiniert, die Teil der Basis-URL sind. In der Präsentation korrigiert, ist die endgültige URL jetzt korrekt:

Geben Sie hier die Bildbeschreibung ein

In Ihrem Beispiel haben Sie kein Trailing /in der Basis-URL. Sie möchten wahrscheinlich einen hinzufügen, damit relative Pfade darüber aufgelöst werden und nicht als Geschwister.

Jake Wharton
quelle
12
Ich verstehe nicht wirklich, warum diese neue Art der URL-Auflösung vorteilhafter ist. Alles, was Sie daraus erhalten können, sind versteckte Fehler (wie in dieser Frage angegeben) und kontraintuitive Ergebnisse ( http://api.example.com/service+ /album/featured-albumsist nicht http://api.example.com/album/featured-albums). Und dieser stille Fehler ist nur darauf zurückzuführen, ob Sie die /am Ende der Basis-URL oder an der Vorderseite der API-URL platzieren. Gibt es Anwendungsfälle, in denen diese Kürzung nützlich ist?
EpicPandaForce
11
Es macht für mich nach dem Anschauen der Präsentation Sinn, aber es wäre großartig, der Website eine kleine Notiz hinzuzufügen. Ich brauchte einige Minuten, um herauszufinden, was falsch lief.
Albert Vila Calvo
8
@ JakeWharton Wie gehe ich @POSTzum baseUrl(ohne pathSegments hinzuzufügen ? Beispiel: baseUrlist http://api.example.com/album/featured-albumsund ich möchte, dass mein @POSTAnruf zu http://api.example.com/album/featured-albums(gleiche URL wie Basis) geht. @POST("") Wirft einjava.lang.IllegalArgumentException: Missing either @POST URL or @Url parameter.
ZakTaccardi
17
Verwenden Sie@Post(".")
Jake Wharton