浅显的实现 望指正..
Webservice的概念
跨平台,跨编程语言,基于xml或json等信息传递的不同系统之间的交互
Webservice的规范
微软的SOAP(REST在第二篇进行介绍介绍)
SOAP指的是(Simple Object Access Protocol),简单对象访问协议,基本的实现原理.
一个系统经过相关的配置,暴露出接口作为服务端,提供站点以供其他系统访问.当一个系统发起SAOP(xml+http)协议的请求对服务端进行请求,服务端返回具有相关信息的xml格式信息,这样在服务端的信息就可以被客户端使用.
Webservice框架介绍
Webservice的框架有很多,Axis,axis2,Xfire,CXF以及JWS,几个框架的区别可自行百度或者可以参考博客,而此处主要想介绍下CXF框架提供的SOAP方式,和Spring 进行整合的方式实怎么样实现的.框架区别参考地址(http://blog.csdn.net/apicescn/article/details/42965785/).
CXF的介绍
毫无意外这又是一个Apache的开源项目,它是提取了celtix和XFire的精华,个人觉得CXF的亮点在于她的简化性和嵌入性,这两点我想在你们接触到CXF之后会有所了解.
CXF对于SOAP的实现
开发先准备
CXF的框架,并且需要配置CXF的环境变量
配置环境变量
CXF_HOME=安装路径
path=%CXF_HOME%/bin
检验:
wsdl2java-v查看版本信息
服务端
1,建立maven项目,对包依赖进行关联
2,引入jar包此处简单小例子只引入
jaxws核心包
http协议包
jetty服务端运行包(和Tomcat服务器或其他服务器只取一)
<dependencies>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxws</artifactId>
<version>3.1.9</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http</artifactId>
<version>3.1.9</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http-jetty</artifactId>
<version>3.1.9</version>
</dependency>
</dependencies>
3,编写服务端的SEI(ServiceEndpoint Interface)接口
服务端暴露接口及其实现,及添加接口WebService注解,接口方法WebMethod注解
packagecom.simple.cxf.service;
importjavax.jws.WebMethod;
importjavax.jws.WebService;
@WebService
publicinterface MobileAddress {
@WebMethod
public String getMobileAdress(StringphoneNumber);
}
4,编写接口实现类
public class MobileAddressImpl implements MobileAddress{
@Override
public StringgetMobileAdress(String phoneNumber) {
System.out.println("服务端在运行...");
return phoneNumber+"是空号";
}
}
5,发布服务
1)获取服务工厂bean
JaxWsServerFactoryBeanserverFactory=new JaxWsServerFactoryBean();
2)设置暴露接口
serverFactory.setServiceClass(接口.class);
serverFactory.setServiceBean(new 接口实现类对象);
serverFactory.setAddress("协议+ip+端口号+上下文(项目名)");
serverFactory.create();//发布项目
importorg.apache.cxf.jaxws.JaxWsServerFactoryBean;
importcom.simple.cxf.service.MobileAddress;
importcom.simple.cxf.service.MobileAddressImpl;
publicclass CxfSoapServer {
public static void main(String args[]){
//创建服务factory
JaxWsServerFactoryBeanjaxWsServerFactoryBean = new JaxWsServerFactoryBean();
//设置
jaxWsServerFactoryBean.setServiceClass(MobileAddress.class);
jaxWsServerFactoryBean.setServiceBean(newMobileAddressImpl());
jaxWsServerFactoryBean.setAddress("http://127.0.0.1:8888/mobile");
jaxWsServerFactoryBean.create();
System.out.println("服务发布成功......");
}
}
6,运行服务端
7,访问网址
客户端
1,根据地址生成,在cmd敲出
wsdl2java -d . -p cn.simple.cxf.client.stubhttp://127.0.0.1:8888/mobile?wsdl
拷贝到客户端中
2,编写客户端
importorg.apache.cxf.jaxws.JaxWsProxyFactoryBean;
importcn.simple.cxf.proxy.MobileAddress;
publicclass CxfSoapClient {
public static void main(String[] args) {
//创建本地代理服务工厂
JaxWsProxyFactoryBeanjaxWsProxyFactoryBean = new JaxWsProxyFactoryBean();
jaxWsProxyFactoryBean.setAddress("http://127.0.0.1:8888/mobile");
jaxWsProxyFactoryBean.setServiceClass(MobileAddress.class);
MobileAddress mobileAddress =(MobileAddress)jaxWsProxyFactoryBean.create();
System.out.println(mobileAddress.getMobileAdress("18399999999"));
}
}
运行客户端
这一过程到底发生什么
1,客户端根据WSDL将数据进行封装成为SOAP协议需要的格式
2,客户端通过SOAP协议将参数发送给服务端
3,服务端根据WSDL协议拿到参数
4,服务端调用方法,并将结果返回
5,响应结果是根据SOAP将数据封装成xml返回
6,客户端拿到响应xml进行解析拿到结果
7,客户端拿到结果自动进行封装成对象
Spring整合CXF
将专业的事情交给专业的人去做.在创建对象这一块,spring的依赖注入具有很大优势.
主要目的是将factorybean的对象交给容器去进行,通过配置来完成..创建对象.这次案例还是采用maven进行包依赖管理.
服务端开发
第一步导入spring包依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>3.2.12.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>3.2.12.RELEASE</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>3.2.12.RELEASE</version>
</dependency>
第二步完成CXF框架包依赖
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxws</artifactId>
<version>3.1.9</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http</artifactId>
<version>3.1.9</version>
</dependency>
第三步完成SEI开发
@WebService
public interface MobileAddress {
@WebMethod
public StringgetMobileAdress(String phoneNumber);
}
public class MobileAddressImpl implements MobileAddress{
@Override
public StringgetMobileAdress(String phoneNumber) {
System.out.println("服务端在运行...");
return phoneNumber+"是空号!";
}
}
第四步配置applicationContext.xml文件
<?xmlversion="1.0" encoding="UTF-8"?>
<beansxmlns="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.1.xsd
http://cxf.apache.org/jaxws
http://cxf.apache.org/schemas/jaxws.xsd">
<import resource="classpath:META-INF/cxf/cxf.xml"/>
<import resource="classpath:META-INF/cxf/cxf-servlet.xml"/>
<jaxws:server address="/mobile"serviceClass="com.simple.cxf.service.MobileAddress">
<jaxws:serviceBean>
<ref bean="mobileAddress"></ref>
</jaxws:serviceBean>
<!-- 拦截器 -->
<jaxws:inInterceptors>
<ref bean="loggingInInterceptor"/>
</jaxws:inInterceptors>
<jaxws:outInterceptors>
<ref bean="loggingOutInterceptor"/>
</jaxws:outInterceptors>
</jaxws:server>
<!-- 输入的日志拦截器-->
<bean id="loggingInInterceptor"class="org.apache.cxf.interceptor.LoggingInInterceptor"/>
<!-- 输出的日志拦截器-->
<bean id="loggingOutInterceptor"class="org.apache.cxf.interceptor.LoggingOutInterceptor"/>
<!-- service -->
<bean id="mobileAddress"class="com.simple.cxf.service.MobileAddressImpl"></bean>
</beans>
第五步配置web.xml
<?xmlversion="1.0" encoding="UTF-8"?>
<web-appxmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee"xsi:schemaLocation="http://java.sun.com/xml/ns/javaeehttp://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID"version="2.5">
<display-name>storemanager</display-name>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<!-- 整合spring容器 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- spring容器位置-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<servlet>
<description>ApacheCXF Endpoint</description>
<display-name>cxf</display-name>
<servlet-name>cxf</servlet-name>
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>cxf</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>
</web-app>
工具生成代理类
启动服务端
页面访问
部署地址加上web.xml中的
在加上applicationContext.xml中的
访问地址是:
http://localhost:8888/cxf_soap_spring_server/services/mobile?wsdl
黑窗口运行生成桩
拷贝到客户端中
客户端
配置applicationContext.xml
<?xmlversion="1.0" encoding="UTF-8"?>
<beansxmlns="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.1.xsd
http://cxf.apache.org/jaxwshttp://cxf.apache.org/schemas/jaxws.xsd">
<jaxws:client id="mobileAddress"serviceClass="cn.simple.cxf_client.stup.MobileAddress"
address="http://localhost:8888/cxf_soap_spring_server/services/mobile">
<!-- 拦截器 -->
<jaxws:inInterceptors>
<ref bean="loggingInInterceptor"/>
</jaxws:inInterceptors>
<jaxws:outInterceptors>
<ref bean="loggingOutInterceptor"/>
</jaxws:outInterceptors>
</jaxws:client>
<!-- 输入的日志拦截器-->
<bean id="loggingInInterceptor"class="org.apache.cxf.interceptor.LoggingInInterceptor"/>
<!-- 输出的日志拦截器-->
<bean id="loggingOutInterceptor"class="org.apache.cxf.interceptor.LoggingOutInterceptor"/>
</beans>
编写测试用例
package cn.simple.cxf_soap_spring_client;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import cn.simple.cxf_client.stup.MobileAddress;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"classpath:applicationContext.xml"})
public class CxfSoapSpringClientTest {
@Autowired
private MobileAddressmobileAddress;
@Test
public void test01(){
System.out.println(mobileAddress.getMobileAdress("18999999999"));
}
}
运行异常
地址填写错误
再次运行