Saya mencari cara termudah dan paling sederhana untuk mengikat dan mengkonversi data di Spring MVC. Jika memungkinkan, tanpa melakukan konfigurasi xml.
Sejauh ini saya telah menggunakan PropertyEditors seperti:
public class CategoryEditor extends PropertyEditorSupport {
// Converts a String to a Category (when submitting form)
@Override
public void setAsText(String text) {
Category c = new Category(text);
this.setValue(c);
}
// Converts a Category to a String (when displaying form)
@Override
public String getAsText() {
Category c = (Category) this.getValue();
return c.getName();
}
}
dan
...
public class MyController {
@InitBinder
public void initBinder(WebDataBinder binder) {
binder.registerCustomEditor(Category.class, new CategoryEditor());
}
...
}
Sederhana: kedua konversi didefinisikan dalam kelas yang sama, dan pengikatannya mudah. Jika saya ingin melakukan pengikatan umum di semua pengontrol saya, saya masih bisa menambahkan 3 baris dalam konfigurasi xml saya .
Tetapi Spring 3.x memperkenalkan cara baru untuk melakukannya, menggunakan Pengonversi :
Dalam wadah Spring, sistem ini dapat digunakan sebagai alternatif untuk PropertyEditors
Jadi katakanlah saya ingin menggunakan Pengonversi karena ini adalah "alternatif terbaru". Saya harus membuat dua konverter:
public class StringToCategory implements Converter<String, Category> {
@Override
public Category convert(String source) {
Category c = new Category(source);
return c;
}
}
public class CategoryToString implements Converter<Category, String> {
@Override
public String convert(Category source) {
return source.getName();
}
}
Kelemahan pertama: Saya harus membuat dua kelas. Manfaat: tidak perlu membuang berkat kemurahan hati.
Lalu, bagaimana cara saya mengikat data konverter?
Kelemahan kedua: Saya belum menemukan cara sederhana (anotasi atau fasilitas program lain) untuk melakukannya di controller: tidak seperti someSpringObject.registerCustomConverter(...);
.
Satu-satunya cara yang saya temukan akan membosankan, tidak sederhana, dan hanya tentang pengikatan lintas-pengontrol umum:
-
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean"> <property name="converters"> <set> <bean class="somepackage.StringToCategory"/> <bean class="somepackage.CategoryToString"/> </set> </property> </bean>
Konfigurasi Java ( hanya di Spring 3.1+ ):
@EnableWebMvc @Configuration public class WebConfig extends WebMvcConfigurerAdapter { @Override protected void addFormatters(FormatterRegistry registry) { registry.addConverter(new StringToCategory()); registry.addConverter(new CategoryToString()); } }
Dengan semua kelemahan ini, mengapa menggunakan Pengonversi? Apakah saya melewatkan sesuatu? Apakah ada trik lain yang tidak saya sadari?
Saya tergoda untuk terus menggunakan PropertyEditors ... Mengikat jauh lebih mudah dan lebih cepat.
sumber
Jawaban:
Tidak, saya pikir Anda telah mendeskripsikan PropertyEditor dan Konverter dengan sangat komprehensif, bagaimana masing-masing dinyatakan dan terdaftar.
Dalam pikiran saya, PropertyEditor terbatas dalam cakupan - mereka membantu mengkonversi String ke tipe, dan string ini biasanya berasal dari UI, dan mendaftarkan PropertyEditor menggunakan @InitBinder dan menggunakan WebDataBinder masuk akal.
Konverter di sisi lain lebih umum, ini dimaksudkan untuk konversi APAPUN dalam sistem - tidak hanya untuk konversi terkait UI (String ke jenis target). Misalnya, Integrasi Spring menggunakan konverter secara ekstensif untuk mengubah muatan pesan ke jenis yang diinginkan.
Saya pikir untuk aliran terkait UI PropertyEditors masih tepat terutama untuk kasus di mana Anda perlu melakukan sesuatu yang khusus untuk properti perintah tertentu. Untuk kasus lain, saya akan mengambil rekomendasi dari referensi Spring dan menulis konverter sebagai gantinya (misalnya, untuk mengkonversi dari id Panjang ke entitas katakan, sebagai sampel).
sumber
sumber
Yang paling sederhana (dengan asumsi bahwa Anda menggunakan kerangka kerja tetap), tetapi bukan cara yang sempurna adalah dengan mengimplementasikan konverter entitas generik melalui
ConditionalGenericConverter
antarmuka yang akan mengkonversi entitas menggunakan metadata mereka.Misalnya, jika Anda menggunakan JPA, konverter ini mungkin terlihat jika kelas yang ditentukan memiliki
@Entity
anotasi, dan menggunakan@Id
bidang beranotasi untuk mengekstrak informasi dan melakukan pencarian secara otomatis menggunakan nilai String yang disediakan sebagai Id untuk pencarian.ConditionalGenericConverter
adalah "senjata pamungkas" dari API konversi Spring, tetapi sedang diimplementasikan setelah itu akan dapat memproses sebagian besar konversi entitas, menghemat waktu pengembang - ini sangat melegakan ketika Anda hanya menentukan kelas entitas sebagai parameter controller Anda dan tidak pernah berpikir untuk mengimplementasikan konverter baru (kecuali untuk jenis khusus dan non-entitas, tentu saja).sumber
Anda dapat memilah-milah kebutuhan untuk memiliki dua kelas Konverter terpisah dengan menerapkan dua Konverter sebagai kelas statis dalam.
Anda masih perlu mendaftarkan keduanya secara terpisah, tetapi setidaknya ini mengurangi jumlah file yang perlu Anda modifikasi jika Anda membuat perubahan.
sumber