WebService學習-第一彈

一:WebService簡介
(1)簡介----百度百科(注意標識的重點)javascript

        Web service是一個平臺獨立的,低耦合的,自包含的、基於可編程的web的應用程序,可以使用開放的XML(標準通用標記語言下的一個子集)標準來描述、發佈、發現、協調和配置這些應用程序,用於開發分佈式的互操做的應用程序。 [1] 
       Web Service技術, 能使得運行在不一樣機器上的不一樣應用無須藉助附加的、專門的第三方軟件或硬件, 就可相互交換數據或集成。依據Web Service規範實施的應用之間, 不管它們所使用的語言、 平臺或內部協議是什麼, 均可以相互交換數據。Web Service是自描述、 自包含的可用網絡模塊, 能夠執行具體的業務功能。Web Service也很容易部署, 由於它們基於一些常規的產業標準以及已有的一些技術,諸如標準通用標記語言下的子集XML、HTTP。Web Service減小了應用接口的花費。Web Service爲整個企業甚至多個組織之間的業務流程的集成提供了一個通用機制。html

(2)WebService三元素java

UDDI:UDDI 的目的是爲電子商務創建標準;UDDI是一套基於Web的、分佈式的、爲Web Service提供的、信息註冊中心的實現標準規範,同時也包含一組使企業能將自身提供的Web Service註冊,以使別的企業可以發現的訪問協議的實現標準。---簡單點說,就是一套規則,方便使用;mysql

WSDL:Web Service描述語言WSDL 就是用機器能閱讀的方式提供的一個正式描述文檔而基於XML(標準通用標記語言下的一個子集)的語言,用於描述Web Service及其函數、參數和返回值。由於是基於XML的,因此WSDL既是機器可閱讀的,又是人可閱讀的。----簡單點說,就是使用規則,方便人和機器進行閱讀;web

SOAP協議:基於Http,基於XML,SOAP即簡單對象訪問協議(Simple Object Access Protocol),它是用於交換XML(標準通用標記語言下的一個子集)編碼信息的輕量級協議。它有三個主要方面:XML-envelope爲描述信息內容和如何處理內容定義了框架,將程序對象編碼成爲XML對象的規則,執行遠程過程調用(RPC)的約定。SOAP能夠運行在任何其餘傳輸協議上。例如,你可使用 SMTP,即因特網電子郵件協議來傳遞SOAP消息,這但是頗有誘惑力的。在傳輸層之間的頭是不一樣的,但XML有效負載保持相同。----簡單點說,就是傳輸協議,方便進行傳輸;ajax

(3)WebService與Socket的區別(兩種通訊的方式)spring

(1) Socket是基於TCP/IP的傳輸層協議。 
    Webservice是基於HTTP協議傳輸數據,http是基於tcp的應用層協議。 
    Webservice採用了基於http的soap協議傳輸數據。
(2)Socket接口經過流傳輸,不支持面向對象。 
    Webservice 接口支持面向對象,最終webservice將對象進行序列化後經過流傳輸。 
    Webservice採用soap協議進行通訊,不需專門針對數據流的發送和接收進行處理,是一種跨平臺的面向對象遠程調用技術。
(3)Socket適用於高性能大數據的傳輸,傳輸的數據須要手動處理,socket通訊的接口協議須要自定義。sql

二:屬於本身的第一個WebService程序
1)服務端代碼(Java工程項目便可,而不須要是web項目,由於webservice已經做爲了java SE裏面自帶的內容):數據庫

package com.hnu.scw.webservice;
import javax.jws.WebService;
import javax.xml.ws.Endpoint;
/**
* <p>Title: MyFirstWebService.java</p>
* <p>Description: </p>
* <p>Company: 湖南大學</p>
* @author scw
* @date 2018年5月3日
*/
@WebService
public class MyFirstWebService {
/**
* 定義webservice服務器中的方法
* @param content
* @return
*/
public String testWebService(String content){
System.out.println("我收到了你發的信息:" + content);
return "服務器:我轉發信息給你";
}

public static void main(String[] args){
//定義本身的webservice服務器發佈的地址
String address = "http://localhost:9090/MyFirstWebService"; //這個9090端口隨便定義,只要不衝突便可
//經過該方法進行發佈
Endpoint.publish(address, new MyFirstWebService());
//打印一句話,表示一下服務器進行了開啓
System.out.println("my webservcie starting");
}
}
舒適提示:1:必須加@WebService註解或者@WebServiceProviderapache

