访问以https://开头的webservice接口

访问以https://开头的webservice接口

随着公司业务的不断扩大,我们跟不同系统的交互就与来越多。在此呢先感谢我们公司的框架部门为我们封装了很多很简便的方法。

比如httpclient的方式:httputil.sendpost(url,map);

又比如webservice的方式:WebServiceUtil.getService(class,url).method();

这些方法一般都能满足我们的需求,里面的参数配置等考虑的都很齐全。但是在特殊情况下,可能需要我们去个性化一种调用方式。

遇到的问题:访问以https://开头的webservice接口

周六本平台对接的另一个系统域名突然从http变更为https。以前使用的webservice接口均无法调用。导致系统无法使用,无奈驱车去公司整改。

困难:

1. http与https的区别在于https是ssl加密的,访问较为安全。但java中访问需要证书。

2. 通过传统webservice的方式,wsdl2java -encoding utf-8 https://xxxxxxx?wsdl 无法生成代理类(肯定可以解决该问题并通过webservice访问,但本人对webservice不是很熟).

3. 原代码使用的是框架方法,无法定位具体问题(目前没有https调用webservice的方法)。

思考:

1. 在互联网上,请求绝大多数是基于http协议的。不管后台是restful形式还是webservice形式,也不管后台是用.net还是java应该都可以通过模拟http请求来实现调用。

或者换句话说,webservice调用本身就是封装好的http请求(只不过多了数据封装和数据解析的步骤)。

2. 自己有http请求跳过证书验证的经验。

 

结论:利用HttpURLConnection调用Webservice。

步骤:

1. 先搞清楚接口的格式。我们可以借用soapUI来看看。

 访问以https://开头的webservice接口_第1张图片

 

分析这个webservice接口我们可以很轻松拿到几个关键行的参数:请求地址,请求主体(body),数据格式(关系到我们构建和解析数据),http请求的几个关键性参数都得到了。

2. 构建请求主体

 

我们直接将上面的body拼接起来,并传入参数,在这里有个小细节,参数尽量用

  data="";包裹起来以表明传输的是文本,不参与格式的解析。

3. 发送http请求

需要注意http请求头的配置博大精深,我这里设置的相对比较简单。

InputStreamReader bis = null;

OutputStreamWriter printWriter = null;

String body = "";

try {

HttpURLConnection httpURLConnection = SSLTrustManager.connect(url+"?wsdl");

httpURLConnection.setRequestMethod("POST");// 提交模式

 

httpURLConnection.setDoOutput(true);

httpURLConnection.setDoInput(true);

httpURLConnection.setRequestProperty("Content-Type", "text/xml; charset=utf-8");

// 获取URLConnection对象对应的输出流

printWriter = new OutputStreamWriter(httpURLConnection.getOutputStream(), "UTF-8");

// 发送请求参数

printWriter.write(xmldate);
// flush输出流的缓冲

printWriter.flush();

// 开始获取数据

bis = new InputStreamReader(httpURLConnection.getInputStream(), "UTF-8");

int len;

 

char[] arr = new char[1024];

while ((len = bis.read(arr)) != -1) {

body += new String(arr, 0, len);

}

} catch (Exception e) {

e.printStackTrace();

} finally {

if (bis != null) {

try {

bis.close();

} catch (IOException e) {

e.printStackTrace();

}

}

if (printWriter != null) {

try {

printWriter.close();

} catch (IOException e) {

e.printStackTrace();

}

}

}

 

4. 关于跳过https验证

 

访问以https://开头的webservice接口_第2张图片

 这个跳过验证在SSLTrustManager这个类里,里面可以跳过https验证,也可以通过加载证书的形式。附上这个类的代码。

import java.net.HttpURLConnection;
import java.net.URL;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLSession;


public class SSLTrustManager implements javax.net.ssl.TrustManager,
            javax.net.ssl.X509TrustManager ,HostnameVerifier{
        public java.security.cert.X509Certificate[] getAcceptedIssuers() {
            return null;
        }
  
        public boolean isServerTrusted(
                java.security.cert.X509Certificate[] certs) {
            return true;
        }
  
        public boolean isClientTrusted(
                java.security.cert.X509Certificate[] certs) {
            return true;
        }
  
        public void checkServerTrusted(
                java.security.cert.X509Certificate[] certs, String authType)
                throws java.security.cert.CertificateException {
            return;
        }
  
        public void checkClientTrusted(
                java.security.cert.X509Certificate[] certs, String authType)
                throws java.security.cert.CertificateException {
            return;
        }
         
            @Override
        public boolean verify(String urlHostName, SSLSession session) { //允许所有主机
            return true;
        }
        public static HttpURLConnection connect(String strUrl) throws Exception {
                
                javax.net.ssl.TrustManager[] trustAllCerts = new javax.net.ssl.TrustManager[1];
                javax.net.ssl.TrustManager tm = new SSLTrustManager();
                trustAllCerts[0] = tm;
                javax.net.ssl.SSLContext sc = javax.net.ssl.SSLContext
                        .getInstance("SSL");
                sc.init(null, trustAllCerts, null);
                javax.net.ssl.HttpsURLConnection.setDefaultSSLSocketFactory(sc
                        .getSocketFactory());
                 
                HttpsURLConnection.setDefaultHostnameVerifier((HostnameVerifier) tm);
                 
               URL url = new URL(strUrl);
               HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();
             
               return urlConn;
           }
               
 }

 

 

 

5. 获取数据后简单的解析

 访问以https://开头的webservice接口_第3张图片

我们发现获取的数据比较杂,真正有用的数据应该被包裹在soap:body里面。我们需要通过dom解析出来。同时我们发现“<”和“>”被用转移字符的形式替代了,我们还需要替换回来。这里就不贴代码了。

 

总结:只要细想不滑坡,办法总比困难多!访问以https://开头的webservice接口_第4张图片

 

 

你可能感兴趣的:(编程,java)