显然,我在Spring Boot中缺少有关基于JSR-303批注的验证的信息。我正在使用Spring Boot 2.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";
}
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
在浏览器中会导致以下日志消息:
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
实例是Person
中的一个字段,但是尽管已用@Valid
进行了注释,但根本没有得到验证。
好吧,如果我为Address
添加了一个吸气剂(否则就不需要了),并将其注释为@Valid
,它终于可以工作了。
但是它不应该用于带注释的字段吗?我在这里想念什么?这与代理“原始” bean有关吗?