Using Spring RestTemplate I try to send a large stream to a server. Than I receive getBody not supported error. If I do it with SimpleClientHttpRequestFactory it works normally, but I can't make my own sslcontext, that I need. What am I doing wrong and how can I fix it?
I use spring boot 2.6.4, if it's important.
Code samples:
RestTemplate creation:
public RestTemplate configureSSLRestTemplate(final String keystoreLocation,
final String keystorePassword,
final String keyPassword,
final int requestTimeout) throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException, UnrecoverableKeyException, KeyManagementException {
final HttpClient httpClient = httpClientConfiguration(keystoreLocation, keystorePassword, keyPassword);
final HttpComponentsClientHttpRequestFactory customRequestFactory = new HttpComponentsClientHttpRequestFactory(httpClient);
customRequestFactory.setBufferRequestBody(false);
customRequestFactory.setConnectTimeout(requestTimeout);
customRequestFactory.setReadTimeout(requestTimeout);
customRequestFactory.setConnectionRequestTimeout(requestTimeout);
return new RestTemplate(customRequestFactory);
}
private CloseableHttpClient httpClientConfiguration(final String keystoreLocation,
final String keystorePassword,
final String keyPassword) throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException, UnrecoverableKeyException, KeyManagementException {
final TrustManager[] trustCheckedCertificates = new TrustManager[]{new X509TrustManager() {
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
public void checkClientTrusted(final X509Certificate[] certs, String authType) {
}
public void checkServerTrusted(final X509Certificate[] certs, String authType) throws CertificateException {
if (!certificateValidatorService.validateCertificate(certs[0], false)) {
throw new CertificateException("Server certificate is wrong"); //TODO
}
}
}};
final SSLContext sslContext = configureSSLContext(keystoreLocation, keystorePassword, keyPassword, trustCheckedCertificates);
return HttpClients.custom().setSSLContext(sslContext)
.setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE).build();
}
public SSLContext configureSSLContext(final String keystoreLocation,
final String keystorePassword,
final String keyPassword,
final TrustManager[] trustCheckedCertificates) throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException, UnrecoverableKeyException, KeyManagementException {
final KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
try (InputStream in = new FileInputStream(keystoreLocation)) {
keystore.load(in, keystorePassword.toCharArray());
}
final KeyManagerFactory keyManagerFactory =
KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
keyManagerFactory.init(keystore, keyPassword.toCharArray());
final SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(keyManagerFactory.getKeyManagers(), trustCheckedCertificates, new SecureRandom());
return sslContext;
}
Message sending:
final RequestCallback requestCallback = new RequestCallback() {
@Override
public void doWithRequest(ClientHttpRequest clientHttpRequest) throws IOException {
IOUtils.copy(request.getInputStream(), clientHttpRequest.getBody());
}
};
ResponseEntity<String> responseEntity;
responseEntity = restTemplate.execute(clientApi, HttpMethod.POST,
requestCallback, restTemplate.responseEntityExtractor(String.class));
}