使用Spring + CXF 发布 Web Service
概念了解: 什么是WebService
- WebService是两个系统的远程调用,使两个系统进行数据交互,如应用:天气预报服务、银行ATM取款、使用邮箱账号登录各网站等。
- WebService之间的调用是跨语言的调用。Java、.Net、php,发送Http请求,使用的数据格式是XML格式。
- webxml.com.cn上面有一些免费的WebService服务,可以进去看看
如何配置:使用Tomcat + Spring + CXF
第一步:配置 Maven 依赖或引入jar包
<!-- lang: xml --> <?xml version="1.0" encoding="UTF-8"?> <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/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>demo.ws</groupId> <artifactId>soap_spring_cxf</artifactId> <version>1.0-SNAPSHOT</version> <packaging>war</packaging> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <spring.version>4.0.5.RELEASE</spring.version> <cxf.version>3.0.0</cxf.version> </properties> <dependencies> <!-- Spring --> <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> <!-- 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> </project>
第二步:写一个 WS 接口及其实现
接口部分:
package com.msun.mr.webService; import java.sql.SQLException; import javax.jws.WebMethod; import javax.jws.WebParam; import javax.jws.WebService; import javax.jws.soap.SOAPBinding; import javax.jws.soap.SOAPBinding.Style; /** * 医嘱服务接口 * * @author ziggo * */ @WebService @SOAPBinding(style = Style.RPC) public interface IGenerateMr { /** * 获取患者的id 信息 * * @param diagName 诊断名称 * @param proportion 医嘱截取比列,传入20~99整数 (传入20时,将获取出现次数大于20%的医嘱) * @param drugCount 医嘱中药品出现的最低个数 5~20 优先满足此参数 * @return * @throws SQLException */ @WebMethod(operationName = "getDoctorAdviceData") public String getDoctorAdviceData(@WebParam(name = "diagName") String diagName,@WebParam(name = "proportion") String proportion, @WebParam(name = "drugCount") String drugCount) ; }
实现部分:
package com.msun.mr.webService.impl; import java.sql.SQLException; import com.msun.mr.ClinicalPathwatGenerator.DoctorOrderInformationGeneration; import com.msun.mr.webService.IGenerateMr; public class GenerateMrImpl implements IGenerateMr { @Override public String getDoctorAdviceData(String diagName, String proportion, String drugCount) { String result = ""; try { result ="接口调用成功啦!!"; } catch (SQLException e) { e.printStackTrace(); } return result; } }
配置spring-mvc.xml
<!-- 配置webservice接口 --> <bean id="generateMrWebService" class="com.msun.mr.webService.impl.GenerateMrImpl"> </bean> <!-- #代表使用spring容器中的类 --> <jaxws:endpoint implementor="#generateMrWebService" address="/generateMrWebService"></jaxws:endpoint>
如果在实现类上添加 Spring 的 org.springframework.stereotype.Component
注解,这样就能被 Spring IOC 容器扫描到,认为它是一个 Spring Bean,可以根据 Bean ID(这里是GenerateMrImpl)来获取 Bean 实例。就不需要配置spring-mvc.xml ,此处我未使用注解,所以配置了spring-mvc.xml文件
第三步:配置 web.xml
<!--========webService CXF ========================================== --> <servlet> <servlet-name>CXFServlet</servlet-name> <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>CXFServlet</servlet-name> <url-pattern>/webservice/*</url-pattern> </servlet-mapping>
所有带有 /
webservice前缀的请求,将会交给被 CXFServlet
进行处理,也就是处理 WS 请求了。
第四步:配置 Spring(实现类GenerateMrImpl 若未使用Component
注解,可省略)
配置 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:aop="http://www.springframework.org/schema/aop" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" 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://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd"> ........ <!-- <context:component-scan base-package="com.msun.mr"/> --> ........ </beans>
该项目实现类未使用Component
注解,采用配置xml文件方式,见第二步,所以这一块注释掉了
第五步:配置 CXF
我们在之前配置好的spring-mvc.xml 文件中,其中<bean>用于加载实例
<!-- 配置webservice接口 --> <bean id="generateMrWebService" class="com.msun.mr.webService.impl.GenerateMrImpl"> </bean>
<jaxws>用于集成 CXF ,在spring中继承CXF有多钟方式,此处使用 CXF 提供的 endpoint
方式,更为方便
<!-- #代表使用spring容器中的类 --> <jaxws:endpoint implementor="#generateMrWebService" address="/generateMrWebService"></jaxws:endpoint>
这里的 implementor
属性值是 #
generateMrWebService,这是 CXF 特有的简写方式,并非是 Spring 的规范,意思是通过 Spring 的 Bean ID 获取 Bean 实例。注意address属性,以后接口调用时用到的地址。
除了jaxws:endpoint方式外,还有simple:server
与 jaxws:server,相比下jaxws:endpoint最为简单,这里不再深入探讨。
第六步:启动 Tomcat
通过以下地址可访问WSDL:http://127.0.0.1:8081/ClinicalPathwayTool/webservice/generateMrWebService?wsdl
结构构成:IP:端口号/项目名称/web文件中配置的前缀请求/spring mvc文件中配置的address属性?wsdl
现在已经成功地通过 CXF 对外发布了 WS,下面要做的事情就是用 WS 客户端来调用这些 endpoint 了。
第七步:调用web service
调用方式分为很多种,介绍一种网络请求方式:
package com.msun.mr.webService; import org.ksoap2.SoapEnvelope; import org.ksoap2.serialization.SoapObject; import org.ksoap2.serialization.SoapSerializationEnvelope; import org.ksoap2.transport.HttpTransportSE; public class WebServiceTest { // 调用接口测试 public static void main(String[] args) { try { String SAVENameSpace = "http://webService.mr.msun.com/"; String SAVESOAP_ACTION = ""; String SAVEMethodName = "getDoctorAdviceData"; SoapObject soapObject = new SoapObject(SAVENameSpace, SAVEMethodName); soapObject.addProperty("diagName", "阑尾炎"); soapObject.addProperty("proportion", "60"); soapObject.addProperty("drugCount", "1"); SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11); // 版本 envelope.bodyOut = soapObject; envelope.setOutputSoapObject(soapObject); HttpTransportSE trans = new HttpTransportSE( "http://127.0.0.1:8081/ClinicalPathwayTool/webservice/generateMrWebService?wsdl", 600000); trans.call(SAVESOAP_ACTION, envelope); System.out.println(envelope.getResponse().toString()); } catch (Exception e) { e.printStackTrace(); } } }
SAVENameSpace 对应xml中的namespace
SAVEMethodName 对应xml中的调用的方法name
soapObject为参数项,可不填写