Retrofit 2 rimuove i caratteri dopo il nome host dall'URL di base


121

Sto usando Retrofit per accedere a un'API RESTful. L'URL di base è:

http://api.example.com/service

Questo è il codice per l'interfaccia:

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

ed è così che invio la richiesta e ricevo la risposta:

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

il registro che ricevo è la cosa strana:

V / Esempio ﹕ Risposta {protocol = http / 1.1, code = 404, message = Not Found, url = http://api.example.com/album/featured-albums }

Cosa sta succedendo qui?


potresti risolvere il problema? poiché anch'io sto affrontando lo stesso problema. e anche dopo aver provato la risposta corretta ottengo sempre un errore
Parth Anjaria

Risposte:


283

Retrofit 2 utilizza le stesse regole di un <a href="">.

La parte iniziale /del tuo URL relativo indica a Retrofit che si tratta di un percorso assoluto sull'host. Ecco un esempio da una presentazione che ho dato che mostra questo:

inserisci qui la descrizione dell'immagine

Nota l'URL errato che è stato risolto in fondo.

Rimuovendo l'interlinea /, l'URL diventa quindi relativo e si combinerà con i segmenti di percorso che fanno parte dell'URL di base. Corretto nella presentazione l'URL finale ora è corretto:

inserisci qui la descrizione dell'immagine

Nel tuo esempio non hai un finale /sull'URL di base. Probabilmente vorrai aggiungerne uno in modo che i percorsi relativi siano risolti sopra di esso piuttosto che come un fratello di esso.


12
Non capisco davvero perché questo nuovo tipo di risoluzione degli URL sia più vantaggioso. Tutto ciò che puoi ottenere da esso sono errori nascosti (come indicato da questa domanda) e risultati controintuitivi ( http://api.example.com/service+ /album/featured-albumsnon lo è http://api.example.com/album/featured-albums). E questo errore silenzioso non deriva da nient'altro che dal fatto che si inserisca /alla fine dell'URL di base o all'inizio dell'URL dell'API. Esistono casi d'uso in cui questo troncamento è utile?
EpicPandaForce


11
Per me ha senso dopo aver visto la presentazione, ma sarebbe fantastico aggiungere una piccola nota al sito web. Mi ci sono voluti alcuni minuti per scoprire cosa stava andando storto.
Albert Vila Calvo

8
@JakeWharton come faccio @POSTa baseUrl(senza aggiungere alcuna pathSegments? Esempio: baseUrlè http://api.example.com/album/featured-albumse voglio che la mia @POSTchiamata vada a http://api.example.com/album/featured-albums(stesso URL della base). @POST("") Lancia ajava.lang.IllegalArgumentException: Missing either @POST URL or @Url parameter.
ZakTaccardi

17
Usa@Post(".")
Jake Wharton
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.