天天看点

webService及CXF框架入门

什么是WebService

Web service是一个平台独立的,低耦合的,自包含的、基于可编程的web的应用程序,可使用开放的XML(标准通用标记语言下的一个子集)标准来描述、发布、发现、协调和配置这些应用程序,用于开发分布式的互操作的应用程序。

调用网络上的webService:http://www.webxml.com.cn/zh_cn/web_services.aspx

调用一次webservice的本质如下:

1、客户端把调用方法参数转换生成XML文档片段(SOAP消息),且该文档必须符合WSDL定义的格式;
2、通过http协议把XML文档片段传给服务器;
3、服务器接受到XML文档片段;
4、服务器解析XML文档片段,提取其中的数据;
5、服务器执行方法;
6、服务器把执行方法得到的返回值转换成符合WSDL定义的XML文档片段;
7、通过http协议把XML文档片段传输给客户端;
8、客户端接受XML文档片段;
9、客户端解析XML文档,提取其中的数据。
           

所以从本质上来看,要支持webservice,必须支持XML文档解析、生成以及支持网络传输。

调用webservice的本质

SOAP(Simple Object Access Protocol):简单对象访问协议

简单对象访问协议是交换数据的一种协议规范,是一种轻量的、简单的、基于XML(标准通用标记语言下的一个子集)的协议,它被设计成在WEB上交换结构化的和固化的信息。

格式:

<SOAP-ENV:Envelope>
 <SOAP:HEADER>
 </SOAP:HEADER>
 <SOAP:Body>
	< getMobileCodeInfo>
		<telephone>13812345678</telephone>
		<userId></userId>
	</ getMobileCodeInfo>
 </SOAP:Body>
</SOAP-ENV:Envelope>
POST /WebServices/MobileCodeWS.asmx HTTP/1.1
Host: ws.webxml.com.cn
Content-Type: text/xml; charset=utf-8
Content-Length: length
SOAPAction: "http://WebXml.com.cn/getMobileCodeInfo"

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
    <getMobileCodeInfo xmlns="http://WebXml.com.cn/">
      <mobileCode>string</mobileCode>
      <userID>string</userID>
    </getMobileCodeInfo>
  </soap:Body>
</soap:Envelope>

HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: length

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
    <getMobileCodeInfoResponse xmlns="http://WebXml.com.cn/">
      <getMobileCodeInfoResult>string</getMobileCodeInfoResult>
    </getMobileCodeInfoResponse>
  </soap:Body>
</soap:Envelope>
           

WSDL(Web Services Description Language):Webservice描述语言

网络服务描述语言是Web Service的描述语言,它包含一系列描述某个web service的定义。

其实就是一个xml文档,这个文档描述了我们当前发布的服务的一些信息(服务的发布地址、服务发布的方法、方法参数、方法返回值等信息)。每个Webservice服务都对应自己的一个WSDL文件。

Wsdl网址:服务的发布地址?wsdl

二、使用jdk开发webservice接口以及调用

首先定义一个天气预报的接口,Weather

@WebService
public interface Weather {
    String queryWeather();
}
           

定义一个实现类,实现该接口

@WebService
public class WeatherImpl implements Weather{
    public String queryWeather() {
        return "今日天气为晴,偏北风二到三级";
    }
}
           

写一个普通的类,使其继承自spring的上下文监听器,并在初始化方法中发布接口,这样在容器启动时自动会发布

public class MyListener extends ContextLoaderListener{

    public void contextInitialized(ServletContextEvent event) {
        String address="http://localhost:8080/weather";
        Endpoint.publish(address, new WeatherImpl());
        super.contextInitialized(event);
    }
}
           

在web容器中设置该监听器

<listener>
      <listener-class>springframe.listener.MyListener</listener-class>
  </listener>
           

使用JDK的wsimport命令生成本地代码调用WebService服务

第一步:执行命令生成本地Java代码

进入命令窗口,输入一下命令生成远程调用代码,接口和实现类

wsimport -s .http://IP:port/项目名?wsdl

第二步:将生成的Java代码复制到项目中

第三步:基于生成的Java代码创建一个代理对象,通过代理对象底层会发送一个http请求,请求体格式需要符合SOAP协议规范

写客户端代码:

public static void main(String[] args) {
        Weather_Service factory=new Weather_Service();
        Weather wea=factory.getWeatherImplPort();
        System.out.println(wea.queryWeather());
    }
           

CXF框架入门

CXF的webservice开发流程如下:

1、服务器端

Ⅰ)开发web service业务接口,该接口用@WebService修饰;

