前言:xfire、spring都是比较流行的技术,这里就不再赘述他们各自的优点;本文着重介绍xfire和spring的整合,不会做太深入的探究。

服务端

1. web.xml配置

spring配置部分:contextConfigLocation定义配置文件路径,可以指定全局的配置文件路径。

<!-- spring配置 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/xfire-servlet.xml
</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- spring配置 -->

XFire配置部分:xfire配置1使用spring的DispatcherServlet类来作为xfire的处理类,DispatcherServlet的配置文件名默认为[servletname]-servlet,位于WEB-INF目录下,也可以通过namespace参数来指定或者通过contextConfigLocation参数自定义配置文档的位置;这种配置方式只能通过服务名.ws的方式访问,方便隐藏其它的服务接口;xfire配置2使用xfire的XFireSpringServlet类来作为xfire的处理类,这种配置方式可以直接通过接口名访问,也可以访问所有的服务接口。

<!-- XFire 配置 1 使用spring的DispatcherServlet作为xfire的处理类,好处是可以自定义服务的名称并隐藏所有提供的其它接口,客户端只能通过服务名.ws的方式访问-->
<servlet>
<!-- 配合Spring容器中XFire一起工作的Servlet -->
<servlet-name>xfireServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<!-- WebApplicationContext命名空间,默认值是[servlet-name]-servlet,对应DispatcherServlet的定义档名称,位于
/WEB-INF下,也可以通过contextConfigLocation参数自定义位置 -->
<param-name>namespace</param-name>
<param-value>xfire-servlet</param-value>
</init-param> <!-- 通过contextConfigLocation参数自定义位置
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/xfire-servlet.xml
</param-value>
</init-param>--> </servlet>
<servlet-mapping>
<servlet-name>xfireServlet</servlet-name>
<!-- 在这个URI下开放Web Service服务 -->
<url-pattern>*.ws</url-pattern>
</servlet-mapping>
<!-- XFire 配置1 --> <!-- XFire 配置2 使用xfire的XFireSpringServlet作为xfire的处理类,可以直接使用接口类名来访问开放的服务,也可以查看所有开发的服务接口 -->
<servlet>
<!-- 配合Spring容器中XFire一起工作的Servlet -->
<servlet-name>xfireServlet2</servlet-name>
<servlet-class>org.codehaus.xfire.spring.XFireSpringServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>xfireServlet2</servlet-name>
<!-- 在这个URI下开放Web Service服务 -->
<url-pattern>/service/*</url-pattern>
</servlet-mapping>
<!-- XFire 配置2 -->

2.xfire-servlet配置

首先需要引入xfire.xml的配置;第二部分用来定义访问的服务名,若使用XFireSpringServlet作为servlet时无需此配置,直接通过接口名访问;第三部分我们通过XFireExporter将业务类导出为Web Service,对于任何导出器,我们都需要引入XFire环境,即serviceFactory和xfire,这是标准的配置。ServiceFactory是XFire的核心类,它可以将一个POJO生成为一个Web Service。在本实例中,我们通过定义一个baseWebService,其余的webService配置都将该bean作为父bean,这样可以简化Spring的配置,不需要多次引入serviceFactory和xfire,这其中的inHandlers参数用来定义xfire的SOAP的截取处理类,可以添加多个,用来完成一些安全验证等功能;最后一部分用来定义业务接口,他们都需要将baseWebService作为父bean。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans> <import resource="classpath:org/codehaus/xfire/spring/xfire.xml" /> <!-- 定义访问的url 使用XFireSpringServlet作为servlet时无需此配置 -->
<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="urlMap">
<map> <entry key="/helloworld.ws">
<ref bean="HelloWorldService" />
</entry> </map>
</property>
</bean> <!-- 使用XFire导出器 我们通过XFireExporter将业务类导出为Web Service,对于任何导出器,
我们都需要引入XFire环境,即serviceFactory和xfire,这是标准的配置。ServiceFactory是
XFire的核心类,它可以将一个POJO生成为一个Web Service。在本实例中,我们通过定义一个
baseWebService,其余的webService配置都将该bean作为父bean,这样可以简化Spring的配置,
不需要多次引入serviceFactory和xfire。-->
<bean id="baseWebService" class="org.codehaus.xfire.spring.remoting.XFireExporter"
lazy-init="false" abstract="true">
<!-- 引用xfire.xml中定义的工厂 -->
<property name="serviceFactory" ref="xfire.serviceFactory" />
<!-- 引用xfire.xml中的xfire实例 -->
<property name="xfire" ref="xfire" />
<!-- 安全验证 -->
<property name="inHandlers" ref="AuthenticationHandler"></property>
</bean> <!-- 安全认证 -->
<bean id="AuthenticationHandler" class="com.AuthenticationHandler"></bean> <bean id="HelloWorldServiceImpl" class="com.impl.HelloWorldServiceImp" />
<bean id="HelloWorldService" parent="baseWebService">
<!-- 业务服务bean -->
<property name="serviceBean" ref="HelloWorldServiceImpl" />
<!-- 业务服务bean的窄接口类 -->
<property name="serviceClass" value="com.HelloWorldService" />
</bean> </beans>

3.AuthenticationHandler安全验证类

webservice是一种开放的服务的,但有时候我们需要控制用户的访问,这里我们采用handler的方式来截取访问的SOAP报文来判断其中是否包含验证信息,这样就可以完成一个简单的安全校验;继承AbstractHandler类实现invoke方法,通过MessageContext获取请求的报文信息头中是否包含我们需要的用户名、密码等验证信息,相应的我们就需要就客户端调用时放入这些信息,客户端验证类ClientPasswordHandler我们在下面的客户端部分介绍。

public class AuthenticationHandler extends AbstractHandler {

    public void invoke(MessageContext cfx) throws Exception {
if (cfx.getInMessage().getHeader() == null) {// 是否有验证信息
throw new org.codehaus.xfire.fault.XFireFault("请求必须包含验证信息",
org.codehaus.xfire.fault.XFireFault.SENDER);
}
Element token = cfx.getInMessage().getHeader()
.getChild("AuthenticationToken");// AuthenticationToken为自定义元素值
if (token == null) {
throw new org.codehaus.xfire.fault.XFireFault("请求必须包含身份验证信息",
org.codehaus.xfire.fault.XFireFault.SENDER);
}
String username = token.getChild("Username").getValue();
String password = token.getChild("Password").getValue();
try {
// 进行身份验证 ,只有test@test的用户为授权用户
if (username.equals("test") && password.equals("test"))
System.out.println("身份验证通过");
else
throw new Exception();
} catch (Exception e) {
throw new org.codehaus.xfire.fault.XFireFault("非法的用户名和密码",
org.codehaus.xfire.fault.XFireFault.SENDER);
}
} }

4、完整这些配置和接口的类的开发后服务端的工作就完成了,在tomcat中运行这个demo,在浏览器中输入对应的url当出现“Invalid SOAP request.”字样是表示接口可以正常访问了,在url后添加?wsdl可以获得更详细的接口信息,如下图:

客户端

1.ClientPasswordHandler安全验证类

客户端安全验证类也要继承AbstractHandler类实现invoke方法,以Element的方式构建验证信息添加到SOAP的报文头信息中,然后添加这个类到客户端访问的服务接口的请求中,就会在被服务端的AuthenticationHandler类截获完成安全验证。

public class ClientPasswordHandler extends AbstractHandler {
private String username = null;
private String password = null; public String getUsername() {
return username;
} public void setUsername(String username) {
this.username = username;
} public String getPassword() {
return password;
} public void setPassword(String password) {
this.password = password;
} public ClientPasswordHandler(String username, String password) {
this.username = username;
this.password = password;
} public void invoke(MessageContext context) throws Exception {
// 为SOAP Header构造验证信息
Element el = new Element("header");//标头
context.getOutMessage().setHeader(el);
Element auth = new Element("AuthenticationToken");//自定义元素
Element username_el = new Element("Username");
username_el.addContent(username);
Element password_el = new Element("Password");
password_el.addContent(password);
auth.addContent(username_el);
auth.addContent(password_el);
el.addContent(auth);
} }

2、访问服务端接口类

GetServiceBean类用来获取服务端接口对象,添加客户端验证类;ClientTest通过调用GetServiceBean获取服务端接口对象,然后就可以像使用本地类一样调用其中的方法了(如下图),这里一个显而易见的要求就是客户端要保留服务端的接口类、对象类才能完成调用。

public class GetServiceBean {

    private static XFireProxyFactory factory = new XFireProxyFactory();

    public static Object getBean(String serviceUrl, Class<?> serviceClass)
throws MalformedURLException {
Service service = new ObjectServiceFactory().create(serviceClass);
Object object = factory.create(service, serviceUrl);
Client client = ((XFireProxy) Proxy.getInvocationHandler(object))
.getClient(); // 获取访问服务的客户端
client.addOutHandler(new ClientPasswordHandler("test", "test"));// 添加客户端验证类
return object;
} }
public class ClientTest {

    public static void main(String[] args) throws Exception {
HelloWorldService service = (HelloWorldService) GetServiceBean.getBean(
"http://localhost/xfireserver/helloworld.ws",
HelloWorldService.class); System.out.println(service.hello("小明"));
Person person = new Person();
person = service.getPerson();
System.out
.println("id:" + person.getId() + " name:" + person.getName());
List<Person> students = new ArrayList<Person>();
students = service.getList();
for (int i = 0; i < students.size(); i++) {
Person per = students.get(i);
System.out.println("id:" + per.getId() + " name:" + per.getName());
}
} }

结语:个人理解会有偏驳和不对的地方,欢迎大家批评指正!

demo下载地址:http://pan.baidu.com/s/1eQxRjeM

xfire集成spring构建webservice的更多相关文章

  1. CXF集成Spring实现webservice的发布与请求

    CXF集成Spring实现webservice的发布(服务端) 目录结构: 主要代码: package com.cxf.spring.pojo; public class User { int id ...

  2. 一个CXF集成SPRING的WEBSERVICE完整实例

    1 首先准备以下JAR包 activation.jar commons-logging-1.1.1.jar cxf-2.5.6.jar jaxb-api-2.2.1.jar jaxb-impl-2.1 ...

  3. CXF集成spring做webservice接口

    一 . cxf 的jar包 1.cxf-2.3.3.jar 2.wsdl4j-1.6.2.jar 3.wss4j-1.5.11.jar 4.wstx-asl-3.2.0.jar 5.XmlSchema ...

  4. 使用XFire+Spring构建Web Service

    XFire是与Axis 2并列的新一代Web Service框架,通过提供简单的API支持Web Service各项标准协议,帮助你方便快速地开发Web Service应用. 相 对于Axis来说,目 ...

  5. 使用XFire+Spring构建Web Service(一)——helloWorld篇

    转自:http://www.blogjava.net/amigoxie/archive/2007/09/26/148207.html原文出处:http://tech.it168.com/j/2007- ...

  6. 使用CXF与Spring集成实现RESTFul WebService

    以下引用与网络中!!!     一种软件架构风格,设计风格而不是标准,只是提供了一组设计原则和约束条件.它主要用于客户端和服务器交互类的软件.基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存 ...

  7. spring boot / cloud (三) 集成springfox-swagger2构建在线API文档

    spring boot / cloud (三) 集成springfox-swagger2构建在线API文档 前言 不能同步更新API文档会有什么问题? 理想情况下,为所开发的服务编写接口文档,能提高与 ...

  8. spring集成cxf实现webservice接口功能

    由于cxf的web项目已经集成了Spring,所以cxf的服务类都是在spring的配置文件中完成的.以下是步骤:第一步:建立一个web项目.第二步:准备所有jar包.将cxf_home\lib项目下 ...

  9. Spring集成CXF发布WebService并在客户端调用

    Spring集成CXF发布WebService 1.导入jar包 因为官方下载的包里面有其他版本的sprring包,全导入会产生版本冲突,所以去掉spring的部分,然后在项目根目录下新建了一个CXF ...

随机推荐

  1. 2012在数据库技术会议上的讲话PPT打包

     2012技术大会演讲PPT打包  DB2 Overview of Disaster Recovery Options.pdf: http://www.t00y.com/file/76767890 ...

  2. 【POJ3612】【USACO 2007 Nov Gold】 1.Telephone Wire 动态调节

    意甲冠军: 一些树高给出.行一种操作:把某棵树增高h,花费为h*h. 操作完毕后连线,两棵树间花费为高度差*定值c. 求两种花费加和最小值. 题解: 跟NOIP2014 D1T3非常像. 暴力动规是O ...

  3. 使用WireShark简单分析ICMP报文

    ICMP协议介绍 1.ICMP是"Internet Control Message Protocol"(Internet控制消息协议)的缩写. 它是TCP/IP协议族的一个子协议. ...

  4. C++输出IP地址段内的合法地址

    近半年的Intel实习生活快要结束了.马上要找工作了,这段时间打算把以前的知识复习复习,顺便在这里记录一下.这是当时去Intel面试的时候,面试官问的一道题.当时因为时间关系,只让我提供一个思路,并没 ...

  5. Android Studio Debug

    小米4usb调试怎么打开?miui6进入开发者模式想要打开USB调试首先开启开发者模式.过去在MIUI V5版本时,小米手机开启开发者模式的方法是连续点击Anroid版本号.不过最新上市的小米4都搭载 ...

  6. PHP微信SDK——Zebra-Wechat

    Zebra-Wechat 微信SDK 眼下处于开发状态,眼下实现了下面功能: 接收微信server推送信息,对推送信息类型进行识别 微信APIclient封装(用户管理.用户组管理.客服管理.自己定义 ...

  7. uva 1556 - Disk Tree(特里)

    题目连接:uva 1556 - Disk Tree 题目大意:给出N个文件夹关系,然后依照字典序输出整个文件文件夹. 解题思路:以每一个文件夹名作为字符建立一个字典树就可以,每一个节点的关系能够用ma ...

  8. Linux netstat订购具体解释

    简单介绍 Netstat 命令用于显示各种网络相关信息,如网络连接,路由表,接口状态 (Interface Statistics).masquerade 连接.多播成员 (Multicast Memb ...

  9. 有一定基础的 C++ 学习者该怎样学习 Windows 编程?

    人的心理有个奇异的特性:一项知识一旦学会之后,学习过程中面临的困惑和不解非常快就会忘得干干净净,似乎一切都是自然而然,本来就该这种.因此,关于「怎样入门」这类问题,找顶尖高手来回答,未必能比一个刚入门 ...

  10. poj2431 Expedition

    直接代码... #include<string.h> #include<stdio.h> #include<queue> #include<iostream& ...