我在我的项目中使用 SpringBoot、Java 和 Gradle。 我的 API 连接到通过 spring 属性配置的数据库,但也依赖于外部 API Rest 来检索某些数据。
我的问题是有没有办法使用 spring 属性配置外部 API 主机和 key ? 我应该使用哪些属性? 有没有办法创建自定义属性?
## application.yml
---
spring:
profiles: dev
datasource:
platform: postgres
url:
jdbc:postgresql://${DATABASE_HOST}:${DATABASE_PORT}/${DATABASE_NAME}
username: ${DATABASE_USER}
password: ${DATABASE_PASSWORD}
driverClassName: org.postgresql.Driver
initialize: true
liquibase:
change-log: classpath:db/changelog-master.xml
最佳答案
您可以安全地采用以下方法,在yml
文件中配置所有 secret 以及外部API端点。如果您想进一步隐藏 secret ,请使用Spring Vault
,它使用了用于存储和撤销 secret 。
https://projects.spring.io/spring-vault/
security:
basic:
enabled: ${env.security.basic.enabled:false}
management:
security:
enabled: ${env.management.security.enabled:false}
apiUsername: apiUser
apiPassword: apiPassword
apiUrl: http://external-rest-api/RESTAdapter
dbUsername: dbUsername
dbPassword: dbPassword
dbServerUrl: jdbc:jtds:sqlserver://localhost:1433;
dbDriverClass: net.sourceforge.jtds.jdbc.Driver
dbServerDialect: org.hibernate.dialect.SQLServerDialect
dbName: databaseName=dbName;
---
spring:
profiles: Prod
dbDriverClass: net.sourceforge.jtds.jdbc.Driver
dbServerDialect: org.hibernate.dialect.SQLServerDialect
dbName: databaseName=prodDBName;
编写一个服务启动器,通过从 yml 文件获取属性来启动服务。
@Configuration
@EnableJpaRepositories("com.dao")
public class ServiceConfig {
/**
* The meta data bean consisting of properties read from the yaml
* configuration file.
*/
@Value("${apiUsername}")
String apiUsername;
@Value("${apiPassword}")
String apiPassword;
@Value("${apiUrl}")
String apiUrl;
@Value("${dbUsername}")
String dbUsername;
@Value("${dbPassword}")
String dbPassword;
@Value("${dbServerUrl}")
String dbServerUrl;
@Value("${dbDriverClass}")
String dbDriverClass;
@Value("${dbServerDialect}")
String dbServerDialect;
@Value("${dbName}")
String dbName;
/**
* Creates and returns a bean of RestClientSapUtil.
*
* @return RestClientApiUtil bean
*/
@Bean(name = "restClientApiUtil")
public RestClientApiUtil getRestClientApiUtil() {
return new RestClientApiUtil(apiUsername, apiPassword, apiUrl);
}
@Bean(name = "datasource")
public DriverManagerDataSource getDriverManagerDataSource() {
DriverManagerDataSource driverManagerDataSource =
new DriverManagerDataSource();
driverManagerDataSource.setUsername(dbUsername);
driverManagerDataSource.setPassword(dbPassword);
driverManagerDataSource.setUrl(dbServerUrl + dbName);
driverManagerDataSource.setDriverClassName(dbDriverClass);
return driverManagerDataSource;
}
@Bean(name = "entityManagerFactory")
public LocalContainerEntityManagerFactoryBean getLocalContainerEntityManagerFactoryBean() {
LocalContainerEntityManagerFactoryBean localContainerEntityManagerFactoryBean =
new LocalContainerEntityManagerFactoryBean();
HibernateJpaVendorAdapter jpaVendorAdapter =
new HibernateJpaVendorAdapter();
jpaVendorAdapter.setShowSql(true);
jpaVendorAdapter.setGenerateDdl(true);
jpaVendorAdapter.setDatabasePlatform(dbServerDialect);
localContainerEntityManagerFactoryBean
.setJpaVendorAdapter(jpaVendorAdapter);
localContainerEntityManagerFactoryBean
.setDataSource(getDriverManagerDataSource());
localContainerEntityManagerFactoryBean
.setPackagesToScan("com.model");
return localContainerEntityManagerFactoryBean;
}
@Bean(name = "transactionManager")
public JpaTransactionManager getJpaTransactionManager(
EntityManagerFactory entityManagerFactory) {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(entityManagerFactory);
return transactionManager;
}
}
最后,您可以构建一个与外部 API 接口(interface)对话的实用程序类,您可以想到下面类似的东西。
/**
* Provides methods for making requests to the API interface.
*
*
*/
public class RestClientApiUtil {
public RestClientApiUtil() {
}
private String apiUsername;
/**
* The password for accessing the external API interface.
*/
private String apiPassword;
/**
* The base URL for accessing the external API interface.
*/
private String apiUrl;
public RestClientApiUtil(String apiUsername,
String apiPassword, String apiUrl) {
this.apiUsername = apiUsername;
this.apiPassword = apiPassword;
this.apiUrl = apiUrl;
}
/**
* Makes a call to the external API interface and returns the response received.
* @param requestData the request data to attach in the request body
* @param endpoint the specific endpoint to make a request to
* @param clazz the class in which the response is expected
* @return Object
* @throws Exception
*/
public <T> T callService(Object requestData, String endpoint, Class<T> clazz)
throws TechnicalException {
RestTemplate restTemplate = null;
ResponseEntity<?> responseEntity = null;
String webServiceUrl = "";
HttpEntity<Object> requestBody = null;
try {
webServiceUrl = formServiceUrl(this.apiUrl, endpoint);
requestBody = createRequestBody(requestData);
restTemplate = new RestTemplate();
responseEntity = restTemplate.exchange(webServiceUrl, HttpMethod.POST, requestBody, clazz);
return clazz.cast(responseEntity.getBody());
} catch (Exception e) {
throw new Exception(e);
}
}
}
我希望这个答案有一定道理,如果您还有任何其他问题,请告诉我。 干杯!
关于java - 通过 Spring Boot 配置文件配置 API 主机,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53948027/