Pertanyaan ini mungkin telah ditanyakan sebelumnya tetapi tidak, itu tidak dijawab secara definitif. Bagaimana tepatnya satu posting seluruh JSON mentah di dalam tubuh permintaan Retrofit?
Lihat pertanyaan serupa di sini . Atau apakah jawaban ini benar bahwa harus berupa url yang disandikan dan diteruskan sebagai bidang ? Saya benar-benar berharap tidak, karena layanan yang saya sambungkan hanya mengharapkan JSON mentah di badan pos. Mereka tidak diatur untuk mencari bidang tertentu untuk data JSON.
Saya hanya ingin mengklarifikasi ini dengan restperts sekali dan untuk semua. Satu orang menjawab untuk tidak menggunakan Retrofit. Yang lain tidak yakin dengan sintaksisnya. Lain berpikir ya itu bisa dilakukan tetapi hanya jika bentuknya disandikan url dan ditempatkan di lapangan (itu tidak dapat diterima dalam kasus saya). Tidak, saya tidak bisa membuat ulang kode semua layanan untuk klien Android saya. Dan ya, sangat umum dalam proyek-proyek besar untuk mengirim JSON mentah alih-alih menyerahkan konten JSON sebagai nilai properti bidang. Mari kita lakukan dengan benar dan melanjutkan. Dapatkah seseorang menunjuk pada dokumentasi atau contoh yang menunjukkan bagaimana hal ini dilakukan? Atau berikan alasan yang valid mengapa itu bisa / tidak boleh dilakukan.
UPDATE: Satu hal yang bisa saya katakan dengan kepastian 100%. Anda BISA melakukan ini di Volley Google. Itu sudah terpasang. Bisakah kita melakukan ini di Retrofit?
RequestBody
seperti ini ->RequestBody body = RequestBody.create(MediaType.parse("text/plain"), text);
untuk jawaban terinci futurestud.io/tutorials/…Jawaban:
The
@Body
penjelasan mendefinisikan permintaan badan tunggal.Karena Retrofit menggunakan Gson secara default,
FooRequest
instans akan diserialisasi sebagai JSON sebagai satu-satunya badan permintaan.Panggilan dengan:
Akan menghasilkan tubuh berikut:
Dokumen Gson memiliki lebih banyak tentang cara kerja serialisasi objek.
Sekarang, jika Anda benar-benar ingin mengirim JSON "mentah" sebagai tubuh sendiri (tapi tolong gunakan Gson untuk ini!) Anda masih dapat menggunakan
TypedInput
:TypedInput didefinisikan sebagai "Data biner dengan tipe mime terkait." Ada dua cara untuk dengan mudah mengirim data mentah dengan deklarasi di atas:
Gunakan TypedByteArray untuk mengirim byte mentah dan tipe mime JSON:
Subclass TypedString untuk membuat
TypedJsonString
kelas:Dan kemudian gunakan instance dari kelas yang mirip dengan # 1.
sumber
TypedString
karena sudah dihapus?RequestBody
untuk membuat tubuh mentah.java.lang.IllegalArgumentException: Unable to create @Body converter for class MatchAPIRequestBody (parameter #1)
Sebagai pengganti kelas kita juga dapat langsung menggunakan
HashMap<String, Object>
untuk mengirim parameter tubuh misalnyasumber
IllegalArgumentException: Unable to create @Body converter for java.util.HashMap<java.lang.String, java.lang.Object>
dengan Moshi. Saya pikir Gson diperlukan agar ini berfungsiYa saya tahu ini sudah terlambat, tetapi seseorang mungkin akan mendapat manfaat dari ini.
Menggunakan Retrofit2:
Saya menemukan masalah ini tadi malam bermigrasi dari Volley ke Retrofit2 (dan seperti yang dinyatakan OP, ini dibangun langsung ke Volley bersama
JsonObjectRequest
), dan meskipun jawaban Jake adalah yang benar untuk Retrofit1.9 , Retrofit2 tidak punyaTypedString
.Kasing saya membutuhkan pengiriman
Map<String,Object>
yang dapat berisi beberapa nilai nol, dikonversi ke JSONObject (yang tidak akan terbang@FieldMap
, begitu pula karakter khusus, beberapa dikonversi), jadi ikuti petunjuk @bnorms, dan seperti yang dinyatakan oleh Square :Jadi ini adalah opsi menggunakan
RequestBody
danResponseBody
:Di antarmuka Anda gunakan
@Body
denganRequestBody
Di titik panggilan Anda buat
RequestBody
, nyatakan itu adalah MediaType, dan gunakan JSONObject untuk mengonversi Peta Anda ke format yang tepat:Semoga ini Membantu siapa pun!
Versi Kotlin yang elegan di atas, untuk memungkinkan abstrak parameter dari konversi JSON di sisa kode aplikasi Anda:
sumber
JsonObjectRequest
, yang perlu Anda lakukan adalah ini. Jawaban yang bagus.post a null value
properti di requestBody yang sebaliknya diabaikan.jsonParams.put("code", some_code);
di baris ketiga?Di Retrofit2 , Saat Anda ingin mengirim parameter Anda secara baku, Anda harus menggunakan Skalar .
pertama tambahkan ini di gradle Anda:
Antarmuka Anda
Aktivitas
sumber
GsonConverterFactory
,.toString()
itu tidak perlu. Anda dapat mendeklarasikanCall<User> getUser(@Body JsonObject body);
menggunakanJsonObject
alih-alihJSONObject
dan meneruskanparamObject
secara langsung. Ini akan bekerja dengan baik.Penggunaan
JsonObject
adalah sebagaimana adanya:Buat antarmuka Anda seperti ini:
Jadikan JsonObject sesuai dengan struktur jsons.
Panggil layanan:
Dan itu! Menurut pendapat pribadi saya, ini jauh lebih baik daripada membuat pojo dan bekerja dengan kekacauan kelas. Ini jauh lebih bersih.
sumber
Saya terutama menyukai saran Jake tentang
TypedString
subkelas di atas . Anda memang dapat membuat berbagai subclass berdasarkan jenis data POST yang Anda rencanakan untuk ditingkatkan, masing-masing dengan set kustom tweak yang konsisten.Anda juga memiliki opsi untuk menambahkan anotasi header ke metode JSON POST Anda di Retrofit API Anda ...
... tetapi menggunakan subkelas lebih jelas mendokumentasikan diri.
sumber
1) Tambahkan dependensi-
2) membuat kelas Api Handler
3) membuat kelas kacang dari Json schema 2 pojo
http://www.jsonschema2pojo.org/
4) membuat antarmuka untuk panggilan api
5) membuat JsonObject untuk diteruskan ke tubuh sebagai parameter
6) Panggil Api Seperti ini
sumber
Saya menemukan bahwa ketika Anda menggunakan objek majemuk sebagai
@Body
params, itu tidak dapat bekerja dengan baik dengan RetrofitGSONConverter
(dengan asumsi Anda menggunakannya). Anda harus menggunakanJsonObject
dan tidakJSONObject
ketika bekerja dengan itu, ia menambahkanNameValueParams
tanpa bertele-tele tentang itu - Anda hanya dapat melihat bahwa jika Anda menambahkan ketergantungan lain dari penebang pencegat, dan shenanigans lainnya.Jadi apa yang saya temukan pendekatan terbaik untuk mengatasi ini adalah menggunakan
RequestBody
. Anda mengubah objek AndaRequestBody
dengan panggilan api sederhana dan meluncurkannya. Dalam kasus saya, saya mengonversi peta:dan inilah panggilannya:
sumber
Tambahkan ScalarsConverterFactory ke retrofit:
dalam gradle:
retrofit Anda:
ubah parameter antarmuka panggilan @Body ke String, jangan lupa tambahkan
@Headers("Content-Type: application/json")
:sekarang Anda dapat memposting json mentah.
sumber
Anda dapat menggunakan hashmap jika Anda tidak ingin membuat kelas pojo untuk setiap panggilan API.
Dan kemudian kirim seperti ini
sumber
gunakan berikut untuk mengirim json
dan berikan ke url
sumber
Setelah begitu banyak upaya, ditemukan bahwa perbedaan mendasar adalah Anda perlu mengirim
JsonObject
bukanJSONObject
parameter.sumber
Berdasarkan jawaban teratas, saya punya solusi untuk tidak harus membuat POJO untuk setiap permintaan.
Contoh, saya ingin memposting JSON ini.
lalu, saya membuat kelas umum seperti ini:
Akhirnya, ketika saya membutuhkan json
Permintaan yang ditandai anotasi
@Body
kemudian dapat diteruskan ke Retrofit.sumber
Jika Anda tidak ingin membuat kelas atau penggunaan tambahan,
JSONObject
Anda dapat menggunakan aHashMap
.Antarmuka retrofit:
Panggilan:
sumber
Hal-hal yang diperlukan untuk mengirim json mentah di Retrofit.
1) Pastikan untuk menambahkan header berikut dan menghapus header duplikat lainnya. Karena, pada dokumentasi resmi Retrofit mereka secara spesifik menyebutkan-
2) a. Jika Anda menggunakan pabrik konverter, Anda dapat melewatkan json Anda sebagai sebuah String, JSONObject, JsonObject dan bahkan POJO. Juga telah memeriksa,
ScalarConverterFactory
tidak perlu hanyaGsonConverterFactory
melakukan pekerjaan.2) b. Jika Anda TIDAK menggunakan pabrik konverter apa pun maka Anda HARUS menggunakan RequestBody okhttp3 seperti yang dikatakan dokumentasi Retrofit-
3) Sukses !!
sumber
Inilah yang bekerja saya untuk versi
retrofit
2.6.2 saat ini ,Pertama-tama, kita perlu menambahkan Scalars Converter ke daftar dependensi Gradle kita, yang akan mengurusi konversi java.lang. Objek-objek tring ke teks / badan permintaan polos,
Kemudian, kita perlu melewati pabrik konverter ke pembuat Retrofit kita. Nantinya akan memberi tahu Retrofit cara mengonversi parameter @Body yang dilewatkan ke layanan.
Kemudian Retrofit service dengan parameter String body.
Kemudian buat tubuh JSON
Hubungi layanan Anda
sumber
✅✅✅✅✅✅✅✅✅✅✅✅ Solusi Kerja ✅✅✅✅✅✅✅✅✅✅✅✅
Saat membuat
OkHttpClient
itu akan digunakan untuk Retrofit.tambahkan Interceptor seperti ini.
Sekarang Anda setiap Retrofit call URL dan permintaan tubuh akan login di
Logcat
. Saring dengan"gsonrequest"
sumber
Saya mencoba ini: Ketika Anda membuat instance Retrofit Anda, tambahkan pabrik konverter ini ke pembuat retrofit:
sumber
Memecahkan masalah saya berdasarkan jawaban TommySM (lihat sebelumnya). Tetapi saya tidak perlu melakukan login, saya menggunakan Retrofit2 untuk menguji https GraphQL API seperti ini:
Menentukan kelas BaseResponse saya dengan bantuan anotasi json (import jackson.annotation.JsonProperty).
Menetapkan prosedur panggilan di antarmuka:
Disebut apicall di badan pengujian: Buat variabel tipe MyRequest (misalnya "myLittleRequest").
sumber
Untuk lebih jelasnya pada jawaban yang diberikan di sini, ini adalah bagaimana Anda dapat menggunakan fungsi ekstensi. Ini hanya jika Anda menggunakan Kotlin
Jika Anda menggunakan
com.squareup.okhttp3:okhttp:4.0.1
metode lama dalam membuat objek MediaType dan RequestBody telah usang dan tidak dapat digunakan di Kotlin .Jika Anda ingin menggunakan fungsi ekstensi untuk mendapatkan objek MediaType dan objek ResponseBody dari string Anda, pertama-tama tambahkan baris berikut ke kelas di mana Anda ingin menggunakannya.
Anda sekarang dapat secara langsung mendapatkan objek MediaType dengan cara ini
Untuk mendapatkan objek dari RequestBody, konversikan dulu JSONObject yang ingin Anda kirim ke string dengan cara ini. Anda harus meneruskan objek mediaType ke sana.
sumber
Saya ingin membandingkan kecepatan voli dan retrofit untuk mengirim dan menerima data yang saya tulis di bawah kode (untuk bagian retrofit)
ketergantungan pertama:
Lalu antarmuka:
dan fungsi untuk mengatur parameter untuk mengirim data ke server (Dalam MainActivity):
Dan saya menemukan Retrofit lebih cepat daripada voli dalam kasus saya.
sumber