Perbedaan antara @Valid dan @Validated di Spring

107

Spring mendukung dua metode validasi yang berbeda: validasi Spring dan validasi kacang JSR-303. Keduanya dapat digunakan dengan mendefinisikan validator Spring yang didelegasikan ke delegator lain termasuk bean validator. Sejauh ini baik.

Tetapi ketika memberi anotasi metode untuk benar-benar meminta validasi, itu cerita lain. Saya bisa memberi anotasi seperti ini

@RequestMapping(value = "/object", method = RequestMethod.POST)
public @ResponseBody TestObject create(@Valid @RequestBody TestObject obj, BindingResult result) {

atau seperti ini

@RequestMapping(value = "/object", method = RequestMethod.POST)
public @ResponseBody TestObject create(@Validated @RequestBody TestObject obj, BindingResult result) {

Di sini, @Valid adalah javax.validation.Valid , dan @Validated adalah org.springframework.validation.annotation.Validated . Dokumen untuk yang terakhir mengatakan

Varian Valid JSR-303, mendukung spesifikasi grup validasi. Didesain untuk penggunaan yang nyaman dengan dukungan JSR-303 Spring tetapi tidak spesifik JSR-303.

yang tidak banyak membantu karena tidak memberi tahu persis bagaimana perbedaannya. Jika sama sekali. Keduanya tampaknya bekerja dengan baik untuk saya.

Sergei Tachenov
sumber
2
Mungkin menarik: stackoverflow.com/questions/18911154/…
Wim Deblauwe
4
"mendukung spesifikasi grup validasi" adalah pernyataan yang sangat eksplisit.
oliver yang lebih baik
Saya harus berpikir bahwa Valid terkait erat dengan validasi JSR 303 (NotNull, dll). Sedangkan Anda dapat membuat validasi / grup lain dan memeriksanya di Divalidasi.
Atul
@zeroflagL, benar, tetapi karena saya belum pernah menggunakannya, saya melewatkan intinya dan malah terpaku pada bagian "bukan khusus JSR-303". Sekarang sudah jelas.
Sergei Tachenov

Jawaban:

83

Seperti yang Anda kutip dari dokumentasi, @Validatedditambahkan untuk mendukung "grup validasi", yaitu grup bidang dalam kacang yang divalidasi. Ini dapat digunakan dalam formulir multi langkah di mana Anda dapat memvalidasi nama, email, dll .. pada langkah pertama dan kemudian bidang lain pada langkah berikutnya.

Alasan mengapa ini tidak ditambahkan ke dalam @Validanotasi adalah karena itu distandarisasi menggunakan proses komunitas java (JSR-303), yang membutuhkan waktu dan pengembang Spring ingin mengizinkan orang untuk menggunakan fungsi ini lebih cepat.

Buka tiket jira ini untuk melihat bagaimana anotasi muncul.

František Hartman
sumber
114

Jawaban yang lebih jujur. Bagi mereka yang masih belum tahu apa itu "grup validasi" .

Penggunaan untuk @ValidValidasi

Pengontrol:

@RequestMapping(value = "createAccount")
public String stepOne(@Valid Account account) {...}

Bentuk objek:

public class Account {

    @NotBlank
    private String username;

    @Email
    @NotBlank
    private String email;

}

Penggunaan untuk@Validated
Sumber Grup Validasi : http://blog.codeleak.pl/2014/08/validation-groups-in-spring-mvc.html

Pengontrol:

@RequestMapping(value = "stepOne")
public String stepOne(@Validated(Account.ValidationStepOne.class) Account account) {...}

@RequestMapping(value = "stepTwo")
public String stepTwo(@Validated(Account.ValidationStepTwo.class) Account account) {...}

Bentuk objek:

public class Account {

    @NotBlank(groups = {ValidationStepOne.class})
    private String username;

    @Email(groups = {ValidationStepOne.class})
    @NotBlank(groups = {ValidationStepOne.class})
    private String email;

    @NotBlank(groups = {ValidationStepTwo.class})
    @StrongPassword(groups = {ValidationStepTwo.class})
    private String password;

    @NotBlank(groups = {ValidationStepTwo.class})
    private String confirmedPassword;

}
zhuhang.jasper
sumber
terima kasih @ Zhuhang.jasper karena telah menjelaskan secara detail dengan sangat sederhana.
Gautam Tyagi
Ini persis seperti yang saya cari selama 2 jam terakhir, terima kasih @ Zhuhang.jasper
Shady Hussein
terima kasih @zhuhang. telah mencari ini.
Wisnu Dahatonde
4

Dalam contoh cuplikan kode pertanyaan, @Validdan @Validatedtidak ada bedanya. Tetapi jika @RequestBodydianotasi dengan sebuah Listobjek, atau nilai string dianotasi oleh @RequestParam, validasi tidak akan berpengaruh.

Kita dapat menggunakan @Validatedkemampuan validasi tingkat metode untuk membuatnya bekerja. Untuk mencapai ini, poin kuncinya adalah ditempatkan @Validateddi kelas. Ini mungkin perbedaan penting lainnya antara @Validdan @Validateddalam kerangka pegas.

Refrence

Lebecca
sumber
Bisakah Anda menjelaskan mengapa anotasi tidak berpengaruh pada Listobjek? Saya berasumsi bahwa ini juga tidak akan berfungsi untuk koleksi lain seperti Map? Mungkin Anda bisa memberi saya penjelasan yang lebih rinci dalam pertanyaan saya: stackoverflow.com/questions/60167961/…
Theiaz
1
@TheiaSeperti yang Anda inginkan
Lebecca
1

selain di atas, Anda hanya dapat menerapkan @Validpada domain / bidang untuk validasi bersarang, bukan dengan @validated.

Zelin Zhu
sumber