热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

【转载】使用CXF开发WebService

CXF相关的文章看了很多,但是这篇是讲解的最清楚的!原文链接:http:my.oschina.nethuangyongblog286439

CXF相关的文章看了很多,但是这篇是讲解的最清楚的!

原文链接:http://my.oschina.net/huangyong/blog/286439#OSC_h1_3

以下是文章的部分内容,仅供备忘!

 

在 Web 容器中使用 Spring + CXF 发布 WS

Tomcat + Spring + CXF,这个场景应该更加接近我们的实际工作情况,开发过程也是非常自然。

第一步:配置 Maven 依赖



<project xmlns&#61;"http://maven.apache.org/POM/4.0.0" xmlns:xsi&#61;"http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation&#61;"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0modelVersion> <groupId>demo.wsgroupId> <artifactId>soap_spring_cxfartifactId> <version>1.0-SNAPSHOTversion> <packaging>warpackaging> <properties> <project.build.sourceEncoding>UTF-8project.build.sourceEncoding> <spring.version>4.0.5.RELEASEspring.version> <cxf.version>3.0.0cxf.version> properties> <dependencies> <dependency> <groupId>org.springframeworkgroupId> <artifactId>spring-contextartifactId> <version>${spring.version}version> dependency> <dependency> <groupId>org.springframeworkgroupId> <artifactId>spring-webartifactId> <version>${spring.version}version> dependency> <dependency> <groupId>org.apache.cxfgroupId> <artifactId>cxf-rt-frontend-jaxwsartifactId> <version>${cxf.version}version> dependency> <dependency> <groupId>org.apache.cxfgroupId> <artifactId>cxf-rt-transports-httpartifactId> <version>${cxf.version}version> dependency> dependencies> project>

第二步&#xff1a;写一个 WS 接口及其实现

接口部分&#xff1a;


package demo.ws.soap_spring_cxf;import javax.jws.WebService;&#64;WebService
public interface HelloService { String say(String name); }

实现部分&#xff1a;


package demo.ws.soap_spring_cxf;import javax.jws.WebService;
import org.springframework.stereotype.Component;&#64;WebService
&#64;Component public class HelloServiceImpl implements HelloService { public String say(String name) { return "hello " &#43; name; } }

需要在实现类上添加 Spring 的 org.springframework.stereotype.Component 注解&#xff0c;这样才能被 Spring IOC 容器扫描到&#xff0c;认为它是一个 Spring Bean&#xff0c;可以根据 Bean ID&#xff08;这里是 helloServiceImpl&#xff09;来获取 Bean 实例。

第三步&#xff1a;配置 web.xml



<web-app xmlns&#61;"http://java.sun.com/xml/ns/javaee" xmlns:xsi&#61;"http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation&#61;"http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version&#61;"3.0"> <context-param> <param-name>contextConfigLocationparam-name> <param-value>classpath:spring.xmlparam-value> context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListenerlistener-class> listener> <servlet> <servlet-name>cxfservlet-name> <servlet-class>org.apache.cxf.transport.servlet.CXFServletservlet-class> servlet> <servlet-mapping> <servlet-name>cxfservlet-name> <url-pattern>/ws/*url-pattern> servlet-mapping> web-app>

所有带有 /ws 前缀的请求&#xff0c;将会交给被 CXFServlet 进行处理&#xff0c;也就是处理 WS 请求了。目前主要使用了 Spring IOC 的特性&#xff0c;利用了 ContextLoaderListener 加载 Spring 配置文件&#xff0c;即这里定义的 spring.xml 文件。

第四步&#xff1a;配置 Spring

配置 spring.xml&#xff1a;



<beans xmlns&#61;"http://www.springframework.org/schema/beans" xmlns:xsi&#61;"http://www.w3.org/2001/XMLSchema-instance" xmlns:context&#61;"http://www.springframework.org/schema/context" xsi:schemaLocation&#61;"http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"> <context:component-scan base-package&#61;"demo.ws"/> <import resource&#61;"spring-cxf.xml"/> beans>

以上配置做了两件事情&#xff1a;

  1. 定义 IOC 容器扫描路径&#xff0c;即这里定义的 demo.ws&#xff0c;在这个包下面&#xff08;包括所有子包&#xff09;凡是带有 Component 的类都会扫描到 Spring IOC 容器中。
  2. 引入 spring-cxf.xml 文件&#xff0c;用于编写 CXF 相关配置。将配置文件分离&#xff0c;是一种很好的开发方式。

第五步&#xff1a;配置 CXF

