用https方式访问webservice笔记

来源:互联网 发布:java非对称加密的区别 编辑:程序博客网 时间:2024/06/06 04:34

有一个webservice只提供https访问接口


直接访问的的时候会报错:


org.apache.axis2.AxisFault: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at org.apache.axis2.AxisFault.makeFault(AxisFault.java:430)
    at org.apache.axis2.transport.http.SOAPMessageFormatter.writeTo(SOAPMessageFormatter.java:78)
    at org.apache.axis2.transport.http.AxisRequestEntity.writeRequest(AxisRequestEntity.java:85)
    at org.apache.commons.httpclient.methods.EntityEnclosingMethod.writeRequestBody(EntityEnclosingMethod.java:499)
    at org.apache.commons.httpclient.HttpMethodBase.writeRequest(HttpMethodBase.java:2114)
    at org.apache.commons.httpclient.HttpMethodBase.execute(HttpMethodBase.java:1096)
    at org.apache.commons.httpclient.HttpMethodDirector.executeWithRetry(HttpMethodDirector.java:398)
    at org.apache.commons.httpclient.HttpMethodDirector.executeMethod(HttpMethodDirector.java:171)
    at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:397)
    at org.apache.axis2.transport.http.impl.httpclient3.HTTPSenderImpl.executeMethod(HTTPSenderImpl.java:872)
    at org.apache.axis2.transport.http.impl.httpclient3.HTTPSenderImpl.sendViaPost(HTTPSenderImpl.java:212)
    at org.apache.axis2.transport.http.HTTPSender.send(HTTPSender.java:121)
    at org.apache.axis2.transport.http.CommonsHTTPTransportSender.writeMessageWithCommons(CommonsHTTPTransportSender.java:403)
    at org.apache.axis2.transport.http.CommonsHTTPTransportSender.invoke(CommonsHTTPTransportSender.java:234)
    at org.apache.axis2.engine.AxisEngine.send(AxisEngine.java:431)
    at org.apache.axis2.description.OutInAxisOperationClient.send(OutInAxisOperation.java:399)
    at org.apache.axis2.description.OutInAxisOperationClient.executeImpl(OutInAxisOperation.java:225)
    at org.apache.axis2.client.OperationClient.execute(OperationClient.java:150)
    at org.apache.axis2.client.ServiceClient.sendReceive(ServiceClient.java:533)
    at org.apache.axis2.client.ServiceClient.sendReceive(ServiceClient.java:509)
    at kkkkkuuuu.testDocument(kkkkkuuuu.java:55)
    at kkkkkuuuu.main(kkkkkuuuu.java:67)



错误原因是未配置证书访问环境,上网寻找问题解决方案,参考如下文章:

http://blog.csdn.net/greatmind829/article/details/8113641


1.首先导出网站证书,浏览器用的是FireFox48.0.2





将服务器证书导入到D:根目录保存。



2:然后根据这个.CER文件生成.trustStore 文件

cd d:/jre7/bin

D:\jre7\bin>keytool -import -file d:/bjp2p.com.cn.crt -storepass netconfig -keystore  d:/crtTrust.trustStore


安装界面提升选择 是【y】


3.编写客户端程序使用此文件配置


import javax.xml.namespace.QName;  

import org.apache.axiom.om.OMAbstractFactory;  
import org.apache.axiom.om.OMElement;  
import org.apache.axiom.om.OMFactory;  
import org.apache.axiom.om.OMNamespace;  
import org.apache.axis2.AxisFault;  
import org.apache.axis2.Constants;
import org.apache.axis2.addressing.EndpointReference;  
import org.apache.axis2.client.Options;  
import org.apache.axis2.client.ServiceClient;  
import org.apache.axis2.rpc.client.RPCServiceClient;  

public class kkkkkuuuu {

