问题
I am trying with @ConfigurationProperties and I find two things:
- for tests to work, I have to put configuration properties files (yml) in
testpackage; setters and an empty constructor are required. - If I annotated the class with
@Validated, injection just fails with allnullvalues.
If you say the first one is understandable, and the second one? Why?
The purpose is to validate configuration properties injection, so that crucial properties values should not be absent when the application launches.
I have this yaml to map:
accertify:
fr:
merchant1:
host: "sandbox.accertify.dev"
protocol: "https"
user: "fraud"
password: "temporal"
merchant: "merchant1FR"
merchant2:
host: "sandbox.accertify.dev"
protocol: "https"
user: "fraud"
password: "temporal"
merchant: "merchant2FR"
es:
merchant1:
host: "sandbox.accertify.dev"
protocol: "https"
user: "fraud"
password: "temporal"
merchant: "merchant1ES"
merchant2:
host: "sandbox.accertify.dev"
protocol: "https"
user: "fraud"
password: "temporal"
merchant: "merchant2ES"
I have this class to mapping nested configurations:
import com.westerngun.fraud.jfps.dto.provider.accertify.country.ConfigurationEs;
import com.westerngun.fraud.jfps.dto.provider.accertify.country.ConfigurationFr;
import com.westerngun.fraud.jfps.service.client.ConnectionDetailsInterface;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.validation.annotation.Validated;
import javax.validation.Valid;
/**
* Class to read Accertify provider connection credentials.
*/
@Getter
@Setter
@Configuration
@ConfigurationProperties(prefix = "accertify")
@Validated // <--- this seems the problem
@NoArgsConstructor
@AllArgsConstructor
public class AccertifyConnectionDetail extends ConnectionDetails {
@Valid
private ConfigurationFr fr;
@Valid
private ConfigurationEs es;
}
And, its interface:
public abstract class ConnectionDetails {
public abstract ConfigurationFr getFr();
public abstract ConfigurationEs getEs();
}
And, ConfigurationEs and ConfigurationFr are both subclass of:
@Component
public class CountryConfigDetail {
@Getter
@Setter
@Valid
private Merchant1 merchant1;
@Getter
@Setter
@Valid
private Merchant2 merchant2;
}
Merchant1 and Merchant2 are subclass of :
@Data
@Component
public class MerchantConfigDetail {
@NotEmpty
@NotNull
private String user;
@NotEmpty
@NotNull
private String password;
...
@NotEmpty
@NotNull
private Map<String, String> headers;
}
When I try to inject into some @Autowired tests without @Validated in the first class, it works(fr and es have values in the yml file)
When I add @Validated, fr and es are null.
Test:
@RunWith(SpringRunner.class)
@SpringBootTest
public class AccertifyConfigurationTest {
@Autowired
private AccertifyConnectionDetail accertifyConnectionDetail; // <--- this field should be injected
@Test
public void givenAAccertifyClientService_WhenClientIsBuild_ShouldHaveTheProviderConfigurationCorrect() {
AccertifyConfiguration accertifyConfiguration = new AccertifyConfiguration(accertifyConnectionDetail);
accertifyConfiguration.buildConfiguration("FR", "Merchant1");
Assert.assertEquals("fraud", accertifyConfiguration.getUser());
Assert.assertEquals("temporal", accertifyConfiguration.getPassword());
Assert.assertTrue(accertifyConfiguration.getHost().startsWith("sandbox.accertify."));
Assert.assertEquals("merchant1FR", accertifyConfiguration.getMerchantCode());
}
...
来源:https://stackoverflow.com/questions/55471653/spring-validated-annotation-prevents-configurationproproperties-value-injectio