使用AXIS2作为Client访问WebService
使用AXIS2,可以方便的构建WebService的服务器端,也可以很方便的作为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) 大部分时候,客户端不会提前获得服务器的证书导致出错。所以需要自己更新一下通信的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,port,clientHost,clientPort); } @Override public Socket createSocket(String host,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,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根据服务器端的设定而指定,一般是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. 需要通过代理服务器的情况。 这个按照官方网站的来就可以了。 ? 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); 就可以通过代理服务器来访问了。 注意,使用代理服务期的注意事项: ? 实际工作中,我利用squid测试的时候,发现通信时,axis2默认使用chunked属性,导致不能通过squid,具体原因不明。 ? 于是,当时用squid的时候,把chunked属性disable掉了。 options.setProperty(HTTPConstants.CHUNKED,false); ? 这一点,官网上没有提及,也可能是我哪里设定的不够。 以上,就是通过Axis2作为客户端访问WebService的几种情况,基本上一般的http环境差不多应该都能对付了。 当然,还有其他的通信方式,暂时在工作中没有用到。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |