Axis2的开发(服务器端和客户端)
目前WebService比较流行.两个项目之间的交互JAVA的实现方式有多种,Ejb,Spring里面的RIM都可以实现,但是WebService有着自己的优势.即客户端和服务器的开发语言没有限制,可以采用自己熟悉的语言,因为它采用的是WSDL文件通过SOAP协议来交互的.因为小弟对JAVAEE比较熟悉,我写过几个客户端的例子,我链接的服务器端大多数是用.NET写的,下面就以前写过的企信通(短信开发平台)写个DMEO.
小弟采用的WebService用的是Apache的Axis2 的最新版--axis2 1.5,Axis2 底层重新编写,比axis1 有很大的进步(因为小弟没有接触过其它的WebService的框架),觉得比较好用.闲活少说,马上开始写代码吧.
1,下载Axis2 1.5.下载地址.
http://ws.apache.org/axis2/download/1_5/download.cgi,里面有二进制(Standard Binary Distribution),源代码(Source Distribution),War包(WAR (Web Archive) Distribution)其中二进制,是必须下载的.War包如果不开发服务器端可以不用下载.
下载后解压二进制目录,
解压后目录如下.
Bin:包括axis2常用的命令.如果想使用里面的命令,需要先把它加载你的ClassPath里面.如wsdl2java、java2wsdl.
Conf:里面包含了axis2的配置信息,如进行axis2后台的用户名和密码.
Repository:里面包含了axis2服务的自带的例子,其中包括axis2要用到的寻址查询之类的信息.
Samples:包括axis2的一些入门的例子,这里面是学习axis2的地方,也是最权威的.
WebApp:是包括axis2自己开发的一个Web应用,(用于开发Webservice的服务器端程序)
2,开发Webservice的客户端.
小弟就链接企信通的服务.服务地址: http://59.36.98.25/ClientWebService/ClientWS.asmx
打开后的界面如下:
一般看到这个界面,就是它的服务器端,是用.net写的(80%的可能.).Webservice的交互是通过WSDL文件,所以我们应该拿到Wsdl文件.点击服务说明.
拿到WSDL文件的界面如下:
启动DOS:使用以下命令,会生成一系列的代码:主要包括一个Stub和CallbackHandler的类wsdl2java -uri http://59.36.98.25/ClientWebService/ClientWS.asmx?WSDL –p com.wangsh.webservice.util -o src,除了这两个参数,其它的都不要加,如果加上了,生成的代码就不一样了,它会给你生成一系列框架的代码而不是我们想要的代码.
-p表示我们生成代码的包名,-o表示生成的代码所放的目录.
这两个类就是关键.我们就可以用它来写客户端代码.
提供了客户端的代码:
// 进行服务器端验证 // 创建一个验证请求 ClientWSStub.AuthRequest authreq = new ClientWSStub.AuthRequest(); authreq.setChannelID(this.channelID); authreq.setCorpAccount(this.corpAccount); authreq.setUserAccount(this.userAccount); authreq.setPassword(MD5.toMD5(this.password)); timestamp = "" + System.currentTimeMillis(); authreq.setTimestamp(timestamp); // MD5(channeled$corpAccount$userAccount$password$timestamp) this.qixintongCode = authreq.getChannelID() + compart + this.corpAccount + compart + this.userAccount + compart + this.password + compart + timestamp; authreq.setCode(MD5.toMD5(this.qixintongCode)); try { ClientWSStub authcliws = new ClientWSStub(); ClientWSStub.Authenticate auth = new Authenticate(); auth.setRequest(authreq); ClientWSStub.AuthenticateResponse authclires = authcliws .Authenticate(auth); ClientWSStub.AuthResponse authres = authclires .getAuthenticateResult(); String result = authres.getResult(); System.out.println(authres.getEpSignName()); System.out.println("============" + result); if ("0".equalsIgnoreCase(result)) { System.out.println("--------------"); // 进行相关参数的设置 this.qunFaint = Integer.parseInt(authres.getSmsGroupCount()); this.tokenID = authres.getTokenID(); this.epSignName = authres.getEpSignName(); this.userSignName = authres.getUserSignName(); return true; } } catch (AxisFault e) { System.out.println("=====创建客户端程序出错了===="); e.printStackTrace(); return false; } catch (RemoteException e) { System.out.println("=====创建请求时出错了!!===="); e.printStackTrace(); return false; }
如果要链接的服务器有Basic,Digest and NTLM Authentication认证的话.使用上面的方法,在链接的时候会报以下错误:
Java code org.apache.axis2.AxisFault: Transport error: 401 Error: Unauthorized serviceClient = new org.apache.axis2.client.ServiceClient( configurationContext, _service); HttpTransportProperties.Authenticator basicauth = new HttpTransportProperties.Authenticator(); basicauth.setUsername("xxx"); basicauth.setPassword("xxx"); basicauth.setHost("xxx.xxx.xxx.xxx"); basicauth.setDomain("xxx.xxx.xxx.xxx "); _serviceClient.getOptions().setProperty(HTTPConstants.AUTHENTICATE, basicauth);
3,用Spring开发axis2的服务器端和客户端.
服务器端:
我们开发的服务器端是在War包(WAR (Web Archive) Distribution)开发的.就是axis2提供的War包程序.感觉就像是在axis2的基础上开发.
_1.首先需要把这个War包拷解压,把该项目下的目录对应拷贝到你的WebService的服务器端.之后再加上你的JAR包和文件.如Spring2.5+hibernate3.3+struts2.1.6的JAR包.
_2.在 /WebRoot/WEB-INF/services下面新建一个文件夹,名字起成你的服务名,该文件下的目录结构如下:
这个services.xml是最重要的,它描述了你的Webservice服务的一些相关信息.
该文件的代码如下:
Spring的配置和以前的配置一样,如Service和DAO层,各自有各自的实现类.我们暴露给客户端的就是Service层,也就是说客户端访问的是Service层.
服务器端还需要在Spring的配置文件里面加上ApplicationContext的一个Bean,代码如下:
Axis2初始化Spring需要借助于它自身的类,这个配置不能少..
如果忘配置了,会他以下错误:
Caused by: org.apache.axis2.AxisFault: Axis2 Can't find Spring's ApplicationContext at org.apache.axis2.AxisFault.makeFault(AxisFault.java:430) at org.apache.axis2.extensions.spring.receivers.SpringAppContextAwareObjectSupplier.getServiceObject(SpringAppContextAwareObjectSupplier.java:63) ... 30 more
如果布置成功的话,启动Tomcat
在地址里面输入:http://Ip地址:端口/services/服务的名字()
下面是客户端器的代码.
package com.axis2.client; import java.util.Iterator; import javax.xml.namespace.QName; import org.apache.axiom.om.OMElement; import org.apache.axis2.AxisFault; import org.apache.axis2.addressing.EndpointReference; import org.apache.axis2.client.Options; import org.apache.axis2.rpc.client.RPCServiceClient; import com.axis2.client.pojo.Person; /** * RPC方式的链接 * * @author Administrator * */ public class Springlient_person { public static void main(String[] args) { try { // 创建一个RPC的客户端实例 RPCServiceClient rpcServiceClient = new RPCServiceClient(); // 拿到相关的配置 Options options = rpcServiceClient.getOptions(); // 创建一个远程的访问地址 EndpointReference target = new EndpointReference( "http://192.168.0.103:8080/passport/services/demoArticle"); options.setTo(target); // 创建一个Qname的命名空间,默认的是域名倒过来写,第二个参数的写方法名 QName qgetname = new QName("http://implay.service.demo.passport.com", "getPerson"); // 参数 Object[] objargs = new Object[] {2}; // 数组的实例 Class[] getobj = new Class[] { Person.class }; // 返回的数组实例. Object[] response = rpcServiceClient.invokeBlocking(qgetname, objargs, getobj); // 拿到请求的对象. Person per = (Person) response[0]; if (per == null) { System.out.println("====wea没有初始化=========="); } System.out.println(per.getPname()); System.out.println(per.getCityList().size()); for (Iterator iterator = per.getCityList().iterator(); iterator.hasNext();) { OMElement ome = (OMElement) iterator.next(); System.out.println(ome.getText()); } } catch (AxisFault e) { System.out.println("=====创建失败了!!=========="); e.printStackTrace(); } } }
里面提到的POJO,服务器端和正常的SSH开发是一样的.在客户端,需要自己再创建一个POJO,和服务器商的是一样的.
需要注意的是只有在Serviec的接口里面提到的方法才可以被客户端调用
客户端请求二进制文件.
在服务器端和一般服务不同的是:(例子代码如下:)
public boolean uploadWithData(DataHandler handler, String name) { String path = "E:/文件/" + name; File pathFile = new File(path); try { FileOutputStream fos = new FileOutputStream(pathFile); BufferedOutputStream bos = new BufferedOutputStream(fos); System.out.println(handler.getContent()); BufferedInputStream bis = new BufferedInputStream(handler .getInputStream()); byte[] b = new byte[1024]; int length = 0; while ((length = bis.read(b)) != -1) { bos.write(b, 0, length); } bis.close(); bos.close(); return true; } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return false; }
在然在客户端调用的具体代码如下:
package com.test.webservice.test; import java.rmi.RemoteException; import javax.activation.DataHandler; import javax.activation.FileDataSource; import org.apache.axis2.AxisFault; import com.test.webservice.util.TestFileStub; import com.test.webservice.util.TestFileStub.UploadWithData; import com.test.webservice.util.TestFileStub.UploadWithDataResponse; public class TestClient { public static void main(String[] args) { FileDataSource testFile = new FileDataSource("1211098267865.jpg"); try { TestFileStub fileStub = new TestFileStub(); UploadWithData data = new UploadWithData(); DataHandler param = new DataHandler(testFile) ; data.setHandler(param); data.setName("测试名字.jpg"); UploadWithDataResponse response = fileStub.uploadWithData(data); System.out.println(response.get_return()); } catch (AxisFault e) { e.printStackTrace(); } catch (RemoteException e) { e.printStackTrace(); } } }