web service

web service技术


创建日期:2011-2-22


1 web service技术
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,增加如下配置。
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4"
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">

<!-- 设置Axis2的servlet -->
<servlet>
<servlet-name>AxisServlet</servlet-name>
<servlet-class>org.apache.axis2.transport.http.AxisServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>AxisServlet</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>

<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>


四、写一个简单的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
第一种
<?xml version="1.0" encoding="UTF-8"?>
<service name="myService">
<Description>Please Type your service description here</Description>
<messageReceivers>
<messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-only"
class="org.apache.axis2.rpc.receivers.RPCInOnlyMessageReceiver" />
<messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-out"
class="org.apache.axis2.rpc.receivers.RPCMessageReceiver" />
</messageReceivers>
<parameter name="ServiceClass" locked="false"> com.lxit.study.ws.service.MyWebService </parameter>
</service>

第二种
<?xml version="1.0" encoding="UTF-8"?>
<serviceGroup>
<service name="myService">
<description>my Web Service demo</description>
<messageReceivers>
<messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-out"
class="org.apache.axis2.rpc.receivers.RPCMessageReceiver" />
<messageReceiver
mep="http://www.w3.org/2004/08/wsdl/in-only"
class="org.apache.axis2.rpc.receivers.RPCInOnlyMessageReceiver" />
</messageReceivers>
<parameter name="ServiceClass">
com.lxit.study.ws.service.MyWebService
</parameter>
</service>
</serviceGroup>
通常使用第一种就可以了,也可以使用第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文件 。 配置如下
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
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">

<bean id="SayHelloService" class="sample.service.ServiceServerImpl" />

</beans>

5.7、增加axis2的配置
在WebContent/WEB-INF/services/目录下建立目录HelloWorld (这个名字可以随便取)
然后建立在其下META-INF目录,然后再在其目录下建立services.xml
目录结构如下



services.xml的内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<service name="HelloWorld">
<description>web service</description>
<parameter name="ServiceObjectSupplier">
org.apache.axis2.extensions.spring.receivers.SpringServletContextObjectSupplier
</parameter>
<parameter name="SpringBeanName">SayHelloService</parameter>
<!--SpringBeanName名字是固定的,不能改. SayHelloService是spring中注册的实现类的ID-->

<operation name="sayHello">
<messageReceiver class="org.apache.axis2.rpc.receivers.RPCMessageReceiver" />
</operation>

</service>


5.8、配置web.xml
内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
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">

<!-- 注册axis2的servlet -->
<servlet>
<servlet-name>AxisServlet</servlet-name> <servlet-class>org.apache.axis2.transport.http.AxisServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
<servlet-name>AxisServlet</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>

<!-- 加载spring的配置文件 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:applicationContext.xml</param-value>
</context-param>

<!-- 增加spring监听器 -->
<listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
</web-app>


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插件安装成功。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值