Ⅱ)开发web service业务接口的实现类,也要用@WebService修饰;

Ⅲ)使用EndPoint类的静态方法publish()来发布web service。

2、客户端

Ⅰ)调用CXF提供的wsdl2java工具,根据WSDL文档生成相应的Java代码(任何语言实现web service都要暴露WSDL文档);

Ⅱ)找到wsdl2java所生成的类中一个继承了Service的类(该类的实例可当工厂使用);

Ⅲ)调用Service子类的实例的getXXXPort()方法,返回给远程web service的代理。

注意:

自动生成webservice客户端代码用的命令

首先当前是从官网下载cxf组件.

http://cxf.apache.org/download.html

下载后解压,在这里主要是用到解压后的bin目录中的wsdl2java.bat该批处理文件.

使用命令生成:Java代码

wsdl2java -p com.zzzl.webservice.qidian -d d:\cxfoutput\src -all  http://game.qidian.com/RemoteWebService/IPreventIndulge.asmx?wsdl  
           

参数说明:

-p 也就是package 对应java中的包

-d 输入目录,生成.java文件会在该目录,会自动添加-p参数配置的包路径

-client 生成客户端测试web service的代码.

-server 生成服务器启动web service的代码.

-impl 生成web service的实现代码.

-ant 生成build.xml文件.

-all 生成上面-client -server -impl -ant 对应的所有文件.

详细访问:https://gqsunrise.iteye.com/blog/2220625

1 基于CXF发布CRM服务

本案例基于spring整合CXF框架实现的。

第一步:创建一个maven工程,导入CXF和spring相关的坐标

引入相关的坐标