2:至少有一個方法是public,而且不能夠用static 和 final進行修飾;緣由很明顯,由於webservice就是提供給別人各自進行使用的,而不是保持同一個,因此不能是static ,而對於final修飾的話就是不可繼承,這也是沒有意義的。你們能夠試試,將方法進行修改,看會不會報錯。

(2)解析WebService服務器的內容

操做:在cmd命令行中執行:wsimport -s . http://localhost:9090/MyFirstWebService

 

結果:這樣的話,就會在你執行這句話的目錄下面生成對應的服務器的代碼(包括.class文件和.java文件)

 

(3)客戶端代碼(Java工程項目便可):

步驟:

1:首先是把上面獲得的代碼中的.java文件(請注意,.class文件就不須要)拷貝到咱們新建的一個客戶端的java項目中

2:編寫咱們的測試方法

package com.hnu.scw.webservice;
import org.junit.Test;
/**
* <p>Title: MyTestWebService.java</p>
* <p>Description: 用於進行測試webservice服務器的客戶端代碼</p>
* <p>Company: 湖南大學</p>
* @author scw
* @date 2018年5月3日
*/
public class MyTestWebService {
@Test
public void testWebService(){
//獲取webservice服務器對象(這裏的類名,實際上是從wsdl文件中的servicename標籤中進行獲取的)
MyFirstWebServiceService myFirstWebServiceService = new MyFirstWebServiceService();
//獲取到咱們自定義的webservice的對象
MyFirstWebService myFirstWebServicePort = myFirstWebServiceService.getMyFirstWebServicePort();
//調用service服務器中的方法
String receivedInfo = myFirstWebServicePort.testWebService("您好,webservice 服務器");
//打印從服務器的方法中獲得的返回值,測試表示收到了服務器返回的內容
System.out.println("服務器返回的內容是:" + receivedInfo);
}
}
舒適提示:能夠經過瀏覽器輸入:http://localhost:端口號/發佈的服務器名字?wsdl     -----------來查看定義service的wsdl文檔

這時候,咱們只須要首先運行服務器端的java項目,而後再運行咱們客戶端的@Test方法,這樣就能夠獲得從服務器中獲取到的消息內容了。

三:與WebService服務器進行交互的方式
(1)普通客戶端調用

這個的話就很少說了,由於在咱們上面的第一個WebService的代碼中,就已是這樣的一種調用方式。

(2)ajax調用

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script type="text/javascript">
/*
思路:
1.建立一個XMLHTTP對象
2.打開連接open("POST",url)
3.設置請求頭Content-Type
4.設置回調函數,處理返回值
5.從返回的XML中解析咱們要的內容
*/

var xmlHttpReqquest = new ActiveXObject("Microsoft.XMLHTTP");
//alert(xmlHttpReqquest);

//發送SOAP請求
function sendMsg(){
//獲取用戶輸入的內容
var name = document.getElementById("name").value;
var url = "http://localhost:9090/MyFirstWebService";
//下面的這種格式主要是經過Eclipse下載了一個webservice調式工具,這樣就能夠看到對應的xml格式內容
var requestBody = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:q0=\"http://webservice.scw.hnu.com/\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">"
+ "<soapenv:Body><q0:testWebService><arg0>"+name+"</arg0></q0:testWebService></soapenv:Body></soapenv:Envelope>";
xmlHttpReqquest.open("POST", url);
xmlHttpReqquest.setRequestHeader("Content-Type","text/xml;charset=utf-8");
xmlHttpReqquest.onreadystatechange = _back;
xmlHttpReqquest.send(requestBody);
}

