Hampir semua programmer java menulis RestController dalam hidupnya, tetapi beberapa orang bertanya-tanya apakah dia melakukannya dengan benar. Bahkan jika Anda seorang programmer yang berpengalaman, Anda mungkin memiliki pertanyaan yang akan saya coba jawab. Artikel ini akan membahas kerangka kerja seperti booting musim semi versi 1.5 dan 2.0, serta quarkus - saingan boot spring baru-baru ini dari topi merah.

Masalah
Diprogram untuk waktu yang lama di java dan spring boot 1.5. Tetapi ada kebutuhan untuk menulis proyek baru:
- Saya punya json untuk mengintegrasikan 1600 baris, beberapa kelas memiliki 100 bidang
- Saya ingin mencoba Kotlin dan Quarkus.
- Tulis pengendali istirahat yang akan dapat bekerja dengan kelas data kotlin tanpa penjelasan dan tanpa melibatkan sihir lombok. Saya ingin kelas data menjadi kecil
Anda mungkin menduga bahwa kelas data kotlin adalah kelas yang tidak dapat diubah, atau tidak bisa diubah. Kelas yang konstruktornya berisi semua bidang. Saya sangat percaya pada konsep ini; setelah membuat kelas, itu tidak dapat diubah, tidak ada setter di dalamnya. Karena gambar buruh pelabuhan tidak dapat diubah di dunia, kelas tanggal yang jatuh ke controller adalah sesuatu yang tidak bisa diubah.
Mari kita lihat kemungkinan cara untuk menyelesaikan masalah, lebih tepatnya bagaimana dalam proyek modern Anda dapat menulis controller:
Opsi standar. secara manual pada pegas atau pegas boot 1.5
Pengontrol sisanya muncul sejak lama, dan contoh berikut ini adalah contoh khas penggunaannya di java, yang ada di semua tutorial.
Kami baru saja membuat pengontrol paling sederhana
@RestController public class FruitController { @PostMapping("/fruit") public void greeting(@RequestBody Fruit request) { System.out.println(request); } }
Dan buat POJO (objek java lama biasa)
public class Fruit { public String name; public String description; public Fruit() { } public Fruit(String name, String description) { this.name = name; this.description = description; } }
mungkin ada variasi dengan bidang pribadi dan penjelasan getter / setter atau lombok, tapi bukan itu intinya.
Hebat, kami menciptakan pengontrol istirahat pertama yang berfungsi. Untuk 90% kasus, opsi kerja. Kamu bisa tinggal di sini
Masalahnya:
Konsep abadi berubah.
Kelas data sedikit verbose.Bisakah kita membuat kekal?
Reaksi alami untuk masalah ini adalah keputusan untuk menghapus konstruktor default dan mencegah pengeditan bidang kelas.
@Getter public class Fruit { private String name; private String description;
Tetapi sekarang masalah muncul, ternyata perpustakaan (kemungkinan besar jackson) tidak dapat membuat kelas. Kemungkinan besar Anda akan melihat kesalahan seperti
Tidak ada konstruktor default ditemukan.Jadi jackson pertama kali
membuat kelas menggunakan konstruktor tanpa parameter, dan kemudian disebut pengambil / penyetel . Sungguh mengerikan. Lagi pula, apakah ada konstruktor dengan semua parameter? Namun sayangnya, ketika kelas dikompilasi, parameternya terlihat seperti ini.
Yaitu saat runtime, java tidak tahu apa-apa tentang nama parameter di konstruktor. Kompiler kehilangan mereka.Opsi kedua adalah pegas atau pegas boot 1.5 + anotasi sebagai keselamatan
Jadi, kami menyadari bahwa kami menginginkan kelas yang tidak dapat diubah, dan kami tahu bahwa kami menggunakan jackson. Kemudian anatotika datang untuk menyelamatkan.
@Getter public class Fruit { private String name; private String description; @JsonCreator public Fruit(@JsonProperty("name") String name, @JsonProperty("description")String description) { this.name = name; this.description = description; } }
Saat ini, dalam proyek kami pada sping boot 1.5, penjelasan ini benar-benar penuh dengan segalanya.
Dan jika Anda menggunakan generator
jsonschema2pojo yang populer, itu akan menghasilkan lebih banyak anotasi. Jujur, saya tidak suka mereka.
Coba salin di sana:
{ "description": "description", "name": "name" }
Pada hasil yang kami dapatkan (Anda dapat menyipitkan mata dan membolak-balik):
@JsonInclude(JsonInclude.Include.NON_NULL) @JsonPropertyOrder({ "description", "name" }) public class Example { @JsonProperty("description") private String description; @JsonProperty("name") private String name; @JsonProperty("description") public String getDescription() { return description; } @JsonProperty("description") public void setDescription(String description) { this.description = description; } @JsonProperty("name") public String getName() { return name; } @JsonProperty("name") public void setName(String name) { this.name = name; } }
Cons:
Anotasi sangat meningkatkan kelas. Sangat verbose, untuk seorang amatir.Opsi ketiga pegas atau pegas boot 1,5 + bendera lombok
Terima kasih
Throwable, saya akan mengutip dari komentar:
โJika Anda menggunakan Lombok, maka cara terbaik adalah menulis di lombok.config:
lombok.allArgsConstructor.addConstructorProperties = true
Ini akan menghasilkan pada constructor
@java.beans.ConstructorProperties
, yang dipahami oleh Jackson. "
Pilihan bagus. Dia pasti akan menyelamatkan saya dari verbositas anotasi.
Cons:
Tapi saya ingin menggunakan Kotlin tanpa lombok.
Saya terlambat mempelajari opsi ini.Versi keempat Spring boot 2.0
@Getter public class Fruit { private String name; private String description; public Fruit( String name, String description) { this.name = name; this.description = description; } }
Anehnya, spring boot 2.0 bekerja dengan tenang dengan kelas yang tidak dapat diubah. Dan juga dengan kelas data kotlin saudara kembarnya
data class Fruit( val name : String, val description : String)
Tampaknya java di runtime tidak tahu nama-nama parameter dalam konstruktor, tetapi karena beberapa alasan spring boot2 sudah tahu cara bekerja dengan kelas data. Jadi, lihat spring-boot-starter-parent, dukungan Kotlin telah ditambahkan di sana.
<plugin> <groupId>org.jetbrains.kotlin</groupId> ... <configuration> <javaParameters>true</javaParameters> </configuration> </plugin> <plugin> <artifactId>maven-compiler-plugin</artifactId> <configuration> <parameters>true</parameters> </configuration> </plugin>
Saya mendekripsi. Agar
nama parameter dalam konstruktor kelas tidak hilang selama runtime, kompiler harus melewati flag javac -parameters. Dan spring boot 2.0 melakukan ini.
Proyek sampel pada
pegas boot 2 .
Opsi kelima. Quarkus + Kotlin
Quarkus memiliki
contoh layanan istirahat , analog dari opsi pertama saya. Yaitu pengendali istirahat dengan cara kuno. Namun, jika Anda ingin menggunakannya dengan Kotlin, Anda harus menambahkan flag seperti yang dilakukan spring boot 2.
Deskripsi masalah di
sini . Contoh cara menambahkan dukungan kelas data kotlin ke quarkus di
sini .
Kesimpulan
Anda dapat menggunakan opsi paling sederhana pertama untuk membuat pengendali istirahat, tetapi saya akan menyarankan untuk bergerak menuju kelas yang tidak dapat diubah. Tulis di Kotlin dan Anda tidak perlu lombok. Kode harus lebih mudah dan lebih mudah. Saya yakin bahwa pembuat pegas sengaja pergi untuk menambahkan
javac -parameters ke opsi kompiler dan seharusnya tidak ada kejahatan dalam hal ini. Semoga sukses untuk semua orang dalam perjalanan ke kode yang sempurna.
Terima kasih atas perhatian Anda!