好的,我正在添加此响应,因为我有一个非常痛苦的实现,即使用 Java 和 SpringBoot (RestTemplate) 使用 IBM DataStage v11.7 中的一个 API。我不确定其他人是否会在使用此类产品或任何其他产品时遇到类似问题……但是这些天我遇到了 PKIX 问题、API 暴露于自签名证书以及最后一个 deflate 标头的问题。很抱歉用这三个回复写了一篇大文章,但您将能够找到前两个问题(PKIX 或具有自签名证书和 RestTemplate 对象的端点)的类似回复。我在这里添加这个是因为 Inflater 还没有很多方法。
其他一些答案说,使用带有 resttemplate 的自定义 httpclient 可能会有所帮助,或者可能已经包含自动“解压缩”,但不知何故,这种情况并不相同。
解压缩或膨胀响应有点棘手,最后添加一个额外的字节是神秘的“蛋糕上的樱桃”。经过一番挣扎后,我设法得到了响应,但它正在打印奇怪/特殊的字符。我认为这是一些编码问题,但实际上是 Inflater 的一些问题。我必须调试以确定响应大小(长度)实际上与我在 Postman 中收到的相同。所以我说,好吧,长度是相似的,所以可能会发生什么。因此,感谢为我们的解决方案做出贡献的所有其他开发人员。
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);
}