<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>com.huawei</groupId>
  <artifactId>common_parent</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>pom</packaging>
  <description>父工程,统一管理依赖</description>
  <properties>
		<spring.version>4.2.4.RELEASE</spring.version>
		<struts2.version>2.3.24</struts2.version>
		<hibernate.version>5.0.7.Final</hibernate.version>
		<slf4j.version>1.6.6</slf4j.version>
		<springdataredis.version>1.4.1.RELEASE</springdataredis.version>
		<activemq.version>5.2.0</activemq.version>
		<shiro.version>1.2.2</shiro.version>
		<springdatajpa.version>1.10.4.RELEASE</springdatajpa.version>
		<jedis.version>2.6.2</jedis.version>
		<poi.version>3.11</poi.version>
		<c3p0.version>0.9.1.2</c3p0.version>
		<cxf.version>3.0.1</cxf.version>
		<servlet.version>2.5</servlet.version>
		<junit.version>4.11</junit.version>
	</properties>

	<dependencies>
		<!-- 权限控制 框架 -->
		<dependency>
			<groupId>org.apache.shiro</groupId>
			<artifactId>shiro-all</artifactId>
			<version>${shiro.version}</version>
		</dependency>

		<!-- spring 框架 -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>${spring.version}</version>
		</dependency>

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context-support</artifactId>
			<version>${spring.version}</version>
		</dependency>

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-web</artifactId>
			<version>${spring.version}</version>
		</dependency>

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-orm</artifactId>
			<version>${spring.version}</version>
		</dependency>

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-jms</artifactId>
			<version>${spring.version}</version>
		</dependency>

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-test</artifactId>
			<version>${spring.version}</version>
		</dependency>

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-aspects</artifactId>
			<version>${spring.version}</version>
		</dependency>

		<!-- spring data jpa 数据库持久层 -->
		<dependency>
			<groupId>org.springframework.data</groupId>
			<artifactId>spring-data-jpa</artifactId>
			<version>${springdatajpa.version}</version>
		</dependency>

		<!-- 消息队列 MQ -->
		<dependency>
			<groupId>org.apache.activemq</groupId>
			<artifactId>activemq-all</artifactId>
			<version>${activemq.version}</version>
		</dependency>

		<!-- struts2 框架 -->
		<dependency>
			<groupId>org.apache.struts</groupId>
			<artifactId>struts2-core</artifactId>
			<version>${struts2.version}</version>
		</dependency>
		<dependency>
			<groupId>org.apache.struts</groupId>
			<artifactId>struts2-spring-plugin</artifactId>
			<version>${struts2.version}</version>
		</dependency>
		<dependency>
			<groupId>org.apache.struts</groupId>
			<artifactId>struts2-convention-plugin</artifactId>
			<version>${struts2.version}</version>
		</dependency>

		<!-- hibernate 框架 -->
		<dependency>
			<groupId>org.hibernate</groupId>
			<artifactId>hibernate-core</artifactId>
			<version>${hibernate.version}</version>
		</dependency>
		<dependency>
			<groupId>org.hibernate</groupId>
			<artifactId>hibernate-entitymanager</artifactId>
			<version>${hibernate.version}</version>
		</dependency>

		<!-- 数据库连接池 -->
		<dependency>
			<groupId>c3p0</groupId>
			<artifactId>c3p0</artifactId>
			<version>${c3p0.version}</version>
		</dependency>

		<!-- 日志框架 -->
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-log4j12</artifactId>
			<version>${slf4j.version}</version>
		</dependency>

		<!-- 工具包 -->
		<dependency>
			<groupId>commons-lang</groupId>
			<artifactId>commons-lang</artifactId>
			<version>2.6</version>
		</dependency>

		<dependency>
			<groupId>org.springframework.data</groupId>
			<artifactId>spring-data-redis</artifactId>
			<version>${springdataredis.version}</version>
		</dependency>

		<!-- oracle数据库驱动,需要手动安装 -->
		<!-- <dependency> <groupId>com.oracle</groupId> <artifactId>ojdbc6</artifactId> 
			<version>11.2.0.1.0</version> </dependency> -->
		<dependency>
			<groupId>com.oracle</groupId>
			<artifactId>ojdbc14</artifactId>
			<version>10.2.0.1.0</version>
		</dependency>

		<!-- Excel解析工具类 -->
		<dependency>
			<groupId>org.apache.poi</groupId>
			<artifactId>poi</artifactId>
			<version>${poi.version}</version>
		</dependency>
		<dependency>
			<groupId>org.apache.poi</groupId>
			<artifactId>poi-ooxml</artifactId>
			<version>${poi.version}</version>
		</dependency>
		<dependency>
			<groupId>org.apache.poi</groupId>
			<artifactId>poi-ooxml-schemas</artifactId>
			<version>${poi.version}</version>
		</dependency>

		<!-- Servlet、JSP -->
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>servlet-api</artifactId>
			<version>${servlet.version}</version>
			<scope>provided</scope>
		</dependency>

		<!-- 单元测试 -->
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>${junit.version}</version>
			<scope>test</scope>
		</dependency>

		<!-- 导入webservice依赖 -->
		<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>

		<dependency>
			<groupId>org.apache.cxf</groupId>
			<artifactId>cxf-rt-frontend-jaxrs</artifactId>
			<version>${cxf.version}</version>
		</dependency>

		<dependency>
			<groupId>org.apache.cxf</groupId>
			<artifactId>cxf-rt-rs-client</artifactId>
			<version>${cxf.version}</version>
		</dependency>

		<dependency>
			<groupId>org.apache.cxf</groupId>
			<artifactId>cxf-rt-rs-extension-providers</artifactId>
			<version>${cxf.version}</version>
		</dependency>

		<dependency>
			<groupId>org.codehaus.jettison</groupId>
			<artifactId>jettison</artifactId>
			<version>1.3.7</version>
		</dependency>

		<!-- 对象转为json 工具包 -->
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>fastjson</artifactId>
			<version>1.1.37</version>
		</dependency>

		<dependency>
			<groupId>com.colobu</groupId>
			<artifactId>fastjson-jaxrs-json-provider</artifactId>
			<version>0.3.1</version>
		</dependency>
		<!-- 引入json-lib的依赖 -->
		<dependency>
			<groupId>net.sf.json-lib</groupId>
			<artifactId>json-lib</artifactId>
			<version>2.4</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/com.belerweb/pinyin4j -->
		<dependency>
			<groupId>com.belerweb</groupId>
			<artifactId>pinyin4j</artifactId>
			<version>2.5.0</version>
		</dependency>
		<dependency>
			<groupId>javax.mail</groupId>
			<artifactId>mail</artifactId>
			<version>1.4</version>
		</dependency>
		<dependency>
			<groupId>redis.clients</groupId>
			<artifactId>jedis</artifactId>
			<version>${jedis.version}</version>
			<scope>compile</scope>
		</dependency>
		<!-- 缓存 -->
		<dependency>
			<groupId>net.sf.ehcache</groupId>
			<artifactId>ehcache-core</artifactId>
			<version>2.6.11</version>
		</dependency>
		<dependency>
			<groupId>org.quartz-scheduler</groupId>
			<artifactId>quartz</artifactId>
			<version>2.2.1</version>
		</dependency>
		<dependency>
			<groupId>org.quartz-scheduler</groupId>
			<artifactId>quartz-jobs</artifactId>
			<version>2.2.1</version>
		</dependency>
		<dependency>
			<groupId>org.apache.xbean</groupId>
			<artifactId>xbean-spring</artifactId>
			<version>4.2</version>
		</dependency>
		<!-- itext -->
		<dependency>
        	<groupId>com.lowagie</groupId>
        	<artifactId>itext</artifactId>
        	<version>2.1.7</version>
        </dependency>
        <dependency>
        	<groupId>com.itextpdf</groupId>
        	<artifactId>itext-asian</artifactId>
        	<version>5.2.0</version>
        </dependency>
        
        <!-- groovy -->
		<dependency>
			<groupId>org.codehaus.groovy</groupId>
			<artifactId>groovy-all</artifactId>
			<version>2.2.0</version>
		</dependency>

		<!-- jasperreport -->
		<dependency>
			<groupId>net.sf.jasperreports</groupId>
			<artifactId>jasperreports</artifactId>
			<version>5.2.0</version>
			<exclusions>
				<exclusion>
					<groupId>com.lowagie</groupId>
					<artifactId>itext</artifactId>
				</exclusion>
			</exclusions>
		</dependency>  
	</dependencies>
	<build>
		<pluginManagement>
			<plugins>
				<plugin>
					<groupId>org.apache.maven.plugins</groupId>
					<artifactId>maven-compiler-plugin</artifactId>
					<version>3.2</version>
					<configuration>
						<source>1.7</source>
						<target>1.7</target>
						<encoding>UTF-8</encoding>
						<showWarnings>true</showWarnings>
					</configuration>
				</plugin>
			</plugins>
		</pluginManagement>
	</build>