      /**
       * 方法二: 应用document方式调用
       * 用ducument方式应用现对繁琐而灵活。现在用的比较多。因为真正摆脱了我们不想要的耦合
       */  
      public static void testDocument() {  
        try {  
            //https方式访问webservices
           System.setProperty("javax.net.ssl.trustStore","D:/crtTrust.trustStore");
           System.setProperty("javax.net.ssl.trustStorePassword", "netconfig");
          // String url = "http://localhost:8080/axis2ServerDemo/services/StockQuoteService";  
          String url = "https://test.bjp2p.com.cn:8443/platformService?wsdl";  
      
          Options options = new Options();  
          // 指定调用WebService的URL  
          EndpointReference targetEPR = new EndpointReference(url);  
          options.setTo(targetEPR);  
          // options.setAction("urn:getPrice");  
         // options.setTransportInProtocol(Constants.TRANSPORT_HTTP);
          ServiceClient sender = new ServiceClient();  
          sender.setOptions(options);  
            
            
          OMFactory fac = OMAbstractFactory.getOMFactory();  
          String tns = "http://supervise.service.app.mp.zkbc.net/";  
          // 命名空间,有时命名空间不增加没事,不过最好加上,因为有时有事,你懂的  
          OMNamespace omNs = fac.createOMNamespace(tns, "");  
      
          OMElement method = fac.createOMElement("productRegistration", omNs);  
          OMElement symbol = fac.createOMElement("arg0", omNs);  
    
          symbol.addChild(fac.createOMText(symbol, "fylcws"));  
          method.addChild(symbol);  
          method.build();  
          OMElement symbol1 = fac.createOMElement("arg1", omNs);  
    
          symbol1.addChild(fac.createOMText(symbol1, "fylcws@4r1"));  
          method.addChild(symbol1);  
          method.build();  
          
          OMElement result = sender.sendReceive(method);  
      
          System.out.println(result);  
      
        } catch (AxisFault axisFault) {  
          axisFault.printStackTrace();  
        }  
      }  
      
      
    public static void main(String[] args) {

        kkkkkuuuu.testDocument();
    }

}

运行后就可以正常了,不会出现PKIX path building failed的错误了。


附带wsdl的服务配置文件,访问https://test.bjp2p.com.cn:8443/platformService?wsdl可以看见:


<!-- Published by JAX-WS RI at http://jax-ws.dev.java.net. RI's version is JAX-WS RI 2.2.8-promoted-b146 svn-revision#13443.
--><!-- Generated by JAX-WS RI at http://jax-ws.dev.java.net. RI's version is JAX-WS RI 2.2.8-promoted-b146 svn-revision#13443.
--><definitions targetNamespace="http://supervise.service.app.mp.zkbc.net/" name="InfoWsServiceService"><types/><message name="productRegistration"><part name="arg0" type="xsd:string"/><part name="arg1" type="xsd:string"/><part name="arg2" type="xsd:string"/></message><message name="productRegistrationResponse"><part name="return" type="xsd:string"/></message><message name="productStatusUpdate"><part name="arg0" type="xsd:string"/><part name="arg1" type="xsd:string"/><part name="arg2" type="xsd:string"/></message><message name="productStatusUpdateResponse"><part name="return" type="xsd:string"/></message><message name="productProcessUpdate"><part name="arg0" type="xsd:string"/><part name="arg1" type="xsd:string"/><part name="arg2" type="xsd:string"/></message><message name="productProcessUpdateResponse"><part name="return" type="xsd:string"/></message><portType name="InfoWsService"><operation name="productRegistration" parameterOrder="arg0 arg1 arg2"><input wsam:Action="http://supervise.service.app.mp.zkbc.net/InfoWsService/productRegistrationRequest" message="tns:productRegistration"/><output wsam:Action="http://supervise.service.app.mp.zkbc.net/InfoWsService/productRegistrationResponse" message="tns:productRegistrationResponse"/></operation><operation name="productStatusUpdate" parameterOrder="arg0 arg1 arg2"><input wsam:Action="http://supervise.service.app.mp.zkbc.net/InfoWsService/productStatusUpdateRequest" message="tns:productStatusUpdate"/><output wsam:Action="http://supervise.service.app.mp.zkbc.net/InfoWsService/productStatusUpdateResponse" message="tns:productStatusUpdateResponse"/></operation><operation name="productProcessUpdate" parameterOrder="arg0 arg1 arg2"><input wsam:Action="http://supervise.service.app.mp.zkbc.net/InfoWsService/productProcessUpdateRequest" message="tns:productProcessUpdate"/><output wsam:Action="http://supervise.service.app.mp.zkbc.net/InfoWsService/productProcessUpdateResponse" message="tns:productProcessUpdateResponse"/></operation></portType><binding name="InfoWsServicePortBinding" type="tns:InfoWsService"><soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="rpc"/><operation name="productRegistration"><soap:operation soapAction=""/><input><soap:body use="literal" namespace="http://supervise.service.app.mp.zkbc.net/"/></input><output><soap:body use="literal" namespace="http://supervise.service.app.mp.zkbc.net/"/></output></operation><operation name="productStatusUpdate"><soap:operation soapAction=""/><input><soap:body use="literal" namespace="http://supervise.service.app.mp.zkbc.net/"/></input><output><soap:body use="literal" namespace="http://supervise.service.app.mp.zkbc.net/"/></output></operation><operation name="productProcessUpdate"><soap:operation soapAction=""/><input><soap:body use="literal" namespace="http://supervise.service.app.mp.zkbc.net/"/></input><output><soap:body use="literal" namespace="http://supervise.service.app.mp.zkbc.net/"/></output></operation></binding><service name="InfoWsServiceService"><port name="InfoWsServicePort" binding="tns:InfoWsServicePortBinding"><soap:address location="https://test.bjp2p.com.cn:8443/platformService"/></port></service></definitions>


===============================================================================================================================

无需导入key文件的访问Https网站的例子,apache HttpClient 4.5版本,源码如下:


package com.squgrc.util.http;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.Method;
import java.net.HttpURLConnection;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.util.EntityUtils;

/**
 * 同时支持Http和Https的客户端工具,
 *
 * 使用非安全方式访问Https网站,信任全部证书。
 *
 * apache HttpClients版本:4.5
 *
 */
public class HttpSSLClientTools {
    // String
    // url="https://grc.songzidai.com/squAPI2/api/adminlogin3.do?userName=13910979086&password=325a2cc052914ceeb8c19016c091d2ac";
    static String url = "http://localhost:8080/squAPI2/api/adminlogin3.do?userName=13910979086&password=325a2cc052914ceeb8c19016c091d2ac";
    static String urlPost = "http://localhost:8080/squAPI2/api/adminlogin3.do";

    public final static void main(String[] args) throws Exception {
        getForm();
        postForm();
    }

    public static void getForm() throws Exception {
        // Trust own CA and all self-signed certs
        // SSLContext sslcontext = SSLContexts.custom()
        // .loadTrustMaterial(new
        // File("D:/worksapce2/squGRC2/src/main/resources/crtTrust.trustStore"),
        // "netconfig".toCharArray(),
        // new TrustSelfSignedStrategy())
        // .build();
        // Allow TLSv1 protocol only
        // SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
        // sslcontext,
        // new String[] { "TLSv1" },
        // null,
        // SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);

        SSLConnectionSocketFactory sslsf2 = new SSLConnectionSocketFactory(createSSLContext(), new String[] { "TLSv1" },
                null, SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
        CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf2).build();
        try {
            HttpGet httpget = new HttpGet(url);

            System.out.println("Executing request " + httpget.getRequestLine());

            CloseableHttpResponse response = httpclient.execute(httpget);
            try {

                HttpEntity entity = response.getEntity();

                System.out.println("----------------------------------------");
                System.out.println(response.getStatusLine());
                // EntityUtils.consume(entity);
                System.out.println(EntityUtils.toString(entity, "UTF-8"));
            } finally {
                response.close();
            }
        } finally {
            httpclient.close();
        }
    }

    public static String doHttp(String urlStr, String charSet, Object parameters, String timeOut) throws Exception {
        String responseString = "";

        int statusCode = 0;

        SSLConnectionSocketFactory sslsf2 = new SSLConnectionSocketFactory(createSSLContext(), new String[] { "TLSv1" },
                null, SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
        CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf2).build();

        // httpclient.setConnectionTimeout(new Integer(timeOut).intValue());
        // httpclient.getHttpConnectionManager().getParams().setConnectionTimeout(new
        // Integer(timeOut).intValue());

        // 发送请求
        CloseableHttpResponse response = null;
        try {
            HttpPost httppost = new HttpPost(urlStr);
            // 组合请求参数
            List<NameValuePair> list = new ArrayList<NameValuePair>();
            Method[] ms = parameters.getClass().getMethods();
            for (int i = 0; i < ms.length; i++) {
                Method m = ms[i];
                String name = m.getName();
                if (name.startsWith("get")) {
                    String param = name.substring(3, name.length());
                    param = param.substring(0, 1).toLowerCase() + param.substring(1, param.length());
                    if (param.equals("class")) {
                        continue;
                    }
                    Object value = "";
                    try {
                        value = m.invoke(parameters, null);
                        BasicNameValuePair nvp = new BasicNameValuePair(param, value.toString());
                        list.add(nvp);
                    } catch (Exception e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                        throw e;
                    }
                }
            }
            //NameValuePair[] nvps = new NameValuePair[list.size()];
            UrlEncodedFormEntity uefEntity = new UrlEncodedFormEntity(list, charSet);
            httppost.setEntity(uefEntity);
            response = httpclient.execute(httppost);
            statusCode = response.getStatusLine().getStatusCode();

            if (statusCode < HttpURLConnection.HTTP_OK || statusCode >= HttpURLConnection.HTTP_MULT_CHOICE) {
                System.err.println("失败返回码[" + statusCode + "]");
                throw new Exception("请求接口失败,失败码[ " + statusCode + " ]");
            } else {
                // if (entity != null) {
                HttpEntity entity = response.getEntity();
                responseString = EntityUtils.toString(entity, charSet);
                System.out.println(responseString);

                return responseString;

            }
        } catch (IOException e) {
            e.printStackTrace();
            System.err.println(e.toString());
            throw e;
        } finally {
            httpclient.close();
            response.close();
        }

    }

    /**
     * post方式提交表单(模拟用户登录请求)
     *
     * @throws Exception
     */
    public static void postForm() throws Exception {
        SSLConnectionSocketFactory sslsf2 = new SSLConnectionSocketFactory(createSSLContext(), new String[] { "TLSv1" },
                null, SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
        CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf2).build();

        // 发送请求
        CloseableHttpResponse response = null;
        try {
            httpclient = HttpClients.createDefault();
            // 创建httppost

            HttpPost httppost = new HttpPost(urlPost);
            // 创建参数队列
            List<NameValuePair> formparams = new ArrayList<NameValuePair>();
            formparams.add(new BasicNameValuePair("userName", "13910979086"));
            formparams.add(new BasicNameValuePair("password", "325a2cc052914ceeb8c19016c091d2ac"));
            // 参数转码
            UrlEncodedFormEntity uefEntity = new UrlEncodedFormEntity(formparams, "UTF-8");
            httppost.setEntity(uefEntity);
            response = httpclient.execute(httppost);
            HttpEntity entity = response.getEntity();
            if (entity != null) {
                System.out.println(EntityUtils.toString(entity, "UTF-8"));
            }
            // 释放连接
        } catch (Exception e) {
            throw e;
        } finally {
            httpclient.close();
            response.close();
        }
    }

    private static SSLContext createSSLContext() {
        SSLContext sslcontext = null;
        try {
            sslcontext = SSLContext.getInstance("SSL");
            sslcontext.init(null, new TrustManager[] { new TrustAnyTrustManager() }, new java.security.SecureRandom());
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (KeyManagementException e) {
            e.printStackTrace();
        }
        return sslcontext;
    }

    // 自定义私有类
    private static class TrustAnyTrustManager implements X509TrustManager {

        public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
        }

        public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
        }

        public X509Certificate[] getAcceptedIssuers() {
            return new X509Certificate[] {};
        }
    }
}


0 0