在Spring控制器中验证通用参数

图片
我们大家经常在通过数字标识符工作的控制器中编写简单的方法。

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

传入ID必须经过验证。 例如,并非所有用户都可以访问所有ID。

可以理解,使用UUID更安全,更可靠。 但是必须创建,存储,索引等。 对于所有实体,这样做都是漫长而困难的。 在许多情况下,使用常规数字ID会更容易。

验证可以通过一种简单的方式完成:

  @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 } 

此简单而逻辑的选项不起作用。 验证器根本就没有被调用。 不支持Spring验证PathVariable。

为了使此选项起作用,您需要将PathVariable转换为ModelAttribute:

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

并且在访问控制器时出现错误。 泛型类型的包装器没有没有参数的默认构造函数,并且没有设置器。 使用Optional可以解决此问题。 他有一个默认构造函数和一个接受普通整数的setter。

将Integer转换为Optional:

 @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/zh-CN425001/


All Articles