//接收SOAP返回,從返回XML中解析
function _back(){
//處理完畢,處理成功
if(xmlHttpReqquest.readystate==4){ //處理完
if(xmlHttpReqquest.status==200){ //成功
var xml = xmlHttpReqquest.responseXML;
//alert(xml);

//獲取return標籤的第一個
var ele = xml.getElementsByTagName("return")[0];
alert(ele.text);
}else{
alert(0);
}
}
}

</script>
</head>
<body>
<input type="text" id="name" name="name" value=""/>
<input type="button" name="send" value="send" onclick="sendMsg();"/>
</body>
</html>
(3)URLConnection的調用方式

//建立url地址
URL url = new URL(""http://localhost:9090/MyFirstWebService");
//打開鏈接
URLConnection conn = url.openConnection();
//轉換成HttpURL
HttpURLConnection httpConn = (HttpURLConnection) conn;
//打開輸入輸出的開關
httpConn.setDoInput(true);
httpConn.setDoOutput(true);
//設置請求方式
httpConn.setRequestMethod("POST");
//設置請求的頭信息
httpConn.setRequestProperty("Content-type", "text/xml;charset=UTF-8");
//拼接請求消息
String data = "<soapenv:Envelope xmlns:soapenv=" +
"\"http://schemas.xmlsoap.org/soap/envelope/\" " +
"xmlns:q0=\"http://server.rl.com/\" " +
"xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" " +
"xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">"
+"<soapenv:Body>"
+"<q0:testWebService>"
+"<arg0>my name is scw</arg0> "
+"</q0:testWebService>"
+"</soapenv:Body>"
+"</soapenv:Envelope>";
//得到輸出流
OutputStream out = httpConn.getOutputStream();
//發送數據
out.write(data.getBytes());
//判斷請求成功
if(httpConn.getResponseCode() == 200){
//得到輸入流
InputStream in = httpConn.getInputStream();
//使用輸入流的緩衝區
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
StringBuffer sb = new StringBuffer();
String line = null;
//讀取輸入流
while((line = reader.readLine()) != null){
sb.append(line);
}
//建立sax的讀取器
SAXReader saxReader = new SAXReader();
//建立文檔對象
Document doc = saxReader.read(new StringReader(sb.toString()));
//得到請求響應return元素
List<Element> eles = doc.selectNodes("//return");
for(Element ele : eles){
System.out.println(ele.getText());
}
}
(4)QName調用------------推薦這種方式

package com.hnu.scw.test;
import java.net.MalformedURLException;
import java.net.URL;
import javax.xml.namespace.QName;
import javax.xml.ws.Service;
import org.junit.Test;
import com.hnu.scw.webservice.MyFirstWebService;
/**
* <p>Title: MyTestQNameWebService.java</p>
* <p>Description: 經過QName的一種調用方式</p>
* <p>Company: 湖南大學</p>
* @author scw
* @date 2018年5月4日
*/
public class MyTestQNameWebService {
@Test
public void test() throws MalformedURLException{
//建立一個鏈接(地址對應的就是webservice服務器中的地址)
URL wsdlDocumentLocation = new URL("http://localhost:9090/MyFirstWebService?wsdl");
//這個參數,主要是根據咱們設定的webService的接口來進行的
QName serviceName = new QName("http://webservice.scw.hnu.com/","MyFirstWebServiceService");
Service ws = Service.create(wsdlDocumentLocation , serviceName );
//獲取到調用的對象內容
MyFirstWebService port = ws.getPort(MyFirstWebService.class);
//方法的調用
String result = port.testWebService("my name is scw");
System.out.println(result);
}
}
舒適提示:(1)這個方式大致和咱們之間進行的客戶端調用類型,可是注意一點,在咱們的客戶端的方式的時候,咱們是把所解析獲得的.java全部文件都拷貝到客戶端程序,而若是用QName的形式,咱們只須要保留咱們對應WebService類的接口那個便可。好比,以下:

客戶端的狀況:

 

QName的狀況:

 

(2)當咱們只保留上面的java文件的時候,會出現錯誤,只須要根據下面進行修改便可;

 

(3)QName對象的參數是如何知道的?那麼久看咱們保留的那個接口類中;

 

(4)經過QName的方式能夠很明顯的感受比第一種客戶端要好,由於,能夠對於端口和連接都有靈活性,並且拷貝的代碼也相對較少;

四:關於WebService的部分註解


五:初識CXF框架
     官網:http://cxf.apache.org/

    Apache CXF = Celtix + XFire,開始叫 Apache CeltiXfire,後來改名爲 Apache CXF 了,如下簡稱爲 CXF。CXF 繼承了 Celtix 和 XFire 兩大開源項目的精華,提供了對 JAX-WS 全面的支持,而且提供了多種 Binding 、DataBinding、Transport 以及各類 Format 的支持,而且能夠根據實際項目的須要,採用代碼優先(Code First)或者 WSDL 優先(WSDL First)來輕鬆地實現 Web Services 的發佈和使用。Apache CXF已是一個正式的Apache頂級項目。

      Apache CXF 是一個開源的 Services 框架,CXF 幫助您利用 Frontend 編程 API 來構建和開發 Services ,像 JAX-WS 。這些 Services 能夠支持多種協議,好比:SOAP、XML/HTTP、RESTful HTTP 或者 CORBA ,而且能夠在多種傳輸協議上運行,好比:HTTP、JMS 或者 JBI,CXF 大大簡化了 Services 的建立,同時它繼承了 XFire 傳統,同樣能夠自然地和 Spring 進行無縫集成。

六:利用CXF框架來搭建咱們的WebService
步驟:

(1)首先去官網下載一個版本http://cxf.apache.org/,如今的話,都是3.2.X版本了,這個根據須要便可;

(2)下載以後,裏面就有一個lib的目錄,就是關於CXF架構的一些依賴包;

能夠去官網下載(或者去博文最後的百度雲中下載):http://cxf.apache.org/

(3)建立一個web項目(注意:這時候用了web項目,而以前的開發都是用的Java項目),而且把依賴包都複製到項目中的lib目錄中(就和正常的開發web項目同樣,在拷貝全部的以後,要把裏面的WHICH_JARS這個文件刪除,不然會報錯)

服務端代碼:

package com.hnu.scw;
import org.apache.cxf.frontend.ServerFactoryBean;
/**
* 基於CXF框架的服務端代碼
* @author Administrator
*
*/
public class FirstCXFService {
/**
* web服務的方法
* @param name
* @return
*/
public String printReciveInfo(String name){
System.out.println("客戶端發送過來信息:" + name);
return "服務器轉發給你了"+ name;
}
public static void main(String[] args){
ServerFactoryBean serverFactoryBean = new ServerFactoryBean();
//設置訪問地址
serverFactoryBean.setAddress("http://localhost:9090/firstService");
//設置實現類
serverFactoryBean.setServiceClass(FirstCXFService.class);
//啓動服務
serverFactoryBean.create();
}
}
舒適提示:不要運行配置的服務器,而是直接運行main函數便可。。。。。這樣就開啓可服務器

客戶端代碼:(一樣的仍是經過cmd中的命令:wsimport -s .  XXXXXXXXXX (SOAP1.1版本)或者wsdl2java –d . XXXXXXXXXX(SOAP1.2版本) 來生成代碼),而後再建立一個工程項目,並把生成的.java文件拷貝進去。

package com.hnu.scw.test;
import org.junit.Test;
import com.hnu.scw.FirstCXFService;
import com.hnu.scw.FirstCXFServicePortType;
/**
* 測試CXF框架的客戶端
* @author Administrator
*
*/
public class CXFClientTest {
@Test
public void printTest(){
FirstCXFService firstCXFService = new FirstCXFService();
FirstCXFServicePortType firstCXFServicePort = firstCXFService.getFirstCXFServicePort();
String result = firstCXFServicePort.printReciveInfo("my name is scw");
System.out.println(result);
}
}

七:面向接口的編寫WebService服務
接口:

package com.hnu.scw;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
import javax.xml.ws.BindingType;
import javax.xml.ws.soap.SOAPBinding;
@WebService(serviceName="HelloServer")
@BindingType(value=SOAPBinding.SOAP12HTTP_BINDING)
public interface FirstServer {
@WebMethod(operationName="sayHello")
@WebResult(name="returnMsg")
public String printReciveInfo(@WebParam(name="name")String name);
}
服務器端實現類:

package com.hnu.scw;
import org.apache.cxf.frontend.ServerFactoryBean;
/**
* 基於CXF框架的服務端代碼
* @author Administrator
*
*/
public class FirstCXFService implements FirstServer{
/**
* web服務的方法
* @param name
* @return
*/
public String printReciveInfo(String name){
System.out.println("客戶端發送過來信息:" + name);
return "服務器轉發給你了"+ name;
}

public static void main(String[] args){
ServerFactoryBean serverFactoryBean = new ServerFactoryBean();
//設置訪問地址
serverFactoryBean.setAddress("http://localhost:9090/firstService");
//設置接口
serverFactoryBean.setServiceClass(FirstServer.class);
//設置實現類
serverFactoryBean.setServiceBean(new FirstCXFService());
//啓動服務
serverFactoryBean.create();
}
}
客戶端類型的方法就很少說了,只是須要從新編譯下載服務端的代碼便可。

八:在WebService服務端添加輸入輸出監控日誌
 方法:其實很簡單,就是添加一些默認的攔截器就能夠了

服務端代碼:

package com.hnu.scw;
import org.apache.cxf.frontend.ServerFactoryBean;
/**
* 基於CXF框架的服務端代碼
* @author Administrator
*
*/
public class FirstCXFService {
/**
* web服務的方法
* @param name
* @return
*/
public String printReciveInfo(String name){
System.out.println("客戶端發送過來信息:" + name);
return "服務器轉發給你了"+ name;
}
public static void main(String[] args){
ServerFactoryBean serverFactoryBean = new ServerFactoryBean();
//設置訪問地址
serverFactoryBean.setAddress("http://localhost:9090/firstService");
//設置實現類
serverFactoryBean.setServiceClass(FirstCXFService.class);
//攔截器
serverFactoryBean.getInInterceptors().add(new LoggingInInterceptor()); //攔截請求的連接,打印相關信息(誰調用)
serverFactoryBean.getOutInterceptors().add(new LoggingOutInterceptor()); //攔截響應的連接,打印相關信息(返回)
//啓動服務
serverFactoryBean.create();
}
}
九:設置WebService的版本是採起SOAP1.2版本
   在前面有說過,JDK是默認支持SOAP1.1版本的,而如今也有1.2版本,那如何將咱們的WebService轉變成1.2版本的呢?其實很簡單,只須要添加一個註解便可:(若是採起的是接口編程,那麼就放在接口名上便可)

@BindingType(value=SOAPBinding.SOAP12HTTP_BINDING)
小知識:SOAP1.1和SOAP1.2的區別:

1)命名空間

