Вы можете написать пользовательский ConstraintValidator
.
@Configuration
@ConfigurationProperties(prefix = "sdk")
@Validated
@NotEmptyWhenEnabled // <----- custom validation -----
@Data
class SdkProperties {
private boolean enabled;
private String apiKey;
}
@Constraint(validatedBy = {NotEmptyWhenEnabledValidator.class})
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@interface NotEmptyWhenEnabled {
String message() default "SDK apiKey needed when SDK is enabled";
Class[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
class NotEmptyWhenEnabledValidator implements ConstraintValidator<NotEmptyWhenEnabled,SdkProperties> {
@Override
public boolean isValid(SdkProperties sdkProperties,
ConstraintValidatorContext constraintValidatorContext) {
boolean enabled = sdkProperties.isEnabled();
boolean empty = null == sdkProperties.getApiKey() || sdkProperties.getApiKey().isEmpty();
return !enabled || (enabled && !empty);
}
}
Затем вы получите приятное сообщение при запуске, когда SDK включен , но API-ключ не *Предоставляется 1008 *.
***************************
APPLICATION FAILED TO START
***************************
Description:
Binding to target org.springframework.boot.context.properties.bind.BindException: Failed to bind properties under 'sdk' to so.demo.SdkProperties$$EnhancerBySpringCGLIB$$1ecd6003 failed:
Reason: SDK apiKey needed when SDK is enabled
Action:
Update your application's configuration
Process finished with exit code 0
РЕДАКТ.
Начиная с spring-boot-2.2.0.RELEASE
(16 октября 2019 г.), у вас есть другой вариант. Вы можете проверить свойства в конструкторе.
, используя: Immutable @ ConfigurationProperties binding
Свойства конфигурации теперь поддерживают привязку на основе конструктора, что позволяет @ConfigurationProperties
-аннотированный класс, чтобы быть неизменным. Связывание на основе конструктора можно включить, пометив класс @ConfigurationProperties
или один из его конструкторов @ConstructorBinding
. Аннотации, такие как @DefaultValue
и @DateTimeFormat
, могут использоваться для параметров конструктора, которые предоставляются привязкой свойства конфигурации.
ref: boot-features-external-config-constructor-binding
так в вашем случае ...
@ConfigurationProperties(prefix = "sdk")
class SdkProperties {
private boolean enabled;
private String apiKey;
@ConstructorBinding
public SdkProperties(boolean enabled, String apiKey) {
this.enabled = enabled;
this.apiKey = apiKey;
// direct validation in the constructor
boolean apiKeyNullOrEmpty = null == apiKey || apiKey.isEmpty();
Assert.isTrue(!enabled || !apiKeyNullOrEmpty, "When SDK is enabled, a SDK-api key is mandatory!");
}
public boolean isEnabled() { return enabled; }
public void setEnabled(boolean enabled) { this.enabled = enabled; }
public String getApiKey() {return apiKey; }
public void setApiKey(String apiKey) { this.apiKey = apiKey; }
}