
Kita semua sering menulis metode sederhana dalam pengontrol yang bekerja melalui pengidentifikasi numerik.
@RequestMapping(value = {"/entityName/{entityId}/get"}, method = RequestMethod.GET) @ResponseBody public Entity get(@PathVariable(value = "entityId") Integer entityId) {
ID yang masuk harus divalidasi.
Misalnya, tidak semua pengguna memiliki akses ke semua ID.
Dapat dipahami bahwa menggunakan UUID lebih aman dan lebih dapat diandalkan. Tetapi itu harus dibuat, disimpan, diindeks, dll. Untuk semua entitas, melakukan ini panjang dan sulit. Dalam banyak kasus, lebih mudah untuk bekerja dengan ID numerik reguler.
Validasi dapat dilakukan dengan cara sederhana:
@RequestMapping(value = {"/entityName/{entityId}/get"}, method = RequestMethod.GET) @ResponseBody public Entity get(@PathVariable(value = "entityId") Integer entityId) { if(!@dao.validate(entityId)) return some_error;
Hanya ada satu nilai tambah dalam solusi ini. Sederhana dan cepat.
Yang lainnya buruk. Duplikasi kode, validasi tidak kompatibel dengan validasi objek, diperlukan pemrosesan terpisah di setiap metode.
Saya ingin melakukan ini:
@RequestMapping(value = {"/entityName/{entityId}/get"}, method = RequestMethod.GET) @ResponseBody public Entity get(@Validated @PathVariable(value = "entityId") Integer entityId) {
Opsi sederhana dan logis ini tidak berfungsi. Validator sama sekali tidak dipanggil. Validasi PathVariable oleh Spring tidak didukung.
Agar opsi ini berfungsi, Anda perlu mengubah PathVariable menjadi ModelAttribute:
@ModelAttribute private Integer integerAsModelAttribute(@PathVariable("entityId") Integer id) { return id; }
Dan mendapatkan kesalahan saat mengakses controller. Pembungkus tipe generik tidak memiliki konstruktor default tanpa parameter dan tidak ada setter. Ini berkeliling menggunakan Opsional. Ia memiliki konstruktor default dan setter yang menerima int biasa.
Ubah Integer menjadi Opsional:
@ModelAttribute private Integer integerAsModelAttribute(@PathVariable("entityId") Optional<Integer> id) { return id.orElse(null); }
Dan karenanya, metode pengontrol itu sendiri dan deklarasi validator:
@InitBinder({"entityId"}) protected void initCommissionIdBinder(WebDataBinder binder) { binder.setValidator(validateEntityIdValidator); binder.setBindEmptyMultipartFiles(false); } @RequestMapping(value = {"/entityName/{entityId}/get"}, method = RequestMethod.GET) @ResponseBody public Entity get(@Validated @ModelAttribute(value = "entityId") Integer entityId) {
Kelas validator benar-benar normal:
public class ValidateIntegerValidator implements Validator { @Override public boolean supports(Class<?> aClass) { return Integer.class.equals(aClass); } @Override public void validate(Object o, Errors errors) { if(o instanceof Integer) { Integer integer = (Integer) o; if(!dao.checkId(integer)) { errors.reject("-1", "ERROR"); } } else { errors.reject("-2","WRONG TYPE"); } } }
Contoh kerja lengkap dapat
diambil di sini .