在具体介绍这两种框架下的webservice之前,先跟大家交流一下SOA认识,也就是面向服务的体系结构。SOA所要解决的主要问题是在现有基础环境的前提下,通过对现有应用程序和基础结构进行重新的组合以应对不断变化的业务需求。SOA凭借其松耦合的特性,使得企业可以按照模块化的方式来添加新服务或更新现有服务,以解决新的业务需要,而其对外提供服务的主要方式之一就是我们今天所要介绍的webservice。目前来讲比较有名的webservice框架大致有四种JWS,Axis,XFire以及CXF。今天我们主要介绍前两种。
1. JWS-WebService.JWS是java语言实现的一种webservice,用来开发和发布服务,它是一个轻量级的WS框架,实现起来也非常的简单,下面通过一个小demo来看一下JWS是如何实现的:
(1) 定义接口,并将接口发布成webservice:
package org.zttc.service; import javax.jws.WebParam; import javax.jws.WebResult; import javax.jws.WebService; import javax.jws.soap.SOAPBinding; @WebService @SOAPBinding(style = SOAPBinding.Style.RPC) public interface IMyService { @WebResult(name="addResult") public int add(@WebParam(name="a")int a,@WebParam(name="b")int b); @WebResult(name="loginUser") public User login(@WebParam(name="username")String username,@WebParam(name="password")String password); }
(2).定义接口实现:
package org.zttc.service; import javax.jws.WebParam; import javax.jws.WebResult; import javax.jws.WebService; @WebService(endpointInterface="org.zttc.service.IMyService") public class MyServiceImpl implements IMyService { @Override public int add(int a, int b) { System.out.println(a + "+" + b + "=" + (a + b)); return a+b; } @Override public User login(@WebParam(name = "username") String username, @WebParam(name = "password") String password) { System.out.println(username + " is logging"); User user = new User(); user.setId("1"); user.setUsername(username); user.setPassword(password); return user; } }
(3).发布服务:
package org.zttc.service; import javax.xml.ws.Endpoint; public class MyServer { public static void main(String[] args){ String address = "http://localhost:8888/ns"; Endpoint.publish(address, new MyServiceImpl()); } }
(4).编写测试类代码:
package org.zttc.service; import java.net.MalformedURLException; import java.net.URL; import javax.xml.namespace.QName; import javax.xml.ws.Service; public class TestClient { public static void main(String[] args){ try { //创建访问wsdl服务地址的url URL url = new URL("http://localhost:8888/ns?wsdl"); //通过QName指明服务的和具体信息 QName sname= new QName("http://service.zttc.org/","MyServiceImplService"); //创建服务 Service service = Service.create(url,sname); //实现接口 IMyService ms =service.getPort(IMyService.class); System.out.println(ms.add(12, 33)); } catch (MalformedURLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
通过上面的代码我们可以看出在调用webservice的同时我们仍然需要知道对应的java类(接口),但调用webservice的情况往往两发生在个不同系统之间的,事先无法获取对应的接口,这时我们因该怎样解决这个问题呢?很简单,我们可以通过jdk,使用导出命令,将wsdl中的接口描述来生成这个接口以及实现类,然后将生成的接口和实现类应用在我们自己的java程序中就可以了,具体的生成命令是: Wsimport -d E:/我的酷盘/我的工程/java项目/webservice/01/ -keep -verbose http://localhost:6666/ns?wsdl .
2 . 基于Axis2框架的webservice。相对于JWS来说Axis2是一个重量级的webservice框架,准确说它是一个Web Services / SOAP / WSDL的引擎,它不但能制作和发布WebService,而且可以生成Java和其他语言版WebService客户端和服务端代码。也正是由于Axis2做了非常优秀的封装,使得我们在使用Axis2-WS的时候非常的简单,下面通过一个小例子跟大家介绍一下Axis2的应用。
(1). 首先我们要做的是下载axis.war,并将这个war包发布到我们的tomcat的webapps下。启动tomcat,访问:http://localhost:8080/axis2/,如果界面显示如下则说明发布成功:(2).编写我们的java类。注意我们所建立的java类不要放在任何包中,直接放在src下即可,代码如下:
public class MyService { public String sayHello(String name,boolean isMan) { if(isMan) { return "Hello,Mr "+name+"! Welcome to Webservice"; } else { return "Hello,Miss "+name+"! Welcome to Webservice"; } } }
(3).将我们建好的class类放到%tomcat%\webapps\axis2\WEB-INF\pojo文件夹下(如果没有该文件夹请新建一个并以pojo命名)。做完这一步之后启动tomcat,访问http://localhost:8080/axis2/services/listServices,如果出现如下界面则说明发布成功:
(4).发布好之后我们就可以编写客户端尝试调用webservice,客户端代码如下:
package com.unimas.datacollection.webservices.client; import org.apache.axis2.addressing.EndpointReference; import org.apache.axis2.client.Options; import org.apache.axis2.rpc.client.RPCServiceClient; import javax.xml.namespace.QName; public class Client { public static void main(String[] args) throws Exception { // 使用RPC方式调用WebService RPCServiceClient serviceClient = new RPCServiceClient(); Options options = serviceClient.getOptions(); // 指定调用WebService的URL EndpointReference er = new EndpointReference( "http://localhost:8080/axis2/services/MyService"); options.setTo(er); // 指定sayHello方法的参数值 Object[] opAddArgs = new Object[] { "张三", false }; // 指定sayHello方法返回值的数据类型的class对象 Class[] classs = new Class[] { String.class }; // 指定要调用的sayHello方法及wsdl文件的命名空间,第一个参数表示WSDL文件的命名空间 // 通过访问http://localhost:8080/axis2/services/MyService?wsdl 就可以看见 // 元素的targetNamespace属性值 QName qname = new QName("http://ws.apache.org/axis2", "sayHello"); // 调用sayHello方法并输出该方法的返回值 // 这里有三个参数的意思:1,是QName对象,表示要调用的方法名;2,webservice的参数值,参数类型是Object[];3,返回值class对象,参数类型是Class[], System.out.println(serviceClient.invokeBlocking(qname, opAddArgs, classs)[0]); } }
至此Axis2-WS发布完成,执行客户端代码即可在控制台输出调用结果。以上是对JWS和Axis2具体应用的简单介绍,对比这两种应用可以发现使用JWS比较灵活,我们可以随意的增加服务而不需要一次次的重新部署,但是我们所要做的工作量是比较大的。而使用Axis2对于开发webservice来讲相当的简单,我们唯一需要做的就是开发一个普通的java类,然后放到tomcat的对应文件夹下即可,可以说小有小的好处,大有大的优势。