admin管理员组文章数量:1122846
Situation
I am trying to create a autoconfiguration in which some properties must pass validation only in specific cases. I have a service MyService
which requires credentials properties.username
and properties.password
, and a OncePerRequestFilter
, which intercepts controller calls and calls MyService
to perform some action, which requires the application's name properties.app-name
.
Here is the global layout:
- when I provide no property and no
MyService
bean exists, the autoconfiguration does nothing, - when no
MyService
bean exists, but I provide a username and password in the properties, I will create a newMyService
bean, and I wish to validate the username and password, - when there exists a
MyService
bean, I will create aOncePerRequestFilter
, and I wish to validate the application name.
In order to do so, I wanted to use validation groups. I already implemented some validation in configuration properties before, and therefore know that Spring checks them when instantiating the object, but I have never tried with groups.
First try
Code
Autoconfiguration
@AutoConfiguration
@EnableConfigurationProperties(MyProperties.class)
public class MyAutoConfiguration {
@Bean
@ConditionalOnMissingBean
@ConditionalOnProperty(prefix = "properties", name = { "username", "password" })
@Validated(CredentialsRequired.class)
public MyService myDefaultService(@Valid MyProperties properties) {
return new MyService(properties);
}
@Bean
@ConditionalOnBean(MyService.class)
@Validated(AppNameRequired.class)
OncePerRequestFilter myFilter(@Valid MyProperties properties, MyService myService) {
return new MyFilter(properties, myService);
}
}
Configuration properties
@Data
@ConfigurationProperties("properties")
public class MyProperties {
@NotBlank(groups = AppNameRequired.class)
private String appName;
@NotBlank(groups = CredentialsRequired.class)
private String username;
@NotBlank(groups = CredentialsRequired.class)
private String password;
}
Result
When I provide no property, nothing fails, which is desired. However, if I just use the following properties:
properties.username=
properties.password=
then both the service and the filter are created without any automatic validation issue, as this short modification shows:
@Bean
@ConditionalOnBean(MyService.class)
@Validated(AppNameRequired.class)
OncePerRequestFilter myFilter(@Valid MyProperties properties, MyService myService, Validator validator) {
if(!validator.validate(properties, AppNameRequired.class).isEmpty()) {
throw new IllegalArgumentException(); // Should not be reached if validation works, but is thrown on instantiation
}
return new MyFilter(properties, myService);
}
Trying with @Validated
on properties class
I have also tried applying @Validated
on MyProperties
, but it did not change much. Furthermore, I noticed this in a more global case:
- when there is
@Validated
on the class, and constraints without groups are all valid, no error is thrown, even if some constraints with groups are invalid - when there is
@Validated
on the class, but at least one constraint without group is violated, Spring fails the instantiation - when there is
@Validated(AppNameRequired.class)
on the class, and constraints without groups are all valid, no error is thrown, even if the constraints with groupAppNameRequired
are invalid
My conclusion, and my question
After all of this, my conclusion is that Spring does not support validation groups for bean validation. Hence, I wonder: is there a way to perform this conditional validation by relying on the Jakarta and Spring Boot annotations only, or am I forced to manually call a validator to perform this?
Situation
I am trying to create a autoconfiguration in which some properties must pass validation only in specific cases. I have a service MyService
which requires credentials properties.username
and properties.password
, and a OncePerRequestFilter
, which intercepts controller calls and calls MyService
to perform some action, which requires the application's name properties.app-name
.
Here is the global layout:
- when I provide no property and no
MyService
bean exists, the autoconfiguration does nothing, - when no
MyService
bean exists, but I provide a username and password in the properties, I will create a newMyService
bean, and I wish to validate the username and password, - when there exists a
MyService
bean, I will create aOncePerRequestFilter
, and I wish to validate the application name.
In order to do so, I wanted to use validation groups. I already implemented some validation in configuration properties before, and therefore know that Spring checks them when instantiating the object, but I have never tried with groups.
First try
Code
Autoconfiguration
@AutoConfiguration
@EnableConfigurationProperties(MyProperties.class)
public class MyAutoConfiguration {
@Bean
@ConditionalOnMissingBean
@ConditionalOnProperty(prefix = "properties", name = { "username", "password" })
@Validated(CredentialsRequired.class)
public MyService myDefaultService(@Valid MyProperties properties) {
return new MyService(properties);
}
@Bean
@ConditionalOnBean(MyService.class)
@Validated(AppNameRequired.class)
OncePerRequestFilter myFilter(@Valid MyProperties properties, MyService myService) {
return new MyFilter(properties, myService);
}
}
Configuration properties
@Data
@ConfigurationProperties("properties")
public class MyProperties {
@NotBlank(groups = AppNameRequired.class)
private String appName;
@NotBlank(groups = CredentialsRequired.class)
private String username;
@NotBlank(groups = CredentialsRequired.class)
private String password;
}
Result
When I provide no property, nothing fails, which is desired. However, if I just use the following properties:
properties.username=
properties.password=
then both the service and the filter are created without any automatic validation issue, as this short modification shows:
@Bean
@ConditionalOnBean(MyService.class)
@Validated(AppNameRequired.class)
OncePerRequestFilter myFilter(@Valid MyProperties properties, MyService myService, Validator validator) {
if(!validator.validate(properties, AppNameRequired.class).isEmpty()) {
throw new IllegalArgumentException(); // Should not be reached if validation works, but is thrown on instantiation
}
return new MyFilter(properties, myService);
}
Trying with @Validated
on properties class
I have also tried applying @Validated
on MyProperties
, but it did not change much. Furthermore, I noticed this in a more global case:
- when there is
@Validated
on the class, and constraints without groups are all valid, no error is thrown, even if some constraints with groups are invalid - when there is
@Validated
on the class, but at least one constraint without group is violated, Spring fails the instantiation - when there is
@Validated(AppNameRequired.class)
on the class, and constraints without groups are all valid, no error is thrown, even if the constraints with groupAppNameRequired
are invalid
My conclusion, and my question
After all of this, my conclusion is that Spring does not support validation groups for bean validation. Hence, I wonder: is there a way to perform this conditional validation by relying on the Jakarta and Spring Boot annotations only, or am I forced to manually call a validator to perform this?
Share Improve this question asked Nov 22, 2024 at 11:54 Aisteru FirëAisteru Firë 2183 silver badges10 bronze badges1 Answer
Reset to default 0It seems that you are trying to use @Validated
for spring beans, using Spring MVC approach.
First idea
From this article, looks like you need to declare an additional bean.
@Bean
public static MethodValidationPostProcessor validationPostProcessor() {
return new MethodValidationPostProcessor();
}
Second idea
Instead of relying on @ConditionalOnProperty
during creation of MyService
you can create a @Conditional
bean which will validate values of the properties.
本文标签: javaSpring group validation does not work on autowired beansStack Overflow
版权声明:本文标题:java - Spring group validation does not work on autowired beans - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1736303921a1932050.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论