配置 spring-cxf.xml&#xff1a;



<beans xmlns&#61;"http://www.springframework.org/schema/beans" xmlns:xsi&#61;"http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxws&#61;"http://cxf.apache.org/jaxws" xsi:schemaLocation&#61;"http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd"> <jaxws:server id&#61;"helloService" address&#61;"/soap/hello"> <jaxws:serviceBean> <ref bean&#61;"helloServiceImpl"/> jaxws:serviceBean> jaxws:server> beans>

通过 CXF 提供的 Spring 命名空间&#xff0c;即 jaxws:server&#xff0c;来发布 WS。其中&#xff0c;最重要的是 address 属性&#xff0c;以及通过 jaxws:serviceBean 配置的 Spring Bean。

可见&#xff0c;在 Spring 中集成 CXF 比想象的更加简单&#xff0c;此外&#xff0c;还有一种更简单的配置方法&#xff0c;那就是使用 CXF 提供的 endpoint 方式&#xff0c;配置如下&#xff1a;



<beans xmlns&#61;"http://www.springframework.org/schema/beans" xmlns:xsi&#61;"http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxws&#61;"http://cxf.apache.org/jaxws" xsi:schemaLocation&#61;"http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd"> <jaxws:endpoint id&#61;"helloService" implementor&#61;"#helloServiceImpl" address&#61;"/soap/hello"/> beans>

使用 jaxws:endpoint 可以简化 WS 发布的配置&#xff0c;与 jaxws:server 相比&#xff0c;确实是一种进步。

注意&#xff1a;这里的 implementor 属性值是 #helloServiceImpl&#xff0c;这是 CXF 特有的简写方式&#xff0c;并非是 Spring 的规范&#xff0c;意思是通过 Spring 的 Bean ID 获取 Bean 实例。

同样&#xff0c;也可以在 Spring 中使用 simple 方式来发布 WS&#xff0c;配置如下&#xff1a;



<beans xmlns&#61;"http://www.springframework.org/schema/beans" xmlns:xsi&#61;"http://www.w3.org/2001/XMLSchema-instance" xmlns:simple&#61;"http://cxf.apache.org/simple" xsi:schemaLocation&#61;"http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://cxf.apache.org/simple http://cxf.apache.org/schemas/simple.xsd"> <simple:server id&#61;"helloService" serviceClass&#61;"#helloService" address&#61;"/soap/hello"> <simple:serviceBean> <ref bean&#61;"#helloServiceImpl"/> simple:serviceBean> simple:server> beans>

可见&#xff0c;simple:server 与 jaxws:server 的配置方式类似&#xff0c;都需要配置一个 serviceBean

比较以上这三种方式&#xff0c;我个人更加喜欢第二种&#xff0c;也就是 endpoint 方式&#xff0c;因为它够简单&#xff01;

至于为什么 CXF 要提供如此之多的 WS 发布方式&#xff1f;我个人认为&#xff0c;CXF 为了满足广大开发者的喜好&#xff0c;也是为了向前兼容&#xff0c;所以这些方案全部保留下来了。

第六步&#xff1a;启动 Tomcat

将应用部署到 Tomcat 中&#xff0c;在浏览器中输入以下地址可进入 CXF 控制台&#xff1a;

http://localhost:8080/ws

CXF 控制台

通过以上过程&#xff0c;可以看出 CXF 完全具备 RI 的易用性&#xff0c;并且与 Spring 有很好的可集成性&#xff0c;而且配置也非常简单。

同样通过这个地址可以查看 WSDL&#xff1a;

http://localhost:8080/ws/soap/hello?wsdl

注意&#xff1a;紧接在 /ws 前缀后面的 /soap/hello&#xff0c;其实是在 address&#61;"/soap/hello" 中配置的。

现在已经成功地通过 CXF 对外发布了 WS&#xff0c;下面要做的事情就是用 WS 客户端来调用这些 endpoint 了。

您可以不再使用 JDK 内置的 WS 客户端&#xff0c;也不必通过 WSDL 打客户端 jar 包&#xff0c;因为 CXF 已经为您提供了多种 WS 客户端解决方案&#xff0c;根据您的口味自行选择吧&#xff01;

4. 关于 CXF 提供的 WS 客户端

方案一&#xff1a;静态代理客户端


