Saya ingin tahu apa cara terbersih dan terbaik untuk melakukan validasi formulir input pengguna. Saya telah melihat beberapa pengembang mengimplementasikan org.springframework.validation.Validator
. Sebuah pertanyaan tentang itu: Saya melihatnya memvalidasi kelas. Apakah kelas harus diisi secara manual dengan nilai-nilai dari input pengguna, dan kemudian diteruskan ke validator?
Saya bingung tentang cara terbersih dan terbaik untuk memvalidasi input pengguna. Saya tahu tentang metode tradisional menggunakan request.getParameter()
dan kemudian memeriksa secara manual nulls
, tapi saya tidak ingin melakukan semua validasi di Controller
. Beberapa saran bagus tentang bidang ini akan sangat dihargai. Saya tidak menggunakan Hibernate dalam aplikasi ini.
sumber
Jawaban:
Dengan Spring MVC, ada 3 cara berbeda untuk melakukan validasi: menggunakan anotasi, secara manual, atau campuran keduanya. Tidak ada "cara terbersih dan terbaik" unik untuk memvalidasi, tetapi mungkin ada satu yang lebih cocok dengan proyek / masalah / konteks Anda.
Mari Punya Pengguna:
Metode 1: Jika Anda memiliki Spring 3.x + dan validasi sederhana untuk dilakukan, gunakan
javax.validation.constraints
anotasi (juga dikenal sebagai anotasi JSR-303).Anda akan membutuhkan penyedia JSR-303 di perpustakaan Anda, seperti Hibernate Validator yang merupakan implementasi referensi (perpustakaan ini tidak ada hubungannya dengan database dan pemetaan relasional, itu hanya validasi :-).
Kemudian di controller Anda, Anda akan memiliki sesuatu seperti:
Perhatikan @Valid: jika pengguna memiliki nama nol, result.hasErrors () akan benar.
Metode 2: Jika Anda memiliki validasi yang kompleks (seperti logika validasi bisnis besar, validasi bersyarat di berbagai bidang, dll.), Atau karena alasan tertentu Anda tidak dapat menggunakan metode 1, gunakan validasi manual. Ini adalah praktik yang baik untuk memisahkan kode pengontrol dari logika validasi. Jangan membuat kelas validasi Anda dari awal, Spring menyediakan
org.springframework.validation.Validator
antarmuka praktis (sejak Spring 2).Jadi katakanlah Anda punya
dan Anda ingin melakukan validasi "kompleks" seperti: jika usia pengguna di bawah 18, pengguna yang bertanggung jawab tidak boleh nol dan usia pengguna yang bertanggung jawab harus di atas 21.
Anda akan melakukan sesuatu seperti ini
Kemudian di controller Anda, Anda akan memiliki:
Jika ada kesalahan validasi, result.hasErrors () akan benar.
Catatan: Anda juga dapat mengatur validator dalam metode @InitBinder pada controller, dengan "binder.setValidator (...)" (dalam hal ini campuran penggunaan metode 1 dan 2 tidak akan mungkin, karena Anda mengganti default validator). Atau Anda bisa instantiate di konstruktor default controller. Atau memiliki @ Component / @ Service UserValidator yang Anda masukkan (@Autowired) di controller Anda: sangat berguna, karena sebagian besar validator singletons + mengejek unit test menjadi lebih mudah + validator Anda dapat memanggil komponen Spring lainnya.
Metode 3: Mengapa tidak menggunakan kombinasi kedua metode? Validasi hal-hal sederhana, seperti atribut "nama", dengan anotasi (cepat dilakukan, ringkas, dan lebih mudah dibaca). Pertahankan validasi berat untuk validator (saat itu akan memakan waktu berjam-jam untuk kode anotasi validasi kustom kompleks, atau hanya ketika itu tidak mungkin untuk menggunakan anotasi). Saya melakukan ini pada proyek sebelumnya, itu bekerja seperti pesona, cepat & mudah.
Peringatan: Anda tidak boleh salah mengartikan penanganan validasi untuk penanganan pengecualian . Baca posting ini untuk mengetahui kapan menggunakannya.
Referensi :
sumber
Ada dua cara untuk memvalidasi input pengguna: anotasi dan dengan mewarisi kelas Validator Musim Semi. Untuk kasus-kasus sederhana, penjelasannya bagus. Jika Anda memerlukan validasi kompleks (seperti validasi lintas-bidang, mis. Bidang "verifikasi alamat email"), atau jika model Anda divalidasi di banyak tempat dalam aplikasi Anda dengan aturan yang berbeda, atau jika Anda tidak memiliki kemampuan untuk memodifikasi memodelkan objek dengan menempatkan anotasi di atasnya, Validator berbasis warisan Spring adalah cara untuk pergi. Saya akan menunjukkan contoh keduanya.
Bagian validasi yang sebenarnya adalah sama, apa pun jenis validasinya yang Anda gunakan:
Jika Anda menggunakan anotasi,
Foo
kelas Anda mungkin terlihat seperti:Anotasi di atas adalah
javax.validation.constraints
anotasi. Anda juga dapat menggunakan Hibernateorg.hibernate.validator.constraints
, tetapi sepertinya Anda tidak menggunakan Hibernate.Atau, jika Anda menerapkan Validator Musim Semi, Anda akan membuat kelas sebagai berikut:
Jika menggunakan validator di atas, Anda juga harus mengikat validator ke controller Spring (tidak perlu jika menggunakan anotasi):
Lihat juga dokumen Spring .
Semoga itu bisa membantu.
sumber
Foo
parameter dalam metode handler. Bisakah Anda mengklarifikasi?Saya ingin menyampaikan jawaban yang bagus dari Jerome Dalbert. Saya menemukan sangat mudah untuk menulis validator anotasi Anda sendiri dengan cara JSR-303. Anda tidak dibatasi untuk memiliki validasi "satu bidang". Anda dapat membuat anotasi Anda sendiri pada level tipe dan memiliki validasi yang kompleks (lihat contoh di bawah). Saya lebih suka cara ini karena saya tidak perlu mencampur berbagai jenis validasi (Spring dan JSR-303) seperti yang dilakukan Jerome. Validator ini juga "Pegas sadar" sehingga Anda dapat menggunakan @ Suntikkan / @ Autowire di luar kotak.
Contoh validasi objek khusus:
Contoh persamaan bidang generik:
sumber
ElementType.METHOD
di@Target
.Jika Anda memiliki logika penanganan kesalahan yang sama untuk penangan metode yang berbeda, maka Anda akan berakhir dengan banyak penangan dengan pola kode berikut:
Misalkan Anda membuat layanan RESTful dan ingin kembali
400 Bad Request
bersama dengan pesan kesalahan untuk setiap kasus kesalahan validasi. Kemudian, bagian penanganan kesalahan akan sama untuk setiap titik akhir REST tunggal yang membutuhkan validasi. Mengulangi logika yang sama di setiap handler tidak terlalu kering !Salah satu cara untuk mengatasi masalah ini adalah dengan menjatuhkan segera
BindingResult
setelah setiap kacang To-Be-Validated . Sekarang, pawang Anda akan seperti ini:Dengan cara ini, jika kacang yang diikat tidak valid,
MethodArgumentNotValidException
akan dibuang oleh Spring. Anda bisa mendefinisikanControllerAdvice
yang menangani pengecualian ini dengan logika penanganan kesalahan yang sama:Anda masih dapat memeriksa metode
BindingResult
menggunakan yang mendasarinya .getBindingResult
MethodArgumentNotValidException
sumber
Temukan contoh lengkap Spring Mvc Validation
sumber
Masukkan kacang ini di kelas konfigurasi Anda.
dan kemudian Anda dapat menggunakan
untuk memvalidasi kacang secara manual. Kemudian Anda akan mendapatkan semua hasil dalam BindingResult dan Anda dapat mengambilnya dari sana.
sumber