WebService之在 Web 容器中使用 Spring + CXF 发布 基于 SOAP 的
Web Service,即“Web 服务”,简写为 WS。那么服务有服务需求方和提供服务方,顾名思义,提供服务方对外发布服务,而服务需求方则调用服务提供方发布的服务。 WS 其实就是建立在 HTTP 协议上实现异构系统通讯的工具,例如:可在 PHP 系统中调用 Java 系统对外发布的 WS,获取 Java 系统中的数据,或者把数据推送到 Java 系统中。
为了让 WS 的开发与使用变得更加简单、更加轻量级,于是出现了另一种风格的 WS,名为?
其中,Jersey 是 Oracle 官方提供的实现,Restlet 是最老牌的实现,RESTEasy 是 JBoss 公司提供的实现,CXF 是 Apache 提供的实现。 可见,CXF 不仅用于开发基于 SOAP 的 WS,同样也适用于开发基于 REST 的 WS,这么好的框架我们怎能错过? 来接下来进入本文的主题: 在 Web 容器中使用 Spring + CXF 发布 WSTomcat + Spring + CXF,接近我们的实际开发 最后总结如下四点,
那么现在围绕着这四点来发布我们自己的WS 第一步,引入jar包,配置Maven pom.xml <project?xmlns="http://maven.apache.org/POM/4.0.0"?xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ??xsi:schemaLocation="http://maven.apache.org/POM/4.0.0?http://maven.apache.org/maven-v4_0_0.xsd"> ??<modelVersion>4.0.0</modelVersion> ??<groupId>com.sunsharing.demo</groupId> ??<artifactId>Spring</artifactId> ??<packaging>war</packaging> ??<version>1.0-SNAPSHOT</version> ??<name>Spring?Maven?Webapp</name> ??<url>http://maven.apache.org</url> ??<properties> ????<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> ????<spring.version>3.1.1.RELEASE</spring.version> ???????<junit.version>4.9.0</junit.version> ??????<cxf.version>3.0.0</cxf.version> ??</properties> ??<dependencies> ??? ????????<dependency> ??????????<groupId>org.springframework</groupId> ??????????<artifactId>spring-context</artifactId> ??????????<version>${spring.version}</version> ????????</dependency> ????????<dependency> ??????????<groupId>org.springframework</groupId> ??????????<artifactId>spring-web</artifactId> ??????????<version>${spring.version}</version> ????????</dependency> ???? ????????<dependency> ??????????<groupId>junit</groupId> ??????????<artifactId>junit</artifactId> ??????????<version>${junit.version}</version> ????????</dependency> ???? ????????<!--?CXF?--> ????????<dependency> ??????????<groupId>org.apache.cxf</groupId> ??????????<artifactId>cxf-rt-frontend-jaxws</artifactId> ??????????<version>${cxf.version}</version> ????????</dependency> ????????<dependency> ??????????<groupId>org.apache.cxf</groupId> ??????????<artifactId>cxf-rt-transports-http</artifactId> ??????????<version>${cxf.version}</version> ????????</dependency> ??</dependencies> ??<build> ????<finalName>Spring</finalName> ????<plugins> ??????<plugin> ????????<groupId>org.mortbay.jetty</groupId> ????????<artifactId>maven-jetty-plugin</artifactId> ????????<version>6.1.5</version> ????????<configuration> ??????????<scanIntervalSeconds>10</scanIntervalSeconds> ??????????<connectors> ????????????<connector?implementation="org.mortbay.jetty.nio.SelectChannelConnector"> ??????????????<port>8088</port> ????????????</connector> ??????????</connectors> ??????????<contextPath>/Spring</contextPath> ????????</configuration> ??????</plugin> ????</plugins> ??</build> </project> 第二步:配置web.xml <?xml?version="1.0"?encoding="UTF-8"?> <web-app?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_3_0.xsd" ?????????version="3.0"> ????<!--?Spring?--> ????<context-param> ????????<param-name>contextConfigLocation</param-name> ????????<param-value>classpath:spring.xml</param-value> ????</context-param> ????<listener> ????????<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> ????</listener> ????<!--?CXF?--> ????<servlet> ????????<servlet-name>cxf</servlet-name> ????????<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class> ????</servlet> ????<servlet-mapping> ????????<servlet-name>cxf</servlet-name> ????????<url-pattern>/ws/*</url-pattern> ????</servlet-mapping> </web-app> 所有带有? 第三步,编写我们自己的WS ????首先是服务接口 ????package?com.sunsharing.rest_cxf; /** ?*?Created?by?nyp?on?2015/2/28. ?*/ import?javax.jws.WebService; @WebService public?interface?HelloService?{ ????String?say(String?name); } ????最后是服务接口的实现 package?com.sunsharing.rest_cxf; /** ?*?Created?by?nyp?on?2015/2/28. ?*/ import?org.springframework.stereotype.Component; import?javax.jws.WebService; @WebService @Component public?class?HelloServiceImpl?implements?HelloService?{ ????public?String?say(String?name)?{ ????????return?"hello?"?+?name; ????} } 值得一提的是引包,Component引入的是spring的包,作用当然是注解注入bean啦,好了我们简单的WS就写好了 第四步,就是配置 CXF? 接着web.xml中配置的spring.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:context="http://www.springframework.org/schema/context" ???????xsi:schemaLocation="http://www.springframework.org/schema/beans ???????http://www.springframework.org/schema/beans/spring-beans-3.1.xsd ???????http://www.springframework.org/schema/context ???????http://www.springframework.org/schema/context/spring-context-3.1.xsd"> ????<context:component-scan?base-package="com.sunsharing.rest_cxf"/> ????<import?resource="spring-cxf.xml"/> </beans> 将配置文件分离,是一种很好的开发方式,到这里我们就就自觉地配置spring-cfx.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:jaxws="http://cxf.apache.org/jaxws" ???????xmlns:simple="http://cxf.apache.org/simple" ???????xsi:schemaLocation="http://www.springframework.org/schema/beans ???????http://www.springframework.org/schema/beans/spring-beans-3.1.xsd ???????http://cxf.apache.org/jaxws ???????http://cxf.apache.org/schemas/jaxws.xsd ???????http://cxf.apache.org/simple ???????http://cxf.apache.org/schemas/simple.xsd"> ????<!--第一种--> ???<!--?<jaxws:server?id="helloService"?address="/soap/hello"> ????????<jaxws:serviceBean> ????????????<ref?bean="helloServiceImpl"/> ????????</jaxws:serviceBean> ????</jaxws:server>--> ????<!--第二种?--> ????<jaxws:endpoint?id="helloService"??implementorClass="#helloServiceImpl"?address="/soap/hello"/> ????<!--第三种--> ????<!--<simple:server?id="helloService"?serviceClass="#helloService"?address="/soap/hello"> ????????<simple:serviceBean> ????????????<ref?bean="#helloServiceImpl"/> ????????</simple:serviceBean> ????</simple:server>--> </beans>
注意:第二种方法中的 implementor 属性值是 #helloServiceImpl,这是 CXF 特有的简写方式,并非是 Spring 的规范,意思是通过 Spring 的 Bean ID 获取 Bean 实例。 (#helloServiceImpl在IDEA中提示红色,并不是报错,不要瞎捣腾)三种方法推荐第二种方法,原因嘛两个字简洁。 说到这里值得一提的就是address="/soap/hello" 结合web.xml中配置的/ws 那么可想像之后的请求是长这个样子的“***/ws/soap/hello” 第五步:启动Web容器 将应用部署到 Tomcat 中,在浏览器中输入以下地址可进入 CXF 控制台: http://localhost:8080/ws 当然我这个地址时报的是404,因为我在发布的项目时添加了项目名 我的实例中输入的地址
http://localhost:8080/Spring/ws 点击上图中的超链接亦或是在地址栏中输入 http://localhost:8080/Spring/ws/soap/hello?wsdl 可见如下页面 到这里,首先得恭喜你现在已经成功地通过 CXF 对外发布了 WS,下面要做的事情就是用 WS 客户端来调用这些 endpoint 了。
关于 CXF 提供的 WS 客户端一共有五个方案 方案一:静态代理客户端 方案二:动态代理客户端 方案三:通用动态代理客户端 方案四:基于 CXF simple 方式的客户端 方案五:基于 Spring 的客户端 这里我们就只讲方案五,更多的方案实现请查阅? Web Service 那点事儿(2)—— 使用 CXF 开发 SOAP 服务本文也是基于这篇文章以及自己部署后总结所写。 首先是配置spring-client.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:jaxws="http://cxf.apache.org/jaxws" ??????xsi:schemaLocation="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"> ?<!--使用?JaxWsProxyFactoryBean--> ?<!--??<bean?id="factoryBean"?class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean"> ???????<property?name="serviceClass"?value="com.sunsharing.rest_cxf.HelloService"/> ???????<property?name="address"?value="http://localhost:8080/Spring/ws/soap/hello"/> ???</bean> ???<bean?id="helloService"?factory-bean="factoryBean"?factory-method="create"/>--> ???<!--使用?jaxws:client(推荐)--> ???<jaxws:client?id="helloService" ?????????????????serviceClass="com.sunsharing.rest_cxf.HelloService" ?????????????????address="http://localhost:8080/Spring/ws/soap/hello"/> </beans> 然后是客服端代码 package?com.sunsharing.rest_cxf; import?org.springframework.context.ApplicationContext; import?org.springframework.context.support.ClassPathXmlApplicationContext; /** ?*?Created?by?nyp?on?2015/2/28. ?*/ public?class?Client?{ ????public?static?void?main(String[]?args)?{ ????????ApplicationContext?context?=?new?ClassPathXmlApplicationContext("spring-client.xml"); ????????HelloService?helloService?=?context.getBean("helloService",?HelloService.class); ????????String?result?=?helloService.say("Spring?world"); ????????System.out.println(result); ????} } 最后想说的是,我们要结合实际选择方案 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |