zoukankan      html  css  js  c++  java
  • 使用AXIS2作为Client訪问WebService

    使用AXIS2,能够方便的构建WebService的server端,也能够非常方便的作为Cilent,来訪问别的WebService。

    以下依据工作中的经历,整理了一下,作为Cilent訪问WebService的要点。

    依据Axis2的官方文档。Client的DataBinding方式有3种,最简单的好像是ADB。那么我就选用的ADB。


    1.普通方式(http 不通过proxy,对方也没有利用SSL)

    // Generate Client
    RPCServiceClient serviceClient = new RPCServiceClient();
    Options options = serviceClient.getOptions();
    
    // Generate Endpoint
    String webserviceurl = "http://www.abc.net/webservice/servicepage"; // for example.
    EndpointReference targetEPR = new EndpointReference(webserviceurl);
    
    options.setTo(targetEPR);
    
    // Auto release transport.
    options.setCallTransportCleanup(true);
    
    // Generate Action
    String ns = "http://www.abc.net/webservice";
    String action = "getSomething"; 
    QName opAction = new QName(ns, action);
    
    // Generate Reqest parameters
    ReqBean reqObj = new ReqBean();
    reqObj.setParam1("param1");
    reqObj.setParam2("param2");
    
    Object[] opArgs = new Object[] { reqObj };
    Class[] returnTypes = new Class[] { ArrayList.class };
    
    Object[] response = null;
    
    try {
        response = serviceClient.invokeBlocking(opAction, opArgs, returnTypes);
    } catch (AxisFault af) {
        // Process exception.
    }
    
    ArrayList res = (ArrayList) response[0];
    
    // Analyze the response.
    // ...

    当中,ReqBean是依据所訪问的WebService须要的parameter,能够依据wsdl生成java的Bean类。

    返回的Response,统一先转换为ArrayList,然后进一步解析为字符串或者各个Bean。


    这是最简单的訪问方式。


    2.通过SSL訪问。

    (https)

    大部分时候,client不会提前获得server的证书导致出错。所以须要自己更新一下通信的protocol。

      官方站点上说的不甚具体。所以罗列一下代码。

      2.1 生成一个新的协议工厂类:

    import java.io.IOException;
    import java.net.InetAddress;
    import java.net.InetSocketAddress;
    import java.net.Socket;
    import java.net.SocketAddress;
    import java.net.UnknownHostException;
    import java.security.cert.CertificateException;
    import java.security.cert.X509Certificate;
    
    import javax.net.SocketFactory;
    import javax.net.ssl.SSLContext;
    import javax.net.ssl.TrustManager;
    import javax.net.ssl.X509TrustManager;
    
    import org.apache.commons.httpclient.ConnectTimeoutException;
    import org.apache.commons.httpclient.HttpClientError;
    import org.apache.commons.httpclient.params.HttpConnectionParams;
    import org.apache.commons.httpclient.protocol.ProtocolSocketFactory;
    
    public class SSLIgnoreErrorProtocolSocketFactory implements
    		ProtocolSocketFactory {
    	private SSLContext sslcontext = null;
    
    	/**
    	 * 不进行证明书的验证
    	 * 
    	 * @return
    	 */
    	private static SSLContext createEasySSLContext() {
    		try {
    			SSLContext context = SSLContext.getInstance("SSL");
    			context.init(null, new TrustManager[] { new X509TrustManager() {
    				public void checkClientTrusted(X509Certificate[] arg0,
    						String arg1) throws CertificateException {
    				}
    
    				public void checkServerTrusted(X509Certificate[] arg0,
    						String arg1) throws CertificateException {
    				}
    
    				public X509Certificate[] getAcceptedIssuers() {
    					return null;
    				}
    			} }, null);
    			return context;
    		} catch (Exception e) {
    			throw new HttpClientError(e.toString());
    		}
    	}
    
    	private SSLContext getSSLContext() {
    		if (this.sslcontext == null) {
    			this.sslcontext = createEasySSLContext();
    		}
    		return this.sslcontext;
    	}
    
    	@Override
    	public Socket createSocket(String host, int port) throws IOException,
    			UnknownHostException {
    		return getSSLContext().getSocketFactory().createSocket(host, port);
    	}
    
    	@Override
    	public Socket createSocket(String host, int port, InetAddress clientHost,
    			int clientPort) throws IOException, UnknownHostException {
    		return getSSLContext().getSocketFactory().createSocket(host, port,
    				clientHost, clientPort);
    	}
    
    	@Override
    	public Socket createSocket(String host, int port, InetAddress localAddress,
    			int localPort, HttpConnectionParams params) throws IOException,
    			UnknownHostException, ConnectTimeoutException {
    		if (params == null) {
    			throw new IllegalArgumentException("Parameters may not be null");
    		}
    		int timeout = params.getConnectionTimeout();
    		SocketFactory socketfactory = getSSLContext().getSocketFactory();
    		if (timeout == 0) {
    			return socketfactory.createSocket(host, port, localAddress,
    					localPort);
    		} else {
    			Socket socket = socketfactory.createSocket();
    			SocketAddress localaddr = new InetSocketAddress(localAddress,
    					localPort);
    			SocketAddress remoteaddr = new InetSocketAddress(host, port);
    			socket.bind(localaddr);
    			socket.connect(remoteaddr, timeout);
    			return socket;
    		}
    	}
    
    }

      2.2 利用上面的类。做成一个新的协议对象。(sslport依据server端的设定而指定。通常是443.)

    Protocol protocol = null;
    SSLIgnoreErrorProtocolSocketFactory socketfactory = null;
    
    socketfactory = new SSLIgnoreErrorProtocolSocketFactory();
    
    protocol = new Protocol("https", socketfactory, sslport);

      2.3 把上面做成的protocol对象设定给RPCServiceClient的options。

    options.setProperty(HTTPConstants.CUSTOM_PROTOCOL_HANDLER, protocol);

    然后。就能够通过https来訪问WebService了

      注意:HTTPConstants是利用的org.apache.axis2.transport.http.HTTPConstants类。


    3. 须要通过代理server的情况。

    这个依照官方站点的来就能够了。

      3.1 生成代理属性:

    HttpTransportProperties.ProxyProperties proxyProperties = new HttpTransportProperties.ProxyProperties();
    proxyProperties.setProxyName(proxy_server);
    proxyProperties.setProxyPort((int) (proxy_port);

      HttpTransportProperties是利用的org.apache.axis2.transport.http.HttpTransportProperties


      3.2 把代理属性设定给RPCServiceClient的options。

    options.setProperty(HTTPConstants.PROXY, proxyProperties);

    就能够通过代理server来訪问了。


    注意,使用代理服务期的注意事项:

      实际工作中,我利用squid測试的时候,发现通信时,axis2默认使用chunked属性,导致不能通过squid,详细原因不明。

      于是。当时用squid的时候,把chunked属性disable掉了。

    options.setProperty(HTTPConstants.CHUNKED, false);

      这一点。官网上没有提及,也可能是我哪里设定的不够。


    以上,就是通过Axis2作为client訪问WebService的几种情况,基本上一般的http环境差点儿相同应该都能对付了。

    当然,还有其它的通信方式。临时在工作中没实用到。


  • 相关阅读:
    POJ-3254 + POJ-1185 状压DP入门题
    POJ-3667 线段树区间合并入门题
    HDU-4507 数位DP 记录一个毒瘤错误orz
    HDU-4734 F(x)数位dp
    HDU-3709 Balanced Number 数位dp+枚举
    分块入门 LibreOJ分块九题
    HDU-4389 X mod f(x) && 2018上海大都会邀请赛J 数位dp
    HDU-3038 How Many Answers Are Wrong (带权并查集)
    Codeforces 608B Hamming Distance Sum (前缀和)
    (二十六 )数据库:水平切分,数据库秒级扩容!
  • 原文地址:https://www.cnblogs.com/jzssuanfa/p/7281390.html
Copyright © 2011-2022 走看看