前言: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. 策略模式设计模式(Strategy)摘录

    23种子GOF设计模式一般分为三类:创建模式.结构模型.行为模式. 创建模式抽象的实例.一个系统独立于怎样创建.组合和表示它的那些对象.一个类创建型模式使用继承改变被实例化的类,而一个对象创建型模式将 ...

  2. android 简单的登录

    一直都知道WEB通过登录后session拿着回答,如今,安卓不知道怎么弄的. 研究了一下,它记录.直接在代码: server结束: index.jsp <%@page import=" ...

  3. Linux内核分析(二)----内核模块简介|简单内核模块实现

    原文:Linux内核分析(二)----内核模块简介|简单内核模块实现 Linux内核分析(二) 昨天我们开始了内核的分析,网上有很多人是用用源码直接分析,这样造成的问题是,大家觉得很枯燥很难理解,从某 ...

  4. FutureTask解析(转)

    站在使用者的角度,future是一个经常在多线程环境下使用的Runnable,使用它的好处有两个:1. 线程执行结果带有返回值2. 提供了一个线程超时的功能,超过超时时间抛出异常后返回. 那,怎么实现 ...

  5. 架构设计之设计模式 (一) 适配器(Adapter)---提高复用性

    简介 简介是为了描述一下该模式是干嘛用的,为了让不了解该模式的人看了之后也有一些新的认识. 本文章分为两部分,第一部分主要介绍适配器模式:第二部分介绍该模式与相近模式的异同. 下午一直在讨论设计模式, ...

  6. 一个用于每一天JavaScript示例-SVG中间javaScript画廊

    <?xml version="1.0" standalone="no"? > <!DOCTYPE svg PUBLIC "-//W3 ...

  7. DevExpress Report的简单应用

    原文:DevExpress Report的简单应用 创建一个简单的WPF应用程序包含一个报告的过程中,使用Microsoft®Visual Studio®中.您将学习如何添加一个静态文本一份报告,为您 ...

  8. [Shell]输入參数

    获取shell脚本的输入參数,而且推断得到的參数. #!/bin/bash #title: testPT.sh #atuhor: orangleliu #date: 2014-08-08 #desc: ...

  9. Java数据结构与算法(21) - ch09红黑树(RB树)

    红-黑规则1. 每一个节点不是红色的就是黑色的2. 根总是黑色的3. 如果节点是红色的,则它的子节点必须是黑色的:如果节点是黑色的,其子节点不是必须为红色.4. 从根到叶节点或空子节点的每条路径,必须 ...

  10. ArcEngine下一个TIN生成的轮廓

    太晚了,直接连接的源代码: /// <summary> /// TIN生成等高线 /// </summary> /// <param name="pInterv ...