天天看點

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 }
           

未完待續。。。