WebService入門詳解

1、什麼是webservice

先來考慮一個問題,如果我們要在自己的程序裏面展示天氣預報,那怎麼弄?正確的做法是我們發送一個請求到一個系統,他會給我們返回來天氣情況。這個就是一個webservice。天氣預報系統就相當於webservice的服務端,我們的系統就相當於客戶端。如http://www.webxml.com.cn這個網站上面就列舉了多個webservice服務站點

2、JAVA中如何調用別人發佈的webservice

2.1、獲取webservice的wsdl文檔

2.11、什麼是wsdl文檔

wsdl跟java一樣,也是一種語言,是通過xml的形式說明該webservice如何調用。

2.12、如何獲取wsdl文檔

通過在webservice的url後面加?wsdl的方式,比如天氣預報的的就是http://ws.webxml.com.cn/WebServices/WeatherWS.asmx?wsdl

2.13、WSDL解析

Wsdl文檔從下往上讀 
Types - 數據類型定義的容器,它使用某種類型系統(一般地使用XML Schema中的類型系統)。(入參和出參的數據類型) 
Message - 通信消息的數據結構的抽象類型化定義。使用Types所定義的類型來定義整個消息的數據結構(入參和出參)。 
Operation - 對服務中所支持的操作的抽象描述,一般單個Operation描述了一個訪問入口的請求/響應消息對(方法)。 
PortType - 對於某個訪問入口點類型所支持的操作的抽象集合,這些操作可以由一個或多個服務訪問點來支持(服務類)。 
Binding - 特定服務訪問點與具體服務類的綁定(不看內容,看關係)。 
Port - 定義爲webservice單個服務訪問點。 
Service- 相關服務訪問點的集合。

2.2、通過wsdl文檔生成客戶端調用代碼

2.21、使用jdk自帶的命令生成

配置java環境變量後在命令窗口中輸入wsimport –s . http://xxxx.xx.xx/xxx?wsdl即可生成java代碼 
注意:-s不能分開,-s後面有個小點,用於指定源代碼生成的目錄。點即當前目錄。如果使用了-s參數則會在目錄下生成兩份代碼,一份爲.class代碼。一份爲.java代碼。.class代碼,可以經過打包以後使用。.java代碼可以直接Copy到我們的項目中運行

2.3、生成代碼後如何調用

先把生成的代碼複製到項目中,然後通過讀wsdl文檔來調用

//wsdl文檔中service的name
SayHelloIntefaceService ss = new SayHelloIntefaceService();
//wsdl文檔中portType的name
SayHelloInteface shf=ss.getSayHelloIntefacePort();
//wdl文檔中complexType的name
String str=shf.sayhellow("lisi");
//str即爲webservice的服務端返回的信息
System.out.println(str);

3、如何發佈一個webservice

Endpoint.publish("http://127.0.0.1:8080/sayHello", new SayHellowIntefaceImpl());

注意:用Jdk1.6.0_21以後的版本發佈一個WebService服務.與Web服務相關的類,都位於javax.xml.ws.*包中。 
主要類有: 
a) @WebService - 它是一個註解,用在類上指定將此類發佈成一個webservice服務. 
b) Endpoint – 此類爲端點服務類,它的方法publish用於將一個已經添加了@WebService註解對象綁定到一個地址的端口上。Endpoint是jdk提供的一個專門用於發佈服務的類,它的publish方法接收兩個參數,一個是本地的服務地址,二是提供服務的類。它位於javax.xml.ws.*包中。 
static Endpoint.publish(String address, Object implementor) 在給定地址處針對指定的實現者對象創建併發布端點。stop方法用於停止服務。 
其他注意事項: 
1) 給類添加上@WebService註解後,類中所有的非靜態方法都將會對外公佈。不支持靜態方法,final方法。 
2) 如果希望某個方法(非static,非final)不對外公開,可以在方法上添加@WebMethod(exclude=true),阻止對外公開。 
3) 如果一個類上,被添加了@WebService註解,則必須此類至少有一個可以公開的方法,否則將會啓動失敗。 
4) 服務類中不能沒有方法 
5) @WebMethod(exclude=true)屏蔽方法

4、其他調用webservice的方式

4.11、 使用ajax調用

