Spring Web MVC - 验证单个请求参数

2022-08-31 20:13:27

我在Spring Web MVC 3.0中运行Web应用程序,并且我有许多控制器方法,其签名大致如下:

@RequestMapping(value = "/{level1}/{level2}/foo", method = RequestMethod.POST)
public ModelAndView createFoo(@PathVariable long level1,
        @PathVariable long level2,
        @RequestParam("foo_name") String fooname,
        @RequestParam(value = "description", required = false) String description);

我想添加一些验证 - 例如,应限制为一定长度或应仅包含某些字符。如果此验证失败,我想向用户返回一条消息,而不仅仅是抛出一些未经检查的异常(如果我让数据向下渗透到DAO层,无论如何都会发生这种情况)。我知道JSR303,但还没有使用它,也不太了解如何在春季环境中应用它。descriptionfooname

据我所知,另一种选择是将 绑定到整个域对象并在那里添加验证约束,但目前我的代码设置为接受各个参数,如上所示。@RequestBody

使用此方法对输入参数应用验证的最直接方法是什么?


答案 1

现在这似乎是可能的(在Spring 4.1.2中尝试过),请参阅 https://raymondhlee.wordpress.com/2015/08/29/validating-spring-mvc-request-mapping-method-parameters/

摘自上页:

  1. 将方法验证后处理器添加到 Spring @Configuration 类:

    @Bean
    public MethodValidationPostProcessor methodValidationPostProcessor() {
        return new MethodValidationPostProcessor();
    }
    
  2. 将@Validated添加到控制器类

  3. 在@RequestParam前使用@Size

    @RequestMapping("/hi")
    public String sayHi(@Size(max = 10, message = "name should at most 10 characters long") @RequestParam("name") String name) {
        return "Hi " + name;
    

    }

  4. 处理约束暴力@ExceptionHandler方法中的异常


答案 2

没有内置的东西可以做到这一点,无论如何还没有。对于当前的发行版,如果要进行自动魔法验证,您仍然需要使用 WebDataBinder 将参数绑定到对象上。如果您使用的是SpringMVC,即使它不是您完成此任务的首选,也值得学习。

它看起来像这样:

public ModelAndView createFoo(@PathVariable long level1,
        @PathVariable long level2,
        @Valid @ModelAttribute() FooWrapper fooWrapper,
        BindingResult errors) {
  if (errors.hasErrors() {
     //handle errors, can just return if using Spring form:error tags.
  }
}

public static class FooWrapper {
  @NotNull
  @Size(max=32)
  private String fooName;
  private String description;
//getset
}

如果您的类路径上有休眠验证器 4 或更高版本,并且使用默认的调度程序设置,它应该“正常工作”。

编辑,因为评论变得有点大:

方法签名中的任何对象,如果不是 Spring 知道如何注入的“预期”对象之一,例如 、 等,都将获得数据绑定。对于简单情况,只需将请求参数名称与 Bean 属性名称和调用 setter 进行匹配即可完成此操作。只有个人风格的东西,在这种情况下,它没有做任何事情。将JSR-303与@Valid上的方法参数线集成在通过.如果使用 ,则使用的对象编组器基于 spring 为请求正文确定的内容类型(通常仅来自 http 标头)。调度程序 servlet(实际上)没有办法为任何任意编组程序“翻转验证开关”。它只是将 Web 请求内容传递到消息转换器,并取回一个对象。不会生成任何 BindingResult 对象,因此无论如何都无法设置 Errors。HttpRequestModelMap@ModelAttributeWebDataBinder@RequestBodyAnnotationMethodHandlerAdapter

您仍然可以将验证器注入控制器并在您获得的对象上运行它,它只是没有与为你填充的请求参数的神奇集成。@ValidBindingResult


推荐