O retrofit 2 remove os caracteres após o nome do host do url de base

121

Estou usando o Retrofit para acessar uma API RESTful. O url base é:

http://api.example.com/service

Este é o código da interface:

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

e é assim que envio a solicitação e recebo a resposta:

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

o log que recebo é a coisa estranha:

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

O que está acontecendo aqui?

Ashkan Sarlak
fonte
você poderia resolver o problema? como também estou enfrentando o mesmo problema. e mesmo depois de tentar a resposta correta sempre recebo uma falha
Parth Anjaria

Respostas:

283

O retrofit 2 usa as mesmas regras que um <a href="">faria.

O início /de sua URL relativa informa ao Retrofit que é um caminho absoluto no host. Aqui está um exemplo de uma apresentação que fiz mostrando isso:

insira a descrição da imagem aqui

Observe o URL incorreto que foi resolvido na parte inferior.

Ao remover o início /, o URL torna-se relativo e se combina com os segmentos de caminho que fazem parte do URL base. Corrigido na apresentação, o URL final agora está correto:

insira a descrição da imagem aqui

Em seu exemplo, você não tem uma trilha /na URL base. Você provavelmente deseja adicionar um para que os caminhos relativos sejam resolvidos em cima dele, em vez de como um irmão dele.

Jake Wharton
fonte
12
Eu realmente não entendo por que esse novo tipo de resolução de URL é mais benéfico. Tudo o que você pode obter com isso são erros ocultos (como indicado por esta pergunta) e resultados contra-intuitivos ( http://api.example.com/service+ /album/featured-albumsnão é http://api.example.com/album/featured-albums). E esse erro silencioso não se origina de nada além de você colocar o /no final do url base ou na frente do URL da API. Existe algum caso de uso em que esse truncamento seja útil?
EpicPandaForce de
11
Faz sentido para mim depois de assistir à apresentação, mas seria ótimo adicionar uma pequena nota ao site. Levei alguns minutos para descobrir o que estava errado.
Albert Vila Calvo
8
@JakeWharton como faço @POSTpara o baseUrl(sem adicionar pathSegment? S Exemplo: baseUrlé http://api.example.com/album/featured-albumse eu quero minha @POSTchamada para ir para http://api.example.com/album/featured-albums. (O mesmo URL como base) @POST("") lança umjava.lang.IllegalArgumentException: Missing either @POST URL or @Url parameter.
ZakTaccardi
17
Uso@Post(".")
Jake Wharton