</project>
           

创建war工程:

webService及CXF框架入门

第二步:在web.xml中配置一个CXF框架提供的CXFServlet

<servlet>
  	<servlet-name>cxf</servlet-name>
  	<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
  	<init-param>
  		<param-name>config-location</param-name>
  		<param-value>classpath:beans.xml</param-value>
  	</init-param>
  </servlet>
  <servlet-mapping>
  	<servlet-name>cxf</servlet-name>
  	<url-pattern>/webservice/*</url-pattern>
  </servlet-mapping>
           

第三步:开发一个Java类,对外提供服务

import javax.jws.WebService;
import javax.xml.ws.Endpoint;

@WebService
public class HelloService {
	public String getInfo(String name){
		System.out.println("服务端的getInfo方法被调用了。。。"  + new Date());
		return "hello " + name;
	}
}
           

第四步:提供spring核心配置文件beans.xml文件(spring文件)

<?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:soap="http://cxf.apache.org/bindings/soap"
xsi:schemaLocation="http://www.springframework.org/schema/beans 
					http://www.springframework.org/schema/beans/spring-beans.xsd
					http://cxf.apache.org/bindings/soap 
					http://cxf.apache.org/schemas/configuration/soap.xsd
					http://cxf.apache.org/jaxws 
					http://cxf.apache.org/schemas/jaxws.xsd">
<!-- 注册服务 -->
	<jaxws:server id="myCXFService" address="/hello" serviceClass="com.huawei.cxf.HelloService">
	</jaxws:server>

</beans>

           

CXF入门案例(客户端开发)

基于spring框架开发客户端,引入框架相关坐标(如上配置即可)

1.使用WSDL2Java或原生的wsimport命令生成本地代码调用,复制到相应的工程中

2.在配置文件中注册代理对象调用

此处省略相关的约束引入(如上配置)
<!-- 注册客户端代理对象,用于Webservice远程调用 -->
	<jaxws:client id="myClient" 
					address="http://localhost:8081/cxf_service/webservice/hello" 
					serviceClass="com.huawei.cxf.HelloService">
	</jaxws:client>
           

第四步:测试

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations="classpath:beans.xml")
public class App {
	@Autowired
	private HelloService proxy;
	
	@Test
	public void test1(){
		String ret = proxy.getInfo("huawei");
		System.out.println(ret);
	}
}

           

如果直接使用隐编码实现CXF调用远程服务如下:

19 public class Server {
20     
21     public static void main(String[] args) {
22    
23         HelloWorldImpl implementor = new HelloWorldImpl();
24         String address="http://192.168.0.102/helloWorld";
25         //Endpoint.publish(address, implementor);//JDK实现
26         JaxWsServerFactoryBean factoryBean = new JaxWsServerFactoryBean();
27         factoryBean.setAddress(address); //设置暴露地址
28         factoryBean.setServiceClass(HelloWorld.class); //接口类
29         factoryBean.setServiceBean(implementor); //设置实现类
30         factoryBean.create();
31       
32         
33     }
34 }
           

未完待续。。。