国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發 > 綜合 > 正文

SOAP凈化有線協議(二):Apache SOAP介紹(2)

2024-07-21 02:21:50
字體:
來源:轉載
供稿:網友
三、帶有javabean的helloworld實例
如前所述,apache soap提供了許多預先構造的串行化和反串行化方法,其中包括為利用java vector、enumeration、數組、javabean作為參數和返回值而提供的串行化器和反串行化器。在這一部分,我將修改helloworld服務,通過一個javabean傳入接收hello信息的用戶名。

3.1、helloworld服務
改寫后的helloworld服務完整代碼如下:


package hello;
public class helloserver
{
public string sayhelloto(string name)
{
system.out.println("sayhelloto(string name)");
return "hello " + name + ", how are you doing?";
}
public string sayhelloto(name thename)
{
system.out.println("sayhelloto(name thename)");
return "hello " + thename.getname() + ", how are you doing?";
}
}
服務的代碼仍舊很簡單,仍舊類似于不用javabean時的helloworld服務。不過,這意味著最復雜的工作都轉移到了客戶端。事實上,這個版本的服務與以前版本的唯一差別在于,現在出現了一個重載的sayhelloto()方法。上面的代碼中重載后的方法用粗體字顯示。

重載的方法需要一個對name javabean的引用。name javabean的定義如下:


package hello;
public class name
{
private string name;
public string getname()
{
return name;
}
public void setname(string name)
{
this.name = name;
}
}
3.2、部署服務
部署一個使用了javabean的服務時,需要為apache soap服務器提供一些額外的信息。因此,現在部署服務的過程稍微復雜一點。

■ 使用管理工具部署服務

要使用管理工具部署這個新版的helloworld服務,首先按照前面所介紹的步驟進行,但這一次不要點擊deploy按鈕。現在,在number of mappings輸入框輸入1,它表示我們將給出一個映射(即name javabean)的信息。緊接mappings之下有一個表格,我們要用到這個表格的第一行。保留encoding style的值為soap,把namespace uri設置成對象的id:在本例中,它是urn:hello。接下來,把local part和java type輸入框設置成name javabean的完整名字,即hello.name。最后,把java to xml serializer和xml to java deserializer輸入框設置成org.apache.soap.encoding.soapenc.beanserializer,這是一個實現了serializer和deserializer接口的類,用來串行化和反串行化name javabean。如果你用到了更多的javabean(比如還有一個address bean),則應該在這個表格中輸入其他bean的信息,同時還應該更新number of mappings輸入框的值,使之反映出表格中實際被使用的行數。

■ 從命令行部署服務

要從命令行進行部署,我們只需修改作為命令行參數傳入的xml部署描述器文件。修改后的xml文件如下所示:


<isd:service xmlns:isd="http://xml.apache.org/xml-soap/deployment" id="urn:hello">
<isd:provider type="java" scope="application" methods="sayhelloto">
<isd:java class="hello.helloserver" static="false"/>
</isd:provider>
<isd:mappings>
<isd:map encodingstyle="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:x="urn:hello" qname="x:hello.name"
javatype="hello.name"
java2xmlclassname="org.apache.soap.encoding.soapenc.beanserializer"
xml2javaclassname="org.apache.soap.encoding.soapenc.beanserializer"/>
</isd:mappings>
</isd:service>
正如在前一個例子中,這些xml代碼所包含的信息和通過web界面的管理工具所提供的信息一樣。

3.3、helloworld客戶程序
和第一個例子一樣,客戶程序更復雜,也更令人感興趣。這里我不再仔細分析整個客戶程序,而是介紹兩個客戶程序版本的不同之處。由于調用方法的一個參數(在本例中,它是唯一的參數)是一個javabean,所以必須手工設置一個類型映射注冊項。這個任務通過如下步驟完成:先創建org.apache.soap.encoding.soapmappingregistry類的一個實例,然后調用它的maptypes()方法。正如maptypes()方法名字所預示的,它用來注冊一個以前未知的類型,比如定制的javabean。maptypes()方法的參數包括要使用的編碼方式、限定的javabean名字、類型的完整類名、串行化器和反串行化器。在本例中,執行串行化任務的是標準的bean串行化器。限定的javabean名字包含一個元素的名字,包括它所屬的名稱空間。在本例中,name javabean的限定名字由名稱空間uri(urn:hello)和本地名字(hello.name)結合構成。請看下面的代碼片斷:


// 創建類型映射注冊器
soapmappingregistry smr = new soapmappingregistry();
beanserializer beanser = new beanserializer();
// 映射類型
smr.maptypes(constants.ns_uri_soap_enc,
new qname("urn:hello", "hello.name"),hello.name.class, beanser, beanser);
接下來,客戶程序必須告訴call對象使用新的注冊器而不是默認的注冊器。為此,我們要調用call對象的setsoapmappingregistry()方法,如下所示:

call.setsoapmappingregistry(smr);
手工設置好類型映射注冊器之后,接下來還必須為call對象設置參數。這一步驟可以按前面介紹的方法完成,不同之處在于,現在我們不再用字符串類型的名字作為參數,而是用javabean作為參數,如下所示:


// 設置調用參數
vector params = new vector();
name thename = new name();
thename.setname(name);
params.addelement(new parameter("name", hello.name.class, thename, null));
call.setparams(params);
客戶程序剩下的部分和原來的版本一樣。listing 3顯示了完整的客戶程序代碼:


listing 3: client2.java
package hello;
import java.net.url;
import java.util.vector;
import org.apache.soap.soapexception;
import org.apache.soap.constants;
import org.apache.soap.fault;
import org.apache.soap.rpc.call;
import org.apache.soap.rpc.parameter;
import org.apache.soap.rpc.response;
import org.apache.soap.encoding.soapmappingregistry;
import org.apache.soap.encoding.soapenc.beanserializer;
import org.apache.soap.util.xml.qname;

