OK I'm adding this response since I had a really painful implementation for consuming one API from IBM DataStage v11.7 with Java and SpringBoot (RestTemplate). I'm not sure if someone else might run into similar problems with such product or any other... But these days I had combination of issues with PKIX, API's exposed with self signed certificates and finally a deflate header. Sorry to do a big post with the three responses, but you'll be able to find similar responses for the first two issues (PKIX or endpoints with self signed certificates and RestTemplate objects). I'm adding this here since Inflater does not have many approaches yet.
Some other answers say that using a custom httpclient with resttemplate may help, or may already include a automatic "decompression" but somehow this case was not the same.
Uncompressing or inflating the response was a bit tricky and adding one extra byte at the end was the misterious "cherry on top of the cake". I managed to get the response after struggling a bit, but it was printing strange/special characters. I thought it was some encoding issue but it was actually some issue with Inflater. I had to debug to identify that the response size (lenght) was actually the same as I received in Postman. So I said, ok, lenghts are similar, so what may be happening. So, thanks to all other developers who contributed to our solution.
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.X509Certificate;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import javax.net.ssl.SSLContext;
import org.apache.http.client.HttpClient;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.TrustStrategy;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.zip.DataFormatException;
import java.util.zip.Inflater;
import java.util.zip.InflaterInputStream;
private static Map<String, String> headersMap = new HashMap<String, String>() {
{
put("Authorization", "Basic XYZ");
put("Accept", "*/*");
put("Accept-Encoding", "deflate");
put("Connection", "keep-alive");
}
};
private static final String baseUrlDesigner = "https://{HOST}/ibm/iis/api/dscdesignerapi";
private static final String designerGetAllJobs = "?api=getJobList&hostName={HOST}&projectName={PROJECT}&compress=nowrap9";
public static RestTemplate getRestTemplateNoSSLValidation( ) {
TrustStrategy acceptingTrustStrategy = (X509Certificate[] chain, String authType) -> true;
SSLContext sslContext = null;
try {
sslContext = org.apache.http.ssl.SSLContexts.custom()
.loadTrustMaterial(null, acceptingTrustStrategy)
.build();
} catch (KeyManagementException e2) {
e2.printStackTrace();
} catch (NoSuchAlgorithmException e2) {
e2.printStackTrace();
} catch (KeyStoreException e2) {
e2.printStackTrace();
}
SSLConnectionSocketFactory csf = new SSLConnectionSocketFactory(sslContext);
HttpClient httpClient = HttpClients.custom()
.setSSLSocketFactory(csf)
.disableContentCompression()
.build();
HttpComponentsClientHttpRequestFactory requestFactory =
new HttpComponentsClientHttpRequestFactory();
requestFactory.setHttpClient(httpClient);
RestTemplate restTemplate = new RestTemplate(requestFactory);
return restTemplate;
}
public static <T> ResponseEntity<T> sendRequest(String url, HttpMethod method, Map<String,String> headerList, Class<T> responseType) {
RestTemplate restTemplate = getRestTemplateNoSSLValidation();
HttpHeaders headers = new HttpHeaders();
for (Entry<String,String> e:headerList.entrySet())
headers.add(e.getKey(),e.getValue());
HttpEntity<String> request = new HttpEntity<String>(null, headers);
ResponseEntity<T> result = (ResponseEntity<T>) restTemplate.exchange(url, method, request, responseType);
return result;
}
public static String decompress(byte[] bytes) {
Inflater inf = new Inflater(true);
InputStream in = new InflaterInputStream(new ByteArrayInputStream(bytes), inf);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
byte[] buffer = new byte[8192];
int len;
while ((len = in.read(buffer)) > 0)
baos.write(buffer, 0, len);
baos.write(new byte[1], 0, 1); // FIX. Had to force one extra byte, otherwise the body string was not read properly :shrug:
return new String(baos.toByteArray(), "UTF-8");
} catch (IOException e) {
throw new AssertionError(e);
}
}
public static void main(String[] args) throws IOException {
ResponseEntity<byte[]> responseBytes =
sendRequest(baseUrlDesigner + designerGetAllJobs,
HttpMethod.GET, headersMap, byte[].class);
String respString = decompress(responseBytes.getBody());
System.out.println("Response lenght: " + respString.length());
System.out.println("Response body: " + respString);
}