Retrofit 2 menghapus karakter setelah nama host dari url dasar

121

Saya menggunakan Retrofit untuk mengakses RESTful api. Url dasarnya adalah:

http://api.example.com/service

Ini adalah kode untuk antarmuka:

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

dan inilah cara saya mengirim permintaan dan menerima tanggapan:

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

log yang saya dapatkan adalah hal yang aneh:

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

Apa yang terjadi di sini?

Ashkan Sarlak
sumber
bisakah Anda menyelesaikan masalah ini? karena saya juga menghadapi masalah yang sama. dan bahkan setelah saya mencoba jawaban yang benar, saya selalu gagal
Parth Anjaria

Jawaban:

283

Retrofit 2 menggunakan aturan yang sama dengan wasiat <a href="">.

Awalan /di URL relatif Anda memberi tahu Retrofit bahwa ini adalah jalur mutlak pada host. Inilah contoh dari presentasi yang saya berikan menunjukkan ini:

masukkan deskripsi gambar di sini

Perhatikan URL yang salah yang diselesaikan di bagian bawah.

Dengan menghapus awalan /, URL kemudian menjadi relatif dan akan digabungkan dengan segmen jalur yang merupakan bagian dari URL dasar. Dikoreksi dalam presentasi, URL final sekarang sudah benar:

masukkan deskripsi gambar di sini

Dalam contoh Anda, Anda tidak memiliki jejak /pada URL dasar. Anda mungkin ingin menambahkan satu sehingga jalur relatif diselesaikan di atasnya, bukan sebagai saudara kandungnya.

Jake Wharton
sumber
12
Saya tidak begitu mengerti mengapa jenis resolusi URL baru ini lebih menguntungkan. Yang bisa Anda dapatkan darinya hanyalah kesalahan tersembunyi (seperti yang ditunjukkan oleh pertanyaan ini), dan hasil kontra-intuitif ( http://api.example.com/service+ /album/featured-albumsbukan http://api.example.com/album/featured-albums). Dan kesalahan diam ini berasal dari apa pun kecuali apakah Anda menempatkannya /di akhir url dasar atau di depan URL API. Apakah ada kasus penggunaan di mana pemotongan ini berguna?
EpicPandaForce
11
Masuk akal bagi saya setelah menonton presentasi, tetapi akan sangat bagus untuk menambahkan catatan kecil ke situs web. Saya butuh beberapa menit untuk mencari tahu apa yang salah.
Albert Vila Calvo
8
@JakeWharton bagaimana cara saya @POSTke baseUrl(tanpa menambahkan apa pun pathSegment? Contoh: baseUrladalah http://api.example.com/album/featured-albumsdan saya ingin @POSTpanggilan saya pergi ke http://api.example.com/album/featured-albums(URL yang sama sebagai basis). @POST("")java.lang.IllegalArgumentException: Missing either @POST URL or @Url parameter.
Melempar
17
Gunakan@Post(".")
Jake Wharton