public class client2
{
public static void main(string[] args) throws exception
{
if(args.length == 0)
{
system.err.println("usage: java hello.client [soap-router-url] ");
system.exit (1);
}
try
{
url url = null;
string name = null;
if(args.length == 2)
{
url = new url(args[0]);
name = args[1];
}
else
{
url = new url("http://localhost:8080/apache-soap/servlet/rpcrouter");
name = args[0];
}
// 構造調用對象
call call = new call();
call.settargetobjecturi("urn:hello");
call.setmethodname("sayhelloto");
call.setencodingstyleuri(constants.ns_uri_soap_enc);
// 創建類型映射注冊器
soapmappingregistry smr = new soapmappingregistry();
beanserializer beanser = new beanserializer();
// 映射類型
smr.maptypes(constants.ns_uri_soap_enc,
new qname("urn:hello", "hello.name"),
hello.name.class, beanser, beanser);
call.setsoapmappingregistry(smr);
// 設置參數
vector params = new vector();
name thename = new name();
thename.setname(name);
params.addelement(new parameter("name", hello.name.class,
thename, null));
call.setparams(params);
// 發出調用
response resp = null;
try
{
resp = call.invoke(url, "");
}
catch( soapexception e )
{
system.err.println("caught soapexception (" +
e.getfaultcode() + "): " + e.getmessage());
system.exit(-1);
}

// 檢查應答
if( !resp.generatedfault() )
{
parameter ret = resp.getreturnvalue();
object value = ret.getvalue();
system.out.println(value);
}
else
{
fault fault = resp.getfault();
system.err.println("generated fault: ");
system.out.println (" fault code = " + fault.getfaultcode());
system.out.println (" fault string = " + fault.getfaultstring());
}
}
catch(exception e)
{
e.printstacktrace();
}
}
}
四、編譯和運行程序
現在整個程序的開發工作已經完成,該是運行它的時候了。不過,我們首先要編譯服務程序和客戶程序。

創建一個hello目錄,把client1.java、client2.java和helloserver.java復制到這個目錄。我把hello目錄放到了apache soap的示例目錄(即e:/soap-2_0/samples)之下。編譯程序時,classpath中只需包含hello目錄的父目錄(即e:/soap-2_0/samples)、soap.jar和xerces.jar。我用下面的批命令編譯程序:


set classpath=e:/soap-2_0/samples/;e:/soap-2_0/lib/soap.jar;e:/xerces-1_2_0/xerces.jar
javac -d .. helloserver.java client.java client2.java
注意:從hello目錄執行這個批命令文件。

要使用這個服務,除了部署它之外,還需要修改web服務器的classpath,確保web服務能夠找到hello.helloserver類——對于本例,這是指把e:/soap-2_0/samples加入到web服務器的classpath。對classpath進行必要的修改之后,重新啟動web服務器。接下來就可以運行客戶程序了。下面是我運行hello.client的批命令文件:

set classpath=e:/soap-2_0/samples/;e:/soap-2_0/lib/soap.jar;e:/xerces-1_2_0/xerces.jar
java hello.client tarak
這里的classpath和編譯程序時用的classpath相同。

最后,運行hello.client2的批命令文件可以如下:

set classpath=e:/soap-2_0/samples/;e:/soap-2_0/lib/soap.jar;e:/xerces-1_2_0/xerces.jar
java hello.client2 tarak
觀察web服務器的控制臺窗口,看看在運行兩個不同的客戶程序時,helloworld服務的哪些方法正在被調用。

■ 結束語
在這篇文章中,我介紹了如何用apache soap實現來創建簡單的基于soap的服務。在soap實現方面,另一個重要的競爭者是microsoft。遺憾的是,“純”java開發者在使用microsoft實現的時候會有一段艱苦的時光,因為它的實現包含了com對象。

在下一篇文章中,我將介紹apache soap支持的另一種創建服務的方式:使用javascript之類的腳本語言,而不是java。另外,我還要介紹一個很不錯的javascript引擎,即rhino。
■ 參考資源
  • w3c的soap 1.1規范:
    http://www.w3.org/tr/soap/
  • 下載apache soap:
    http://xml.apache.org/dist/soap/
  • 有關ibm soap工程的更多信息:
    http://www.alphaworks.ibm.com/tech/soap4j
  • apache soap可用功能的一個清單:
    http://xml.apache.org/soap/features.html
  • apache許可協議:
    http://www.apache.org/license.txt
  • 下載tomcat 3.1
    http://jakarta.apache.org/builds/jakarta-tomcat/release/v3.1.1/bin/
  • 下載apache xerces 1.2版本:
    http://xml.apache.org/dist/xerces-j/
  • "ms soap sdk vs ibm soap4j: comparison & review," james snell (o'reilly):
    http://windows.oreilly.com/news/soapreview_0600.html
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 克拉玛依市| 察雅县| 莎车县| 济源市| 江阴市| 沙雅县| 安西县| 安图县| 富蕴县| 承德市| 潞西市| 海南省| 丹江口市| 淮阳县| 东乌| 通许县| 沁阳市| 芷江| 福鼎市| 德化县| 正定县| 新源县| 花莲县| 翼城县| 五河县| 锡林浩特市| 大厂| 伊川县| 抚顺市| 泊头市| 凤山市| 塘沽区| 洪洞县| 淮北市| 绩溪县| 华阴市| 灌南县| 明水县| 云和县| 隆子县| 永仁县|