package demo.ws.soap_cxf;import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;public class JaxWsClient {public static void main(String[] args) { JaxWsProxyFactoryBean factory &#61; new JaxWsProxyFactoryBean(); factory.setAddress("http://localhost:8080/ws/soap/hello"); factory.setServiceClass(HelloService.class); HelloService helloService &#61; factory.create(HelloService.class); String result &#61; helloService.say("world"); System.out.println(result); } }

这种方案需要自行通过 WSDL 打客户端 jar 包&#xff0c;通过静态代理的方式来调用 WS。这种做法最为原始&#xff0c;下面的方案更有特色。

方案二&#xff1a;动态代理客户端


package demo.ws.soap_cxf;import org.apache.cxf.endpoint.Client;
import org.apache.cxf.jaxws.endpoint.dynamic.JaxWsDynamicClientFactory;public class JaxWsDynamicClient { public static void main(String[] args) { JaxWsDynamicClientFactory factory &#61; JaxWsDynamicClientFactory.newInstance(); Client client &#61; factory.createClient("http://localhost:8080/ws/soap/hello?wsdl"); try { Object[] results &#61; client.invoke("say", "world"); System.out.println(results[0]); } catch (Exception e) { e.printStackTrace(); } } }

这种方案无需通过 WSDL 打客户端 jar 包&#xff0c;底层实际上通过 JDK 的动态代理特性完成的&#xff0c;CXF 实际上做了一个简单的封装。与 JDK 动态客户端不一样的是&#xff0c;此时无需使用 HelloService 接口&#xff0c;可以说是货真价实的 WS 动态客户端。

方案三&#xff1a;通用动态代理客户端


package demo.ws.soap_cxf;import org.apache.cxf.endpoint.Client;
import org.apache.cxf.endpoint.dynamic.DynamicClientFactory;public class DynamicClient { public static void main(String[] args) { DynamicClientFactory factory &#61; DynamicClientFactory.newInstance(); Client client &#61; factory.createClient("http://localhost:8080/ws/soap/hello?wsdl"); try { Object[] results &#61; client.invoke("say", "world"); System.out.println(results[0]); } catch (Exception e) { e.printStackTrace(); } } }

这种方案与“方案三”类似&#xff0c;但不同的是&#xff0c;它不仅用于调用 JAX-WS 方式发布的 WS&#xff0c;也用于使用 simple 方式发布的 WS&#xff0c;更加智能了。

方案四&#xff1a;基于 CXF simple 方式的客户端


package demo.ws.soap_cxf;import org.apache.cxf.frontend.ClientProxyFactoryBean;public class SimpleClient {public static void main(String[] args) { ClientProxyFactoryBean factory &#61; new ClientProxyFactoryBean(); factory.setAddress("http://localhost:8080/ws/soap/hello"); factory.setServiceClass(HelloService.class); HelloService helloService &#61; factory.create(HelloService.class); String result &#61; helloService.say("world"); System.out.println(result); } }

这种方式仅用于调用 simple 方式发布的 WS&#xff0c;不能调用 JAX-WS 方式发布的 WS&#xff0c;这是需要注意的。

方案五&#xff1a;基于 Spring 的客户端

方法一&#xff1a;使用 JaxWsProxyFactoryBean



<beans xmlns&#61;"http://www.springframework.org/schema/beans" xmlns:xsi&#61;"http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation&#61;"http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd"> <bean id&#61;"factoryBean" class&#61;"org.apache.cxf.jaxws.JaxWsProxyFactoryBean"> <property name&#61;"serviceClass" value&#61;"demo.ws.soap_spring_cxf.HelloService"/> <property name&#61;"address" value&#61;"http://localhost:8080/ws/soap/hello"/> bean> <bean id&#61;"helloService" factory-bean&#61;"factoryBean" factory-method&#61;"create"/> beans>

方法二&#xff1a;使用 jaxws:client&#xff08;推荐&#xff09;



<beans xmlns&#61;"http://www.springframework.org/schema/beans" xmlns:xsi&#61;"http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxws&#61;"http://cxf.apache.org/jaxws" xsi:schemaLocation&#61;"http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd"> <jaxws:client id&#61;"helloService" serviceClass&#61;"demo.ws.soap_spring_cxf.HelloService" address&#61;"http://localhost:8080/ws/soap/hello"/> beans>

客户端代码&#xff1a;


package demo.ws.soap_spring_cxf;import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class Client { public static void main(String[] args) { ApplicationContext context &#61; new ClassPathXmlApplicationContext("spring-client.xml"); HelloService helloService &#61; context.getBean("helloService", HelloService.class); String result &#61; helloService.say("world"); System.out.println(result); } }

谈不上那种方案更加优秀&#xff0c;建议根据您的实际场景选择最为合适的方案。

 

Spring &#43; CXF 这对搭档&#xff0c;让发布 WS 更加简单&#xff0c;只需以下四个步骤&#xff1a;

  1. 配置 web.xml
  2. 编写 WS 接口及其实现
  3. 配置 CXF 的 endpoint
  4. 启动 Web 容器

转:https://www.cnblogs.com/postnull/articles/5006833.html



推荐阅读
  • 1.WebServicea.定义:WebService是一种跨编程语言和跨操作系统平台的远程调用技术b.三大技术:XMLXSD,SOAP, ... [详细]
  • 开发笔记:(002)spring容器中bean初始化销毁时执行的方法及其3种实现方式
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了(002)spring容器中bean初始化销毁时执行的方法及其3种实现方式相关的知识,希望对你有一定的参考价值。 ... [详细]
  • Activiti7流程定义开发笔记
    本文介绍了Activiti7流程定义的开发笔记,包括流程定义的概念、使用activiti-explorer和activiti-eclipse-designer进行建模的方式,以及生成流程图的方法。还介绍了流程定义部署的概念和步骤,包括将bpmn和png文件添加部署到activiti数据库中的方法,以及使用ZIP包进行部署的方式。同时还提到了activiti.cfg.xml文件的作用。 ... [详细]
  • Java序列化对象传给PHP的方法及原理解析
    本文介绍了Java序列化对象传给PHP的方法及原理,包括Java对象传递的方式、序列化的方式、PHP中的序列化用法介绍、Java是否能反序列化PHP的数据、Java序列化的原理以及解决Java序列化中的问题。同时还解释了序列化的概念和作用,以及代码执行序列化所需要的权限。最后指出,序列化会将对象实例的所有字段都进行序列化,使得数据能够被表示为实例的序列化数据,但只有能够解释该格式的代码才能够确定数据的内容。 ... [详细]
  • ZSI.generate.Wsdl2PythonError: unsupported local simpleType restriction ... [详细]
  • 在Xamarin XAML语言中如何在页面级别构建ControlTemplate控件模板
    本文介绍了在Xamarin XAML语言中如何在页面级别构建ControlTemplate控件模板的方法和步骤,包括将ResourceDictionary添加到页面中以及在ResourceDictionary中实现模板的构建。通过本文的阅读,读者可以了解到在Xamarin XAML语言中构建控件模板的具体操作步骤和语法形式。 ... [详细]
  • 本文讨论了如何使用Web.Config进行自定义配置节的配置转换。作者提到,他将msbuild设置为详细模式,但转换却忽略了带有替换转换的自定义部分的存在。 ... [详细]
  • 在一对一直播源码使用过程中,有时会出现软键盘切换闪屏问题,就是当切换表情的时候屏幕会跳动,因此要对一对一直播源码表情面板无缝切换进行优化。 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • 本文介绍了Android 7的学习笔记总结,包括最新的移动架构视频、大厂安卓面试真题和项目实战源码讲义。同时还分享了开源的完整内容,并提醒读者在使用FileProvider适配时要注意不同模块的AndroidManfiest.xml中配置的xml文件名必须不同,否则会出现问题。 ... [详细]
  • Servlet多用户登录时HttpSession会话信息覆盖问题的解决方案
    本文讨论了在Servlet多用户登录时可能出现的HttpSession会话信息覆盖问题,并提供了解决方案。通过分析JSESSIONID的作用机制和编码方式,我们可以得出每个HttpSession对象都是通过客户端发送的唯一JSESSIONID来识别的,因此无需担心会话信息被覆盖的问题。需要注意的是,本文讨论的是多个客户端级别上的多用户登录,而非同一个浏览器级别上的多用户登录。 ... [详细]
  • 开发笔记:spring boot项目打成war包部署到服务器的步骤与注意事项
    本文介绍了将spring boot项目打成war包并部署到服务器的步骤与注意事项。通过本文的学习,读者可以了解到如何将spring boot项目打包成war包,并成功地部署到服务器上。 ... [详细]
  • SpringMVC工作流程概述
    SpringMVC工作流程概述 ... [详细]
  • Linux下部署Symfoy2对app/cache和app/logs目录的权限设置,symfoy2logs
    php教程|php手册xml文件php教程-php手册Linux下部署Symfoy2对appcache和applogs目录的权限设置,symfoy2logs黑色记事本源码,vsco ... [详细]
  • http头_http头部注入
    1、http头部注入分析1、原理 ... [详细]
author-avatar
园园哚
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有