今天遇到一个接口调用的问题,我在调用这个接口的时候一直报502的错误,后来发现这个接口是https的请求,必须要跳过ssl认证才能访问,下面做一下记录:
1.封装跳过ssl认证的方法
/**
* 忽略ssl认证方法
* @throws Exception
*/
public static void ignoreSsl() throws Exception {
HostnameVerifier hv = (urlHostName, session) -> {
System.out.println("Warning: URL Host: " + urlHostName
+ " vs. " + session.getPeerHost());
return true;
};
trustAllHttpsCertificates();
HttpsURLConnection.setDefaultHostnameVerifier(hv);
}
/**
* 信任所有,创建SSLContext对象,并使用我们指定的信任管理器初始化
* @throws Exception
*/
private static void trustAllHttpsCertificates() throws Exception {
TrustManager[] trustAllCerts = new TrustManager[1];
TrustManager tm = new MyX509TrustManager();
trustAllCerts[0] = tm;
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, null);
System.setProperty("https.protocols", "TLSv1.2,TLSv1.1,SSLv3");
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
}
/**
* 在JSSE中,实现证书信任管理器X509TrustManager接口,让它信任我们指定的证书
*/
static class MyX509TrustManager implements X509TrustManager {
/**
* 返回受信任的X509证书数组
* @return
*/
@Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
/**
* 该方法检查服务端的证书,若不信任该证书则抛出异常
* @param certs
* @param authType
* @throws CertificateException
*/
@Override
public void checkServerTrusted(X509Certificate[] certs, String authType)
throws CertificateException {
}
/**
* 该方法检查客户端的证书,若不信任该证书则抛出异常
* @param certs
* @param authType
* @throws CertificateException
*/
@Override
public void checkClientTrusted(X509Certificate[] certs, String authType)
throws CertificateException {
}
}
2.调用接口并把响应结果以json对象的方式返回
public JSONObject restTemplateTransferFile(String imgUrlStr){
final String url = "https://localhost:10111";
RestTemplate restTemplate = new RestTemplate();
// 设置请求头
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.valueOf(MediaType.MULTIPART_FORM_DATA_VALUE));
// 设置请求体,注意是LinkedMultiValueMap
MultiValueMap<String, Object> form = new LinkedMultiValueMap<>();
form.add("interface",5);
form.add("business","csig_cloud_video_str");
byte[] b=null;
try {
URL imgUrl = new URL(imgUrlStr);
HttpURLConnection conn = (HttpURLConnection) imgUrl.openConnection();
conn.setRequestMethod("GET");
conn.setConnectTimeout(10 * 1000);
// 通过输入流获取图片数据
InputStream inStream = conn.getInputStream();
// 得到图片的二进制数据
b = readInputStream(inStream);
} catch (Exception e) {
return new JSONObject();
}
// BASE64Encoder encoder = new BASE64Encoder();
// String str = encoder.encode(b);
form.add("myfile",b);
// 用HttpEntity封装整个请求报文
HttpEntity<MultiValueMap<String, Object>> files = new HttpEntity<>(form, headers);
try {
URL realUrl = new URL(url);
if ("https".equalsIgnoreCase(realUrl.getProtocol())) {
try {
RestOcrUtil.ignoreSsl();
} catch (Exception e) {
e.printStackTrace();
}
}
} catch (MalformedURLException e) {
e.printStackTrace();
}
restTemplate.getMessageConverters().set(1, new StringHttpMessageConverter(StandardCharsets.UTF_8));
String s = restTemplate.postForObject(url, files, String.class);
return JSONObject.parseObject(s);
}
3.其中有一个远程访问图片并转成二进制数据的需求
/**
* 把流转换成二进制数据
* @param inStream
* @return
* @throws Exception
*/
public static byte[] readInputStream(InputStream inStream) throws Exception {
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
byte[] buffer = new byte[10*1024];
int len = 0;
while ((len = inStream.read(buffer)) != -1) {
outStream.write(buffer, 0, len);
}
inStream.close();
return outStream.toByteArray();
}
更多详细内容见:https://blog.csdn.net/paradise003/article/details/72876153