一、方案描述
我这里采用RestTemplate的方式调用https请求,请求第三方接口获取数据,证书由第三方私自签发的证书,我们构建的是一个springboot的API项目。
1.pom文件引入jar
java
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Apache HttpClient - Used to request HTTP resources over the network -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
2.构建一个RestTemplateConfig
构建RestTemplateConfig为了初始化RestTemplate让它具备验证证书功能。
java
/**
* @Author: LongGE
* @Date: 2023-08-28
* @Description:
*/
@Configuration
public class RestTemplateConfig {
/**
* 1.创建一个KeyStore,并将需要信任的证书加载到KeyStore中。示例代码如下:
* @return
* @throws CertificateException
* @throws IOException
* @throws KeyStoreException
* @throws NoSuchAlgorithmException
*/
@Bean
public KeyStore createKeyStore() throws CertificateException, IOException, KeyStoreException, NoSuchAlgorithmException {
CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
FileInputStream inputStream =
new FileInputStream("D:\\WorkSpace\\local\\online-project\\RequestSpringBoot\\src\\main\\resources\\my-certificate.crt");
X509Certificate certificate = (X509Certificate) certFactory.generateCertificate(inputStream);
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(null, null);
keyStore.setCertificateEntry("my-cert", certificate);
return keyStore;
}
/**
* 2.创建一个TrustManagerFactory,使用上述创建的KeyStore来初始化它
* @return
* @throws CertificateException
* @throws NoSuchAlgorithmException
* @throws KeyStoreException
* @throws IOException
*/
@Bean
public TrustManagerFactory createTrustManagerFactory() throws CertificateException, NoSuchAlgorithmException, KeyStoreException, IOException {
KeyStore keyStore = createKeyStore();
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(keyStore);
return trustManagerFactory;
}
/**
* 3.创建一个SSLContext,并使用上述创建的TrustManagerFactory来初始化它。
* @return
* @throws NoSuchAlgorithmException
* @throws CertificateException
* @throws KeyStoreException
* @throws IOException
* @throws KeyManagementException
*/
@Bean
public SSLContext createSSLContext() throws NoSuchAlgorithmException, CertificateException, KeyStoreException, IOException, KeyManagementException {
TrustManagerFactory trustManagerFactory = createTrustManagerFactory();
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, trustManagerFactory.getTrustManagers(), new SecureRandom());
return sslContext;
}
/**
* 4.创建一个HttpsURLConnectionFactory,使用上述创建的SSLContext来设置HttpsURLConnection的SSLSocketFactory。
* @return
* @throws CertificateException
* @throws NoSuchAlgorithmException
* @throws KeyStoreException
* @throws KeyManagementException
* @throws IOException
*/
@Bean
public RestTemplate createRestTemplate() throws CertificateException, NoSuchAlgorithmException, KeyStoreException, KeyManagementException, IOException {
SSLContext sslContext = createSSLContext();
HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
httpClientBuilder.setSSLContext(sslContext);
// 创建HttpComponentsClientHttpRequestFactory
HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
requestFactory.setHttpClient(httpClientBuilder.build());
// 创建RestTemplate,并设置自定义的SSLSocketFactory
RestTemplate restTemplate = new RestTemplate(requestFactory);
return restTemplate;
}
}
二.使用方案
这样构建好的RestTemplate,我们在Controller或者Service就可以通过@Autowried注解引入。
java
@RestController
@RequestMapping("/TestController")
public class TestController {
@Autowired
private RestTemplate restTemplate;
private String url = "https://www.houpu.com";
private String relativePath2 = "/ResponseController/getTestMapping";
@GetMapping("/test02")
public String test02() {
//发起请求
String fullUrl2 = UriComponentsBuilder.fromHttpUrl(url).path(relativePath2).toUriString();
String response2 = restTemplate.getForObject(fullUrl2, String.class);
System.out.println(response2);
return response2;
}
}