什麼是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工程:
第二步:在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 }
未完待續。。。