2)標籤變化

舒適提示:在開發中若是使用SOAP1.2實現WebService,在生成本地調用代碼時,應該使用CXF提供wsdl2java命令。若是使用SOAP1.1實現WebService,在生成本地調用代碼時,應該使用jdk提供wsimport命令。在實際項目中目前儘可能使用SOAP1.1版本;

十:CXF和Spring框架的整合(重點知識)
步驟:

(1)導包:將下載下來的CXF中的lib目錄中jar導入到web項目中的WEB-INF目錄下的lib中(一樣,仍是須要將其中的WHICH_JARS這個文件刪除,不然會報錯),不須要額外導入Spring的包,由於在CXF的lib中已經包含有Spring的jar包,這個本身能夠進行查看;

(2)建立WebService的類;

好比:

package com.hnu.scw.webservice;
import javax.jws.WebService;
/**
* 建立一個webservice服務類
* @author scw
*
*/
@WebService
public class MyWebService {
/**
* 建立WebService的調用方法
* @param content
* @return
*/
public String hiMyService(String content){
System.out.println("客戶端發送過來了:" + content);
return "服務器返回:"+ content ;
}
}
(3)在WEB-INF目錄下面建立一個cxf-servlet.xml-------------------這個就是對於webservice的管理

<?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"
xsi:schemaLocation=" http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.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:endpoint id="helloService" address="/mywebservice" implementor="com.hnu.scw.webservice.MyWebService"></jaxws:endpoint>
</beans>
(4)修改web.xml文件內容,將WebService的cxf-servlet.xml進行管理

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.5" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<display-name>cxf</display-name>
<!-- 配置cxf框架 cxf-servlet.xml -->
<servlet>
<servlet-name>cxf</servlet-name>
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>cxf</servlet-name>
<!-- 這裏配置只針對/cxf/的這樣連接進行管理,由於若是也配置成/*這樣的話,也是能夠,這只是更加便於管理而已 -->
<url-pattern>/cxf/*</url-pattern>
</servlet-mapping>
</web-app>
(5)啓動tomcat項目,測試CXF的配置是否成功

 

(6)配置Spring的配置文件中的beans.xml,專門進行bean的內容的管理(在項目的src下便可,這和Spring開發沒什麼不一樣)

主要是爲了將WebService的類放入到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:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd ">
<bean id="myWebService" class="com.hnu.scw.webservice.MyWebService"></bean> <!--這就是個人webservice類的路徑-->
</beans>
(7)修改以前的cxf-servlet.xml中的內容

緣由:由於如今咱們的bean放入到了Spring中進行管理,因此,咱們直接引用Spring中的bean便可

<?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"
xsi:schemaLocation=" http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.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"/>

<!-- 加載提供的服務 ,注意看此時的implementor標籤的寫法,#表示的是引用Spring中的bean內容-->
<jaxws:endpoint id="helloService" address="/mywebservice" implementor="#myWebService"></jaxws:endpoint>
</beans>
(8)修改web.xml內容,將Spring放入到容器進行管理

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.5" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<display-name>cxf</display-name>

<!-- 配置spring框架 beans.xml -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:beans.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<!-- 配置cxf框架 cxf-servlet.xml -->
<servlet>
<servlet-name>cxf</servlet-name>
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>cxf</servlet-name>
<!-- 這裏配置只針對/cxf/的這樣連接進行管理,由於若是也配置成/*這樣的話,也是能夠,這只是更加便於管理而已 -->
<url-pattern>/cxf/*</url-pattern>
</servlet-mapping>
</web-app>
(9)啓動tomcat,進行測試是否整合成功

 

總結:經過上面的步驟,咱們的整合已經成功了,可是你們可能發現有不少地方不是很好,好比咱們的cxf-servlet.xml是放在WEB-INF目錄下,那麼咱們應該也像配置Spring的配置文件同樣,放在src下這樣的話將會更加好,因此,咱們進行下面的修改

 (10)修改cxf-servlet.xml的加載路徑----------這樣咱們就能夠把這個xml放到src目錄下了

<!-- 配置cxf框架 cxf-servlet.xml -->
<servlet>
<servlet-name>cxf</servlet-name>
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
<!-- 配置cxf-servlet.xml的尋找的位置 -->
<init-param>
<param-name>config-location</param-name>
<param-value>classpath:cxf-servlet.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>cxf</servlet-name>
<!-- 這裏配置只針對/cxf/的這樣連接進行管理,由於若是也配置成/*這樣的話,也是能夠,這只是更加便於管理而已 -->
<url-pattern>/cxf/*</url-pattern>
</servlet-mapping>


--------------------------------------------------------------------------------------------

項目總體結構以下:

 

------------------------------------------------------------------------------------------------

十一:項目實踐
前提內容:這是一個比較經典的物流供應項目,網上能夠找到源碼的。只不過,既然咱們學得是WebService,那麼確定就要進行相應的改造的,因此,針對裏面的一個物流查詢模塊,來設計成爲一個可以讓其餘系統都能調用的功能(這樣,情景引入的問題是否是就解決了)。

描述:針對項目中的,物流查詢模塊改形成一個WebService服務,方便其餘的模塊或者系統進行相應的使用,實現一種跨平臺的功能。

步驟:

環境:eclipse + maven + mysql (其餘的編輯器什麼的都行,這個徹底根據自身習慣便可,沒有要求)

(1)導入項目內容--------這個很少說,就是導入maven項目,而後把相應的數據庫內容在本地生成便可(都在個人百度雲裏面了)

(2)查看原始內容(重點關注我標識的部分,也就是咱們要進行改造的類)

 

 

咱們就改造下面這個方法:這個方法的功能就是,經過物流的ID,來查詢到它的物流信息

 

提示:你們稍微看一下這個類,基本瞭解是幹嗎的就能夠了哈~~

改造其類爲WebService類步驟(重點來了):

(1)將須要修改成WebService的類,添加註解 @WebService進行標識

 

(2)添加操做對應的DAO類的額外bean依賴

//給WebService使用
@WebMethod(exclude=true)
public void setExportDao(ExportDao exportDao) {
this.exportDao = exportDao;
}
分析:

1:添加@WebMethod(exclude=true)的做用:防止給調用者看到這個方法,由於這個方法只是給spring來進行注入bean依賴的;

2:你們可能注意到一個問題了,在spring開發中,

咱們通常是這樣。

可是,千萬注意一下,這個也是要的,而爲何又多了一個set注入,是由於,這是專門用戶webservice注入的,因此,必定要區分開緣由,因此這二者都是須要存在的。也就是下面的這樣的代碼:

//給spring service使用dao
@Resource
ExportDao exportDao;

//給WebService使用
@WebMethod(exclude=true)
public void setExportDao(ExportDao exportDao) {
this.exportDao = exportDao;
}
(3)將其餘不進行提供webservice調用的方法進行註解屏蔽,而只保留webservice可以調用的方法。以下所示:

@WebMethod(exclude=true)
public List<Export> find(Map paraMap) {
return exportDao.find(paraMap);
}

//WebService調用
public Export get(String id) {
return exportDao.get(id);
}
(4)添加cxf-servlet.xml文件

目錄:

cxf-servlet.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:jaxws="http://cxf.apache.org/jaxws"
xsi:schemaLocation=" http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.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"/>

<!-- 發佈WebService 參數:訪問地址address,實現類 implementor -->
<bean id="exportService" class="cn.itcast.jk.service.impl.ExportServiceImpl">
<property name="exportDao" ref="exportDaoImpl"/>
</bean>

<jaxws:endpoint address="/ExportServiceImpl" implementor="#exportService"/>
</beans>
分析:如今再回頭看一下第(2)步中,額外添加的set注入,是否是就明白緣由了呢?這上面的知識都是我上面講過的,因此,不懂的就回頭再去看看吧。

(5)修改web.xml,添加對cxf-servlet.xml的加載

<!-- 3.webService CXF -->
<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:cxf-servlet.xml</param-value>
</init-param>
</servlet>

<servlet-mapping>
<servlet-name>cxf</servlet-name>
<url-pattern>/cxf/*</url-pattern>
</servlet-mapping>
(6)在pom.xml中添加對CXF框架的依賴

<!-- 整合CXF WebService框架 -->
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxws</artifactId>
<version>3.0.2</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http</artifactId>
<version>3.0.2</version>
</dependency>
分析:經過上面的步驟,基本上就改造完成了,那麼下面就來進行實際的使用:(這裏經過ajax的形式來進行,也是咱們開發中用的相對較多的方式)

(7)ajax來調用webservice類的形式

具體的內容:你們就看代碼中:src\main\webapp\WEB-INF\pages\cargo\export目錄下的ajaxExport.jsp頁面內容吧

(8)進行測試。(固然,這個最好是在整合完成CXF和Spring,即改造完webservice類的時候就測試一下比較好)

針對這個項目的話,我把最初的項目源碼和改造後的代碼以及數據庫內容,兩個版本的都放入了百度雲,並且把該博文中相關的代碼都放入了這裏面,供你們進行下載。

連接:https://pan.baidu.com/s/1_exUqQeg3h2OwGFhDa2dmg          密碼:60fq

總結:我想沒有比這篇博文更加詳細的介紹了的吧。^_^~!WebService其實開發起來並不難,並且功能仍是很是強大,對於若是存在着異構系統之間的調用的話,仍是挺實用的。因此,對於這部分的內容,就介紹到這裏了,歡迎你們的關注哦~

相關文章
相關標籤/搜索