var xhr;
function invoke(){
    if(window.ActiveXObject){
        xhr = new ActiveXObject("Microsoft.XMLHTTP");
    }else{
        xhr = new XMLHttpRequest();
    }
    //指定請求地址
    var url = "http://127.0.0.1:7777/hello?wsdl";
    //定義請求類型和地址和異步
    xhr.open("POST", url, true);
    //設置Content-Type
    xhr.setRequestHeader("Content-Type", "text/xml;charset=UTF-8");
    //指定回調方法
    xhr.onreadystatechange = back;

    var textVal = document.getElementById("mytext").value;
    //組裝消息體的數據
    var data = '<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:q0="http://server.hm.com/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">'
    +'<soapenv:Body>'
    +'<q0:sayHello>'
    +'<arg0>'+textVal+'</arg0>'
    +'</q0:sayHello>'
    +'</soapenv:Body>'
    +'</soapenv:Envelope>';
    xhr.send(data);

}
function back(){
    if(xhr.readyState == 4){
        if(xhr.status == 200){
            var doc = xhr.responseXML;
            alert(doc);
            alert(xhr.responseText);
            var tag = doc.getElementsByTagName("return")[0];
            alert(tag)

        }
    }
}

4.12、通過URLConnection調用

//創建url地址
URL url = new URL("http://192.168.1.104:8080/hello");
//打開連接
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:sayHello>"
        +"<arg0>renliang</arg0> "
      +"</q0:sayHello>"
      +"</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.13、使用jquery調用cxf

$(function(){
        $("#mybutton").click(function(){
            var data = '<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:q0="http://server.web.cxf.rl.com/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">'
                  +'<soapenv:Body>'
                  +'<q0:sayHello>'
                  +'   <arg0>sss</arg0>'
                  +' </q0:sayHello>'
                  +'</soapenv:Body>'
                  +'</soapenv:Envelope>';

                $.ajax({
                    url:'http://localhost:8080/cxf-web-server/services/hello',
                    type:'post',
                    dataType:'xml',
                    contentType:'text/xml;charset=UTF-8',
                    data:data,
                    success:function(responseText){
                        alert($(responseText).find('return').text());
                    },
                    error:function(){
                        alert("error");
                    }
                })
        })
    })

5、wsdl文檔元素名稱修改

自動生成的文檔的名字有時不規範,可以手動進行修改。 
@WebService( 
portName=”myHelloService”,修改端口名字 
serviceName=”HelloServices”,修改服務訪問點集合名字 
name=”HelloService”,修改服務類的名字 
targetNamespace=”hello.rl.com” 修改命名空間名字 
)

@WebResult(name=”sirHello”)修改返回值的元素的父標籤名字 
@WebParam(name=”sir”)修改傳入參數的元素的父標籤名字

6、CXF使用詳解

說到webservice那麼cxf是不得不說的一個東西

1、什麼是cxf

可以理解爲使用webservice的一種框架,用了cxf,可以讓發佈和調用更加簡單並且功能豐富

2、cxf目錄詳解(瞭解)

Apache CXF = Celtix + Xfire 
支持多種協議: 
a) SOAP1.1,1,2 
b) HTTP 
c) CORBA(Common Object Request Broker Architecture公共對象請求代理體系結構,早期語言使用的WS。C,c++,C#) 
d) 並可以與Spring進行快速無縫的整合 
e) 靈活的部署:可以運行有Tomcat,Jboss,Jetty(內置),IBMWS,BeaWS上面。

bin(目錄) 
bin 目錄中是 CXF 框架中所提供的代碼生成、校驗、管理控制檯工具(可執行命令)

docs(目錄) 
CXF 所有類(class)對應的 API 文檔,爲開發者使用 CXF 完成應用開發提供應有的幫助。

etc(目錄) 
包含一個基本的 Service 暴露所需要的 web.xml 文件,及其它的配置文件。

lib(目錄) 
lib 目錄中包含 CXF 及其運行時所需要的和可選的第三方支持類包(.jar 文件),可以根據不同項目所需的 CXF 特性選擇所需要的支持類包。如果不想一一去區分的話,可 
以直接在 Web 項目中包含所有的 CXF 及其運行時所需要的第三方支持類包(.jar 文件)即可。 
其中 cxf-2.0.2-incubator.jar 是 CXF 框架的二進制包文件,包含了全部的模塊(modules),cxf-manifest-incubator.jar 是列表清單文件 manifest jar 。

以下的 jar 包是所有 CXF 項目所必需的: 
cxf.jar 
commons-logging.jar 
geronimo-activation.jar (Or the Sun equivalent) 
geronimo-annotation.jar (Or the Sun equivalent) 
geronimo-javamail.jar (Or the Sun equivalent) 
neethi.jar 
jaxb-api.jar 
jaxb-impl.jar 
stax-api.jar 
XmlSchema.jar 
wstx-asl.jar 
xml-resolver.jar

對於 Java2WSDL 和 WSDL2Java,除了必需的之外,還需要再增加如下 jar 包: 
jaxb-xjc.jar 
veliocity.jar 
velocity-dep.jar

爲了支持 JAX-WS ,除了必需的之外,還需要再增加如下 jar 包: 
jaxws-api.jar 
saaj-api.jar 
saaj-impl.jar 
asm.jar (可選的,但是可以提升包裝類型的性能)

