Валидатор Spring Boot JSR-303 и бин в области запроса - PullRequest
0 голосов
/ 01 февраля 2019

Похоже, я что-то упускаю из-за проверки на основе аннотаций JSR-303 в Spring Boot.Я использую Spring Boot 2.0.4.RELEASE.

Просто, чтобы изолировать проблему, я создал небольшой «проект» с двумя вложенными 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";
  }

Person.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);
  }    
}

Address.java:

@Component
@RequestScope
public class Address {

  @NotNull
  private String street;

  @NotNull
  private String city;

 // getters and setters omited

Вызов

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

inбраузер выдает следующие сообщения журнала:

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 установлено, валидатор все равно жалуется, как если бы он был нулевым.

Теперь, если я размещаю аннотации проверки в методах получения вместо полей, экземпляр внешнего класса (Person) проверяется правильно.Однако экземпляр Address, который является полем в Person, вообще не проверяется, несмотря на то, что он помечен @Valid.

ОК, если я добавлю геттер для Address (который яв противном случае не нужно), и аннотируйте это как @Valid, это, наконец, работает.

Но разве он не должен работать с аннотированными полями?Что мне здесь не хватает?Это как-то связано с проксированием «оригинального» бина?

...