代码之家  ›  专栏  ›  技术社区  ›  badbishop

Spring Boot JSR-303验证程序和请求作用域bean

  •  0
  • badbishop  · 技术社区  · 6 年前

    显然,我在Spring Boot中遗漏了一些关于JSR-303基于注释的验证的内容。我使用的是SpringBoot2.0.4.RELEASE。

    为了解决这个问题,我创建了一个带有两个嵌套的请求范围bean和一个控制器的小“项目”。即使bean的一些属性被设置为有效值(并被验证),我仍然会收到一个验证错误,说它们都是空的。

    这是我的课。 MyController.java版本:

    @Controller
    public class MyController {
    
      @Autowired
      private Validator standardValidator;
    
      @Autowired
      private Person person;
    
      @GetMapping("/")
      public String getItBound(ServletRequest request) {
        ServletRequestParameterPropertyValues paramMap = new ServletRequestParameterPropertyValues(
            request);
        System.err.println(standardValidator.getClass().getName());
    
        DataBinder binder = new DataBinder(person);
        binder.bind(paramMap);
    
        System.err.println("person.getName() is " + person.getName());
    
        binder.addValidators(standardValidator);
        binder.validate();
    
        Errors result = binder.getBindingResult();
    
        result.getAllErrors().stream().forEach(System.err::println);
    
        return "myTemplate";
      }
    

    个人.java:

    @Component
    @RequestScope(proxyMode = ScopedProxyMode.TARGET_CLASS)
    public class Person {
    
      @NotNull
      private String name;
    
      @Autowired
      @NotNull
      @Valid
      private Address address;
    
      public String getName() {
        return name;
      }
    
      public void setName(String name) {
        this.name = name;
      }
    
      public String getStreet() {
        return address.getStreet();
      }
    
      public void setStreet(String street) {
        address.setStreet(street);
      }
    
      public String getCity() {
        return address.getCity();
      }
    
      public void setCity(String city) {
        address.setCity(city);
      }    
    }
    

    地址.java:

    @Component
    @RequestScope
    public class Address {
    
      @NotNull
      private String street;
    
      @NotNull
      private String city;
    
     // getters and setters omited
    

    打电话

    http://localhost:8080/?name=MaxMusterman
    

    在浏览器中会生成以下日志消息:

    org.springframework.validation.beanvalidation.LocalValidatorFactoryBean
    2019-02-01 12:40:02.453  INFO 11404 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : FrameworkServlet 'dispatcherServlet': initialization completed in 0 ms
    person.getName() is MaxMusterman
    Field error in object 'target' on field 'name': rejected value [null]; codes [NotNull.target.name,NotNull.name,NotNull.java.lang.String,NotNull]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [target.name,name]; arguments []; default message [name]]; default message [darf nicht null sein]
    Field error in object 'target' on field 'address': rejected value [null]; codes [NotNull.target.address,NotNull.address,NotNull]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [target.address,address]; arguments []; default message [address]]; default message [darf nicht null sein]
    

    因此,尽管设置了name属性,验证器仍然像null一样抱怨。

    现在,如果我将验证注释放在getter方法而不是字段上,那么外部类实例( Person )已正确验证。然而, Address 实例,它是 ,尽管被注释为 @Valid .

    好吧,如果我加一个getter 地址 (否则我不需要),并将其注释为 @有效 ,终于成功了。

    但它不应该和带注释的字段一起工作吗?我错过了什么?这和代理“原始”bean有什么关系吗?

    0 回复  |  直到 6 年前