爲了支持 XML 配置,除了必需的之外,還需要再增加如下 jar 包:aopalliance.jar 
spring-beans.jar 
spring-context.jar 
spring-core.jar 
spring.web.jar

爲了獨立的 HTTP 服務支持,除了必需的之外,還需要再增加如下 jar 包:geronimo-servlet.jar 
jetty.jar 
jetty-sslengine.jar 
jetty-util.jar 
sl4j.jar & sl4j-jdk14.jar (可選的,但是可以提升日誌 logging)

爲了支持 Aegis ,除了必需的之外,還需要再增加如下 jar 包: 
jaxen.jar 
jdom.jar 
stax-utils.jar

爲了支持 WS-Security ,除了必需的之外,還需要再增加如下 jar 包:bcprov-jdk14.jar 
wss4j.jar 
xalan.jar 
xmlsec.jar

爲了支持 HTTP Binding ,除了必需的之外,還需要再增加如下 jar 包:jra.jar 
jettison.jar (僅爲 JSON 服務所需的)

licenses(目錄) 
列表了引用第三方 jar 包的相關許可協議。

modules(目錄) 
modules 目錄中包含了 CXF 框架根據不同特性分開進行編譯的二進制包文件。發佈基於 CXF 框架的 Web 項目時,可以選擇使用該目錄下的所有 .jar 文件,也可以選擇 lib 目 錄中的 cxf-2.0.2-incubator.jar 文件。

samples(目錄) 
samples 目錄中包含了所有隨 CXF 二進制包發佈的示例,包含這些示例的源代碼和相關 Web 應用配置文件,可以方便地用 Ant 來編譯運行測試這些示例,來了解 CXF 的開發和

使用的方法。可以通過 samples 目錄和它各個子目錄下的 README.txt 的文件來詳細瞭解示例的編譯與運行的步驟。

3、使用cxf發佈webservice

1、把cxf目錄下lib下面的包全部加入到項目中

2、編寫代碼

1、創建接口

@WebService
@BindingType(value=javax.xml.ws.soap.SOAPBinding.SOAP12HTTP_BINDING)
public interface SayHelloInteface {
    public String sayhellow(String name);
}

2、創建實現類

@WebService
public class SayHellowIntefaceImpl implements SayHelloInteface {

    @Override
    public String sayhellow(String name) {
        return name+"hello world";
    }
}

3、使用cxf類發佈

public static void main(String[] args) {
    //運行
    JaxWsServerFactoryBean jwsf=new JaxWsServerFactoryBean();
    //CXF攔截器
    jwsf.getInInterceptors().add(new LoggingInInterceptor());
    jwsf.getOutInterceptors().add(new LoggingOutInterceptor());

    jwsf.setAddress("http://127.0.0.1:8080/sayHello");
    jwsf.setServiceClass(SayHelloInteface.class);
    jwsf.setServiceBean(new SayHellowIntefaceImpl());
    jwsf.create();
}

4、使用cxf的wsdl2java命令生成客戶端代碼

wsdl2java –d . http://127.0.0.1:6666/helloworld?wsdl

5、調用

調用方式不變

SayHelloIntefaceService ss = new SayHelloIntefaceService();
SayHelloInteface shf=ss.getSayHelloIntefacePort();
String str=shf.sayhellow("lisi");
System.out.println(str);

6、在web項目中發佈webservice

  1. 創建服務接口在接口上加@webservice
  2. 創建服務接口的實現類
  3. 在web.xml中配置CXFServlet

    <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
    <web-app>
        <servlet>
            <servlet-name>cxf</servlet-name>
            <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
        </servlet>
        <servlet-mapping>
            <servlet-name>cxf</servlet-name>
            <url-pattern>/services/*</url-pattern>
        </servlet-mapping>
        <session-config>
            <session-timeout>60</session-timeout>
        </session-config>
    </web-app>
    
  4. 配置cxf-servlet.xml

    <jaxws:server id="bye" address="/bye" serviceClass="com.rl.cxf.web.inter.ByeInter">
        <jaxws:serviceBean>
            <bean class="com.rl.cxf.web.inter.ByeInterImpl"></bean>
        </jaxws:serviceBean>
        <jaxws:outInterceptors>
            <bean class="org.apache.cxf.interceptor.LoggingInInterceptor"></bean>
        </jaxws:outInterceptors>
        <jaxws:inInterceptors>
            <bean class="org.apache.cxf.interceptor.LoggingOutInterceptor"></bean>
        </jaxws:inInterceptors>
    </jaxws:server>
    
  5. 使用wsdl2java生成客戶端代碼
  6. 調用webservice
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章