التحقق من صحة المعلمات العامة في وحدات تحكم الربيع

الصورة
غالبًا ما نكتب طرقًا بسيطة في وحدات التحكم تعمل من خلال المعرّفات الرقمية.

@RequestMapping(value = {"/entityName/{entityId}/get"}, method = RequestMethod.GET) @ResponseBody public Entity get(@PathVariable(value = "entityId") Integer entityId) { //    ID } 

يجب التحقق من صحة المعرف الوارد. على سبيل المثال ، ليس كل المستخدمين لديهم حق الوصول إلى جميع المعرفات.

من المفهوم أن استخدام UUIDs أكثر أمانًا وموثوقية. ولكن يجب إنشاؤها وتخزينها وفهرستها ، إلخ. بالنسبة لجميع الكيانات ، فإن القيام بذلك طويل وصعب. في كثير من الحالات ، يكون من الأسهل العمل باستخدام المعرّفات الرقمية العادية.

يمكن أن يتم التحقق بطريقة بسيطة:

  @RequestMapping(value = {"/entityName/{entityId}/get"}, method = RequestMethod.GET) @ResponseBody public Entity get(@PathVariable(value = "entityId") Integer entityId) { if(!@dao.validate(entityId)) return some_error; //    ID } 

هناك زائد واحد فقط في هذا الحل. بسيط وسريع.
كل شيء سيء. تكرار الكود ، التحقق من الصحة غير متوافق مع التحقق من صحة الكائن ؛ هناك حاجة إلى معالجة منفصلة في كل طريقة.

أريد القيام بذلك:

  @RequestMapping(value = {"/entityName/{entityId}/get"}, method = RequestMethod.GET) @ResponseBody public Entity get(@Validated @PathVariable(value = "entityId") Integer entityId) { //    ID } 

لا يعمل هذا الخيار البسيط والمنطقي. المدقق ببساطة لا يتم استدعاؤه. التحقق من PathVariable بواسطة Spring غير معتمد.

لكي يعمل هذا الخيار ، تحتاج إلى تحويل PathVariable إلى ModelAttribute:

 @ModelAttribute private Integer integerAsModelAttribute(@PathVariable("entityId") Integer id) { return id; } 

والحصول على خطأ عند الوصول إلى وحدة التحكم. لا تحتوي أغلفة الأنواع العامة على مُنشئ افتراضي بدون معلمات ولا يوجد مُحدد. يحدث هذا باستخدام اختياري. لديه كل من المنشئ الافتراضي وجهاز قبول يقبل ints العادي.

حوّل العدد الصحيح إلى اختياري:

 @ModelAttribute private Integer integerAsModelAttribute(@PathVariable("entityId") Optional<Integer> id) { return id.orElse(null); } 

وبناءً على ذلك ، فإن طريقة التحكم نفسها وإعلان المدقق:

 @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) { //    ID.   . } 

فئة المصدق طبيعية تمامًا:

 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"); } } } 

يمكن أخذ مثال عملي كامل هنا .

Source: https://habr.com/ru/post/ar425001/


All Articles