java调用第三方接口跳过SSL认证

今天遇到一个接口调用的问题,我在调用这个接口的时候一直报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 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> 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

你可能感兴趣的:(ssl认证,springboot,java,https,接口)