1.1 什么是Web Services
简单地说就是一个应用程序,它向外界暴露出一个能够远程进行调用的程序。
Web services建立可互操作的分布式应用程序 。
1.2 Web Services平台的技术。
XML/xsd
Soap:(Simple Object Access Protocol)简单对象访问协议。是XML Web Service 的通信协议。当用户通过UDDI找到你的WSDL描述文档后,他可以通过SOAP调用你建立的Web服务中的一个或多个操作。SOAP是XML文档形式的调用方法的规范,它可以支持不同的底层接口,像HTTP(S)或者SMTP。
WSDL:(Web Services Description Language) WSDL 文件是一个 XML 文档,它对web Services的接口进行了定义,用于说明一组 SOAP 消息以及如何交换这些消息。大多数情况下由软件自动生成和使用。
UDDI是一种查找相应服务的机制,用于web服务的发布、浏览以及查找注册信息。它采用XML格式来封装各种不同类型的数据,并且发送到注册中心或者由注册中心来返回需要的数据。
这里特别要提出,UDDI不是必须的,事实上目前在企业项目中很少用到UDDI。
1.3 架构
服务提供者到注册中心(uddi)注册自己的服务。服务请求者(客户端)到注册中心(uddi)找到需要的web服务,并获得服务定义(wsdl),根据wsdl定义就可以调用相应的服务(通过soap协议)。
1.4 Web Service特点
Web Service的主要目标是跨平台的可互操作性。为了实现这一目标,Web Service 完全基于XML(可扩展标记语言)独立于平台、独立于开发语言的标准,是创建可互操作的、分布式应用程序的新平台。
优点: 跨防火墙的通信 、
应用程序集成 (异构系统) 、
软件和数据重用
跨语言 跨平台
缺点: 访问速度慢、稳定性问题。
1.5 Java与其他语言互操作
WSDL 文件是一个 XML 文档,它对web Services的接口进行了定义,用于说明一组 SOAP 消息以及如何交换这些消息。只要获得服务地址和WSDL 文件,就可对服务进行调用,无论服务的实现者是java还是.net。
操作方式:
1、直接解析soap消息。(繁琐、效率低)
2、通过工具(apache soap、visual studio)
事实上支持web services的各种语言和平台都可以实现互操作,如vb,delphi。只不过目前主流是Java与.net。
1.6 SOA与Web Service
最后我想说说SOA与Web Service的关系,这是经常被混淆的两个概念。
SOA(Service-oriented architecture,面向服务架构)。 将企业应用系统中细粒度的功能打包成粗粒度的服务,通过中间方式(语言),实现异构系统(操作系统、开发语言)之间的通讯、调用。
SOA并不是一种技术,而是一种软件设计理念。
Web service != SOA,但Web service 是目前实现SOA的最好方式。
2.Axis2简介与下载
MVC 有struts框架,Web Service也有框架:如axis2、xfire、cxf。
下面将介绍Web Service的一些规范和axis2的简单使用。
2.1 Axis2简介
Apache Axis2 是Axis的后续版本,是新一代的SOAP引擎。
Axis2的主要特点有:
(1)采用名为 AXIOM(AXIs Object Model)的新核心 XML 处理模型,利用新的XML解析器提供的灵活性按需构造对象模型。
(2) 支持不同的消息交换模式。目前Axis2支持三种模式:In-Only、Robust-In和In-Out。In-Only消息交换模式只有SOAP请求,而不需要应答;Robust-In消息交换模式发送SOAP请求,只有在出错的情况下才返回应答;In-Out消息交换模式总是存在SOAP请求和应答。
(3) 提供阻塞和非阻塞客户端 API。
(4) 支持内置的 Web服务寻址 (WS-Addressing) 。
(5) 灵活的数据绑定,可以选择直接使用 AXIOM,使用与原来的 Axis 相似的简单数据绑定方法,或使用 XMLBeans、JiBX 或 JAXB 2.0 等专用数据绑定框架。
(6) 新的部署模型,支持热部署。
(7) 支持HTTP,SMTP,JMS,TCP传输协议。
(8) 支持REST (Representational State Transfer)。
2.2 Axis2 支持的规范包括
SOAP 1.1 and 1.2
Message Transmission Optimization Mechanism (MTOM), XML Optimized Packaging (XOP) and SOAP with Attachments
WSDL 1.1, including both SOAP and HTTP bindings
WS-Addressing (submission and final)
WS-Policy
SAAJ 1.1
2.3 Axis2 下载
Axis2官方下载地址:http://axis.apache.org/axis2/java/core/download.cgi
下载:axis2-1.4.1-bin.zip 和 axis2-1.4.1-war.zip
3 服务端
axis2与web项目集成
有一个最简单的方法就是把axis2.war中的内容作为Web Project的基础, 来进行开发。
不过为了更清楚的了解如何在一个已有的Web Project中嵌入axis2, 那就手动来配置。大致分如下几个步骤:
一、新建Web Project,名为“studyaxis2server”
二、下载axis2-1.4.1war.zip包,解压缩
将axis2/WEB-INF/lib 里的jar包拷贝到 studyaxis2server/WebRoot/WEB-INF/lib/
将axis2.war/axis2-web拷贝至studyaxis2server/WebRoot/axis2-web/
(其实,axis2-web下面的东西可以不要那么多,那些JSP文件只保留了index.jsp和listServices.jsp这两个文件,listServices.jsp不是listService.jsp。这样集成后的工程就瘦身了)
三、配置axis2 servlet
打开studyaxis2server/WebRoot/WEB-INF/web.xml,增加如下配置。
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
AxisServlet
org.apache.axis2.transport.http.AxisServlet
1
AxisServlet
/services/*
index.jsp
四、写一个简单的web服务类
package com.lxit.study.ws.service;
/** 写一个简单的web服务类 */
public class MyWebService {
public String sayHello(String name) {
return "hello, " + name;
}
}
五、配置Web Service.
由于axis2已嵌入到studyaxis2server项目中,所以web service就不用打包成aar,而是直接在/WEB-INF目录下创建相应的文件夹和services.xml,目录结构如下图:
这个services目录下面就是我们webservice对应的服务存放的地方。其中最重要的是META-INF目录下的services.xml文件,axis2通过该文件来获知该服务的名称、服务类型以及服务类。下面是一个简单的services.xml
六、services.xml
第一种
Please Type your service description here
class="org.apache.axis2.rpc.receivers.RPCInOnlyMessageReceiver" />
class="org.apache.axis2.rpc.receivers.RPCMessageReceiver" />
com.lxit.study.ws.service.MyWebService
第二种
my Web Service demo
class="org.apache.axis2.rpc.receivers.RPCMessageReceiver" />
mep="http://www.w3.org/2004/08/wsdl/in-only"
class="org.apache.axis2.rpc.receivers.RPCInOnlyMessageReceiver" />
com.lxit.study.ws.service.MyWebService
通常使用第一种就可以了,也可以使用第2种。
七、发布服务并访问
把项目部署到tomcat 中。
在浏览器中访问: http://localhost:9090/studyaxis2server/services/listServices
可以看到myService服务,说明服务已部署成功。
点myService 这个超链接
或者 直接在浏览器中访问: http://localhost:9090/studyaxis2server/services/myService?wsdl
可以查看到该Web服务的描述文件。
4 客户端
一、新建Web Project,名为“studyaxis2Client”
package com.lxit.ws.demo;
import javax.xml.namespace.QName;
import junit.framework.TestCase;
import org.apache.axis2.AxisFault;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.Options;
import org.apache.axis2.rpc.client.RPCServiceClient;
public class TestWebService extends TestCase {
private RPCServiceClient serviceClient;
private Options options;
private EndpointReference targetEPR;
/**
* WS测试:传递String,返回String
*/
public void testSayHello() {
System.out.println("===================================");
final String endPointReference = "http://localhost:9090/studyAxis2Server/services/hello";
final String targetNamespace = "http://demo.ws.lxit.com"; //
init(endPointReference);
String opName = "sayHello";
Object[] opArgs = new Object[] { "第一次使用Web Service" };
Class>[] opReturnType = new Class[] { String[].class };
try {
Object[] response = invokeOp(targetNamespace, opName, opArgs, opReturnType);
System.out.println(((String[]) response[0])[0]);
} catch (Exception e) {
e.printStackTrace();
}
}
private void init(String endpoint) {
try {
serviceClient = new RPCServiceClient();
options = serviceClient.getOptions();
targetEPR = new EndpointReference(endpoint);
options.setTo(targetEPR);
} catch (AxisFault e) {
e.printStackTrace();
}
}
private Object[] invokeOp(String targetNamespace, String opName,
Object[] opArgs, Class>[] opReturnType) throws AxisFault,
ClassNotFoundException {
// 设定操作的名称
QName opQName = new QName(targetNamespace, opName);
// 设定返回值
// Class>[] opReturn = new Class[] { opReturnType };
// 操作需要传入的参数已经在参数中给定,这里直接传入方法中调用
return serviceClient.invokeBlocking(opQName, opArgs, opReturnType);
}
}
该例子最大的不同和优势表现在客户端的调用方式,或者说是发起服务调用的方式,虽然比起客户端stub存根的方式,代码稍多,但是这种方式统一,不需要生产stub存根代码,解决了客户端有很多类的问题。如果读者对这些代码进一步封装,我想调用方式很简单,只需要传递相关参数,这更好地说明了服务调用的优势。而且这种方式更加简单明了,一看便知具体含义。而不需要弄得stub类的一些机制。
5 axis2与spring集成
我们选择的版本是 axis2-1.4 + spring2.5 + eclipse8.0 + tomcat 6.0。
我们以前都是把从官网上下载的war包考到tomcat的webapps下,现在我们自己建一个web项目 。
5.1、建工程
首先建立一个web工程,名字叫AxisSpring,
5.2、拷贝jar包
把相应的axis2的jar文件考到WEB-INF的lib下 ,Spring 的jar拷贝到WEB-INF的lib下 。
5.3、 项目结构说明
在项目的WebContent下的目录结构要和以前用war包是的目录结构一样(否则可能就要报 错了)
目录结构如图所示:
5.4、建包
在src下建立package sample.service
5.5、建立接口与实现类
用于提供服务
package sample.service;
/**
* 定义服务接口
*/
public interface ServiceServer {
//定义服务方法
public String sayHello(String name);
public String sayHello2(User user);
}
实现类:
package sample.service;
public class ServiceServerImpl implements ServiceServer {
public String sayHello(String name) {
User user = new User("1", "2");
System.out.println(user.getUsername() + ": " + user.getPassword() );
System.out.println("-----------" + name);
return "hello, "+name;
}
public String sayHello2(User user) {
System.out.println(user.getUsername() + ": " + user.getPassword() );
return "hello";
}
}
5.6、建立spring配置文件
在src下建立applicationContext.xml文件 。 配置如下
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
5.7、增加axis2的配置
在WebContent/WEB-INF/services/目录下建立目录HelloWorld (这个名字可以随便取)
然后建立在其下META-INF目录,然后再在其目录下建立services.xml
目录结构如下
services.xml的内容如下:
web service
org.apache.axis2.extensions.spring.receivers.SpringServletContextObjectSupplier
SayHelloService
5.8、配置web.xml
内容如下:
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
AxisServlet org.apache.axis2.transport.http.AxisServlet
1
AxisServlet
/services/*
contextConfigLocation
classpath*:applicationContext.xml
org.springframework.web.context.ContextLoaderListener
9、启动tomcat 在浏览器中输入http://localhost:8080/WebService/services/listServices
可以看到上面的内容说明我们的服务已经发布成功了
6 axis2使用总结
axis2是一个web service框架,以下是使用中的一些总结:
1、要传递的对象首先必须实现serializable接口
2、axis2不支持方法重载。
在对外发布的接口中不能使用方法重载,
如果你写了多个重名的方法,在该service中只会注册一个。
解决方法:更改成不同的方法名
3、axis2不支持事务。
数据库增删改查一般都需要事务处理的,但是在对外发布的接口中是不能配置事务的。
解决方法:或者写一个代理类或者直接在dao中进行事务管理。
4、AXIS2 1.4.1不支持java.util.Date type
Time portion of java.util.Date is missing from SOAP response in Axis2 1.5
瞧瞧axis2 的这些个bug,使用起来太不方便了。
虽然Apache的官方网站的bug页上有解决方案,但是我把DateServuce。aar文件考下来后仍然报相同的错误:
Axis2 1.5只能返回日期部分,时间部分丢失了!
解决方法:把Date类型都改成String类型的,这样是最安全的,但可能跟要求不符,应该不能算是一个好的解决方案吧。
5、axis2在java中不支持二进制对象的传递如inputSream,。
解决方法:将二进制流转换为只能传递byte[]。
6、axis2不能传递list、Map 类型的数据集合。
解决方法:将list转换成数组类型。
附件1::MyEclipse6.5中安装axis2插件
目前最新的Eclipse版本中自带了axis插件,但很多童鞋还在使用老版本如MyEclipse6.5,并没有axis 插件。最简单的插件安装方式是把下载的插件解压缩到plugins文件夹中,但是,如果安装的插件比较多,以后就不方便拆卸了。所以接下来我们使用links方式安装。
(1)下载 Axis Eclipse plug-in(代码生成工具和打包工具)下载:
http://archive.apache.org/dist/ws/axis2/tools/1_4/axis2-eclipse-codegen-wizard-1.4.zip
http://archive.apache.org/dist/ws/axis2/tools/1_4/axis2-eclipse-service-archiver-wizard-1.4.zip
(2)在myeclipse的目录下(例如:我的是C:\java\MyEclipse_6.5 ) 新建Axis2目录
(3)在Axis2 下建立eclipse 目录 并在eclipse下建立features和plugins 目录
(4)将下载的两个压缩文件解压后,复制到刚刚建好的plugins目录下
(5) 在C:\java\MyEclipse_6.5\eclipse\links目录下新建axis2-1.4.1.link文件,并在里面填写axis2插件路径(要找到Axis2目录,例如我的是:path= C:/java/MyEclipse_6.5/Axis2)
(6)完成后重启myeclipse,在file->new->other中可看到Axis2 Wizards,axis2插件安装成功。