久久亚洲日韩看片无码,亚洲天堂福利视频,亚洲第一页在线观看http://m.tkk7.com/boluobn/category/24672.html大江東去,浪淘盡...zh-cnFri, 31 Aug 2007 07:03:42 GMTFri, 31 Aug 2007 07:03:42 GMT60Web Service深度編程——Axis序列化/反序列化器開發指南http://m.tkk7.com/boluobn/articles/141322.html菠蘿菠蘿Thu, 30 Aug 2007 04:42:00 GMThttp://m.tkk7.com/boluobn/articles/141322.htmlhttp://m.tkk7.com/boluobn/comments/141322.htmlhttp://m.tkk7.com/boluobn/articles/141322.html#Feedback0http://m.tkk7.com/boluobn/comments/commentRss/141322.htmlhttp://m.tkk7.com/boluobn/services/trackbacks/141322.html 

JAVA——咖啡館Velocity 的應用示例- -| 回首頁 | 2005年索引 | - -Web Service 的開發層次
Web Service深度編程——Axis序列化/反序列化器- -
Tag: Web   Service   Axis                            

Web Service深度編程——Axis序列化/反序列化器開發指南


作者:薛谷雨

作者簡介

薛谷雨是NORDSAN(北京)信息科技開發有限公司高級JAVA研發工程師,正致力于企業級異構數據交換的服務器產品的研發,在J2EE和WEB SERVICE方面有較為豐富的開發經驗,你可以通過 rainight@126.com 與他取得聯系。

前言

Axis是Apache組織推出的SOAP引擎,Axis項目是Apache組織著名的SOAP項目的后繼項目。Axis為開發者提供了大量的序列化/反序列化器,能夠基本滿足大部分應用。但在某些情況下,對特定的對象,現有的序列化/反序列化器不能勝任,于是只有開發人員自己實現專用于此對象的序列化/反序列化器插入到Axis中來完成序列化工作。考慮到Web Service是一門新興技術,中文資料大多是泛泛的講解,關于序列化/反序列化器的開發鮮有較為深入的介紹,本文提供一份較為完整的開發指南,并提供了一個十分有用的實現,即序列化JDOM模型的Element,使其可以通過Web 服務在網絡上傳輸,我想這一擴展是許多采用JDOM作為XML解析工具的開發人員都夢寐以求的功能。通過本文的介紹和實例,希望能起到拋磚引玉的作用,讀者在閱讀完本文之后可以輕松的實現針對于任何非符合BEAN規范的對象的序列化/反序列化器。

本文所面對的讀者需要有一定的使用Axis做Web服務開發的開發經驗,因此關于如何Axis的基礎知識并不在本文的介紹范圍,如果讀者對此感興趣,可以參考本文最后的參考資料部分,去相應的網站進行學習。

序列化/反序列化器簡介

序列化/反序列化器在英文中的對應翻譯是Serializer/Deserializer,一個序列化器的功能是遵循一定的映射規則和編碼風格,將一種類型的JAVA對象通過某種特定的機制,轉換成為XML描述的形式;反序列化器的功能是序列化器所做工作的逆操作,兩者相輔相成,成對出現。Axis中的序列化/反序列化器采用設計范式中的工廠模式,每一個Serializer唯一對應一個SerializerFactory;每一個Deserializer唯一對應一個DeserializerFactory。一種類型的JAVA對象具體要采用哪個序列化/反序列化器需要在提供Web服務的服務器和調用Web服務的客戶端分別配置,關于這一部分如何配置,我將在本文后面的內容中進行詳細介紹。Axis已經為開發者提供了豐富的序列化/反序列化器,對于java的基本數據類型,絕大部分常用的容器類(比如數組類型,Vector類型等)都提供了實現,特別是提供了對W3C的DOM對象(比如Document, Element等)和符合Bean規范的JAVA對象提供了功能完善的序列化/反序列化器,因此我們在需要的時候只要在配置文件中配置一下就可以直接使用。如果對象中包含其它類型的對象,比如Vector中包含一組Bean對象,Axis會自動疊代的調用序列化器,最終拼裝成唯一的XML表述。在還原成JAVA對象時,也遵循這樣的疊代操作逆向進行。關于Axis到底內置了哪些序列化/反序列化器,您可以參照Axis的API文檔中包org.apache.axis.encoding.ser下的類的名稱"望文生義"的了解一下,在以后的開發中做到心中有數。但對于一些特殊類型的對象(其實我們自己開發的很大一部分類都是這種特殊類型的對象,很少有絕對符合Bean規范的),需要通過Web服務進行傳遞,我們不得不開發自己的序列化/反序列化器。

開發篇

開發自己的序列化/反序列化器是一個激動人心的工作,但是卻并不復雜,需要做的事情包括實現名成為org.apache.axis.encoding的包中的SerializerFactory,Serializer,DeserializerFactory和Deserializer這四個接口。下面我將結合一個實例來講解序列化/反序列化器的開發方法,希望讀者能夠一邊參看本文提供的源代碼一邊學習。

JDOM作為一款比較"另類"的XML解析工具(因為它不符合W3C的DOM模型,自己另立一套)默默地占領著java世界里的xml解析器的半壁江山,由于其簡潔的設計和方便靈活的API調用,已經漸漸成為了許多開發人員在進行XML開發的首選。但是Axis是建立在W3C的DOM模型的基礎之上,師出名們正派,自然不屑與JDOM為伍。因此當開發人員想將自己已經寫好的基于JDOM的應用模塊采用Web服務的方式發布的時候,不可避免的會遇到如何將JDOM模型下的對象如Document, Element等序列化的問題。在軟件工程師不會自己擴展Axis的序列化/反序列化器的時候,我們只能有兩個辦法達到這個目的,第一個就是更改以前應用模塊內的API設計,使暴露的入口參數和返回值參數都是W3C的對象類型,但這種做法并不現實,因為這一應用模塊往往不是獨立存在,牽一發將動全身,導致舊有系統架構的崩塌;另一種做法就是為這個模塊做一個代理類,它做的工作就對外接收或返回DOM模型的對象,對內轉換成JDOM模型的對象,然后轉發給應用模塊,繁瑣且效率低下。當我們向Axis注入了針對于JDOM模型的序列化/反序列化器后,這一工作便可以由Axis代勞了。下面我們將逐個開發這四個類:

JDomElementSerializerFactory

JDomElementSerializerFactory是一個工廠類,需要通過某種機制注冊到Axis引擎(具體方法見下面"服務器端應用篇");Axis通過調用它,來實例化JDomElementSerializer。Axis 提供了BaseSerializerFactory,這個類是一個抽象類,并實現其中包含了一些可重用的代碼。我們自己開發的工廠類只需簡單繼承這個類就可以。構造函數中需要調用父類的構造函數將序列器類下面是它的源代碼:

package org.apache.axis.encoding.ser;

public class JDomElementSerializerFactory
extends BaseSerializerFactory {

public JDomElementSerializerFactory() {
  super(JDomElementSerializer.class);
}
}

JDomElementSerializer

JDomElementSerializer實現org.apache.axis.encoding.Serializer接口,其核心API是serialize(),我們需要在這個方法的內部完成對JDOM模型的Element的序列化工作,序列化的結果要保存在入口參數傳入的序列化上下文對象(SerializationContext)中:

public void serialize(QName name, Attributes attributes, Object value,
SerializationContext context) throws java.io.IOException {

  if (!(value instanceof Element))
    throw new IOException(
    Messages.getMessage("cant Serialize Object"));

  //獲取符合JDOM的Element對象
  Element root=(Element)value;

  //輸出到StringWriter
  XMLOutputter outputter=new XMLOutputter();//創建一個JDOM的XML輸出器
  StringWriter sw=new StringWriter();
  outputter.output(root,sw);

  //用支持W3C的DOM模型的Xerces解析器解析文本流
  DOMParser parser=new DOMParser();//創建一個DOM的XML解析器
  try {
    parser.parse(new org.xml.sax.InputSource(
        new java.io.StringReader(sw.toString())));
  }catch (Exception ex) {
    throw new java.io.IOException("序列化時產生錯誤");
  }

  //獲取符合DOM模型的Element對象
  org.w3c.dom.Element w3c_root =
      parser.getDocument().getDocumentElement();

  //放入序列化上下文對象中
  context.startElement(name, attributes);
  context.writeDOMElement(w3c_root);
  context.endElement();
}

JDomElementDeserializerFactory

反序列化器的工廠類同序列化器的工廠類一樣的設計,在此不在贅述。代碼:

package org.apache.axis.encoding.ser;

public class JDomElementDeserializerFactory
extends BaseDeserializerFactory {

public JDomElementDeserializerFactory() {
  super(JDomElementDeserializer.class);
}

}

JDomElementDeserializer

用過SAX解析XML的讀者,對反序列化的實現比較容易理解,反序列化也采用了消息觸發的機制,我們只需繼承org.apache.axis.encoding.DeserializerImpl類,并覆蓋其中的onEndElement方法:

/**
  * 在元素結束觸發反序列化的方法
  * @param namespace String 命名空間
  * @param localName String 本地名稱
  * @param context DeserializationContext 反序列化上下文
  * @throws SAXException
  */
public void onEndElement(String namespace, String localName,
  DeserializationContext context) throws SAXException {

  try {
    //從反序列化上下文對象中獲取原始的消息元素
    MessageElement msgElem = context.getCurElement();
    if (msgElem != null) {
    MessageContext messageContext = context.getMessageContext();
    Boolean currentElement = (Boolean) messageContext.getProperty(
        DESERIALIZE_CURRENT_ELEMENT);

    //如果當前的消息元素本身需要反序列化
    if (currentElement != null && currentElement.booleanValue()) {
      org.w3c.dom.Element element = msgElem.getAsDOM();
      org.jdom.input.DOMBuilder db=new org.jdom.input.DOMBuilder();
      value=db.build(element);
      messageContext.setProperty(DESERIALIZE_CURRENT_ELEMENT,
        Boolean.FALSE);
      return;
    }

    //反序列化消息元素中的消息體
    java.util.ArrayList children = msgElem.getChildren();
    if (children != null) {

      //取得消息體
      msgElem = (MessageElement) children.get(0);
      if (msgElem != null) {
        org.w3c.dom.Element ret = msgElem.getAsDOM();
        org.jdom.input.DOMBuilder db=new org.jdom.input.DOMBuilder();

        //用DOMBuilder將DOM模型的Element,轉換成JDOM模型的Element
        value=db.build(ret);
      }
    }

    }
  }
  catch (Exception ex) {
    //錯誤,則記日志,并拋SAXException
    log.error(Messages.getMessage("exception00"), ex);
    throw new SAXException(ex);
  }
}

完成這四個類的編碼,序列化/反序列化器的開發工作基本完成,下面將詳細講解使用及部署方法。

服務器端應用篇

為了簡單起見,我們將一個很簡單的類通過Web服務發布,類中只有一個名稱為hello函數,函數的返回值為JDOM模型的Element。代碼如下:

package test;

import org.jdom.*;
import java.rmi.RemoteException;

public class Sample1 implements java.rmi.Remote{
public Sample1() {
}

public Element hello(String name){
  Element root=new Element("root");
  Element hello=new Element("hello");
  hello.setText("hello,"+name+"!");
  root.addContent(hello);
  return root;
}

}

關于如何將一個類發布成Web服務,在此并不進行介紹,相信讀者可以自己完成,我們只關注如何將序列化/反序列化器加入到我們的Web服務中。打開web服務的配置文件server-config.xml,編輯關于Sample1的服務的配置部分:



注意上面代碼中的粗體字部分,是我們現在要添加的,它表述了如何將序列化反序列化器部署到Web服務中。

部署到Web Server

解壓縮本文后面附帶的源代碼,根目錄下有build.xml文件,讀者需要正確安裝配置好Apache Ant,然后運行

Ant make

編譯后可生成壓縮文件sample.war。將生成的war包部署到Tomcat4.1下,啟動Tomcat,本文默認的Tomcat監聽的http端口為8080。后面的客戶端測試程序也將通過連接這一端口訪問此Web服務。如果讀者的Tomcat不在8080端口上工作,那么客戶端程序也要進行相應的修改。最后啟動Tomcat,這部分操作完成。

客戶端應用篇

下面我們將編寫客戶端程序訪問剛才部署的Web服務,講解如何把我們編寫的序列化/反序列化器加載到客戶端應用程序中,下面是客戶端調用的代碼,注意斜體字部分,是關于序列化/反序列化器的注冊過程(如果你的Web服務器不是工作在8080端口,或采用了其他Web服務名,請自行更改下面程序中的url變量中的值),我們在test包下創建了一個名稱為 Client的類,代碼如下:

package test;

import org.apache.axis.client.Service;
import org.apache.axis.client.Call;
import org.apache.axis.utils.Options;
import javax.xml.namespace.QName;

public class Client {
public Client() {
}

public static void main(String[] args) throws Exception{
  if(args.length<1){
    System.out.println("錯誤:缺少參數");
    System.exit(0);
}
  //Web服務的URL
  String url="http://localhost:8080/sample/services/Sample1";
  Service service=new Service();
  Call call = (Call)service.createCall();
  call.setTargetEndpointAddress(url);

  //注冊序列化/反序列化器
  call.registerTypeMapping(org.jdom.Element.class,
      new QName("http://jdom.org","Element"),
    new org.apache.axis.encoding.ser.JDomElementSerializerFactory(),
    new org.apache.axis.encoding.ser.JDomElementDeserializerFactory());

  //設置調用方法
  call.setOperationName(
      new javax.xml.namespace.QName("http://test", "hello"));

  //Web服務調用
  java.lang.Object _resp = call.invoke(new java.lang.Object[] {args[0]});

  //輸出到屏幕
  org.jdom.output.XMLOutputter out=new org.jdom.output.XMLOutputter();
  out.output( (org.jdom.Element) _resp, System.out);

}

}

編譯后運行該程序,在控制臺窗口工程的根目錄下輸入

run world ( 其中"world"為調用例程中API的入口參數)

經過一次web通訊,一兩秒后屏幕將顯示運行結果:


  hello,world!


至此我們完成了一次Web服務的訪問過程。如果在程序執行過程中,我們用TCP Moniter之類的工具監視這一次訪問中的在網絡中流入流出的數據,可以看到客戶端發起調用的xml數據流如下:

POST /sample/services/Sample1 HTTP/1.0
Content-Type: text/xml; charset=utf-8
Accept: application/soap+xml,
application/dime, multipart/related, text/*
User-Agent: Axis/1.1
Host: 127.0.0.1
Cache-Control: no-cache
Pragma: no-cache
SOAPAction: ""
Content-Length: 430


  world




服務器端返回的結果的XML輸出流如下:

HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Date: Wed, 31 Mar 2004 06:42:18 GMT
Server: Apache Coyote/1.0
Connection: close

 
  hello,world!
 

結語

以上詳細講解了Axis的序列化/反序列化器的開發過程,相信讀者已經從中學到了不少知識,并能夠應用于自己的項目開發中去。通過掌握這一技術,我們將更為深刻的理解Axis的內部結構和Web服務的工作機理,這些經驗是市面上那些泛泛的講解JAVA Web服務的參考書上所學不到的。后續的文章還將向您展示一些在Java Web服務深度開發中的高級技術,讓您真正駕馭Axis。

參考資料

附件中提供了本文中的全部源碼,它是一個完整的工程,可以參考學習。
在apache的網站您可以獲得最新的Axis庫及其開發文檔:http://ws.apache.org/axis/ 本文中提到的Tomcat Web服務器可以在這里免費獲得:http://jakarta.apache.org/tomcat/index.html
《IBM DEVELOPWORK》中一個關于web服務的教程《從JAVA類創建web服務》,是您快速掌握Web服務開發的很好教材,初學者可以進行學習。
JDOM類庫可以去www.jdom.org下載,CSDN上有一篇不錯的文章可以讓您快速掌握JDOM的使用方法。http://www.csdn.net/develop/Read_Article.asp?Id=13806



菠蘿 2007-08-30 12:42 發表評論
]]>
Axis開發Webservice傳Bean對象返回String串的實例http://m.tkk7.com/boluobn/articles/141311.html菠蘿菠蘿Thu, 30 Aug 2007 04:32:00 GMThttp://m.tkk7.com/boluobn/articles/141311.htmlhttp://m.tkk7.com/boluobn/comments/141311.htmlhttp://m.tkk7.com/boluobn/articles/141311.html#Feedback0http://m.tkk7.com/boluobn/comments/commentRss/141311.htmlhttp://m.tkk7.com/boluobn/services/trackbacks/141311.htmlAxis開發Webservice傳Bean對象返回String串的實例 這幾天也一直在為了設計與實現一個業務平臺,想用Webservice 來作為核心技術來實現,也一直想精溢求精地把這個東東搞好, 突然覺得好久沒來這里寫日志了.呵,時間如白駒過隙啊!

 

  對于webService 以前也接觸過.但只是皮毛,這次可是來真格的.來就來吧,年輕人這就是機會.一定得把握好,干它一票! 呵,就在網上到處找找啊,在本地機器上左試試,右試試啊, 什么法子都用一遍。就不信搞不定它,小樣!

 

  網上的例子也比較散,比較簡易的,達不我想要的業務水平,只能慢慢搜索與摸索吧。。。。。。就這樣天天想著這事,也沒什么心情來這里寫寫。

 

  近些天,也快回深圳了,定在下周四動身吧。這邊的工作也得告一節了。把我前一些日子,搞一個完整的Samples 放到這里來,與大家共享。希望對有心人有些啟發,也希望高人指點與點評。。。。。。。、

 

   ****************************************************
   *Axis開發Webservice傳Bean對象返回String串的實例.rtf*
   ****************************************************

 

在ECLIPSE 里新建一工程,其次建包,再次建類,
基本包:samples.userguide.example5
基本類: Order.java
       
內容:
    *  Order.java *
*《********************************

package samples.userguide.example5;

/**
 * This is a JavaBean which represents an order for some products.
 * Copyright: Copyright (c) 2007-1
 * @author Black skin (blackskin@126.com)
 * @version 1.0
 */
public class Order {
 /** Who's ordering */
 private String customerName;

 /** Where do they live */
 private String shippingAddress;

 /** Which items do we want */
 private String itemCodes[];

 /** And how many */
 private int quantities[];

 // Bean accessors

 public String getCustomerName() {
  return customerName;
 }

 public void setCustomerName(String name) {
  customerName = name;
 }

 public String getShippingAddress() {
  return shippingAddress;
 }

 public void setShippingAddress(String address) {
  shippingAddress = address;
 }

 public String[] getItemCodes() {
  return itemCodes;
 }

 public void setItemCodes(String[] items) {
  itemCodes = items;
 }

 public int[] getQuantities() {
  return quantities;
 }

 public void setQuantities(int[] quants) {
  quantities = quants;
 }
}

********************************》*

 

主服務包: samples.userguide.example5
主服務類: BeanService.java
         
 如下:
    * BeanService.java *
**《*******************************
package samples.userguide.example5;

/**
 * This is a JavaBean which represents an order for some products.
 * Copyright: Copyright (c) 2007-1
 * @author Black skin (blackskin@126.com)
 * @version 1.0
 */

public class BeanService {
 public String processOrder(Order order) {
  String sep = System.getProperty("line.separator");

  String response = "Hi, " + order.getCustomerName() + "!" + sep;

  response += sep + "You seem to have ordered the following:" + sep;

  String[] items = order.getItemCodes();
  int[] quantities = order.getQuantities();

  for (int i = 0; i < items.length; i++) {
   response += sep + quantities[i] + " of item : " + items[i];
  }

  response += sep + sep + "If this had been a real order processing system, "
            + sep + "we'd probably have charged you about now.";

  return response;
 }

 public static void main(String[] args) throws Exception{
  /** Who's ordering */
  String customerName = "Black Skin";
  /** Where do they live */
  String shippingAddress = "001 xingan Street, bayuquan, YK";
  /** Which items do we want */
  String[] items = new String[] { "apple", "160ml-Milk" };
  /** And how many */
  int[] quantities = new int[] { 2, 4 };
  /** request class init() */
  Order order = new Order();
  order.setCustomerName(customerName);
  order.setShippingAddress(shippingAddress);
  order.setItemCodes(items);
  order.setQuantities(quantities);
  /** server class init() */
  BeanService beanservice = new BeanService();
  String result = beanservice.processOrder(order);
  /** OutPut the result */
  System.out.println(" " + result); 
 }
 
}

********************************》*

 

 BeanService.java里有個本地測試方法(samples.userguide.example5.BeanService.main()),來測試此應用的可運行性;


到此,服務端類寫完了,接著來把此類的方法發布成 WebService 接口

手寫一個deploy.wsdd 文件,可以參考下面的例子:
      *deploy.wsdd例子*
*《********************************
<?xml version="1.0" encoding="utf-8"?>
<deployment xmlns="http://xml.apache.org/axis/wsdd/" xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
<service name="服務名" provider="java:RPC">
<parameter name="className" value="服務類文件的實際路徑(包括包的信息)"/>
<parameter name="allowedMethods" value="*(即為所有方法都可訪問,如要指定多個可用空格分隔開)"/>
<parameter name="allowedRoles" value="user"/>
<parameter name="scope" value="Session"/>
<requestFlow>
<handler type="java:org.apache.axis.handlers.SimpleAuthenticationHandler"/>
</requestFlow>
</service>
</deployment>
********************************》*

顯然,簡單,造一個deploy.wsdd 信手捏來,如下:
      *deploy.wsdd*
*《********************************
<deployment xmlns="http://xml.apache.org/axis/wsdd/" xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
    <service name="OrderProcessor" provider="java:RPC">
        <parameter name="className" value="samples.userguide.example5.BeanService"/>
        <parameter name="allowedMethods" value="processOrder"/>
        <beanMapping qname="myNS:Order" xmlns:myNS="urn:BeanService" languageSpecificType="java:samples.userguide.example5.Order"/>
    </service>
</deployment>
********************************》*

有了deploy.wsdd文件了,接著通過它來生成 server-config.wsdd.
OK! 用命令直接生成就行;在deploy.wsdd 的文件夾下新建一個 makeWsdd.bat.
其中的寫法有下面的例子來參考:

      * makeWsdd.bat 例子*
*《********************************
set AXISCLASSPATH= “應用發布的路徑”
set AXIS_LIB= “AXIS框架的內部JAR包LIB路徑”
SET CLASSPATH=.;%CLASSPATH%;%AXIS_LIB%\wsdl4j-1.5.1.jar;%AXIS_LIB%\axis.jar;%AXIS_LIB%\jaxrpc.jar;
%AXIS_LIB%\saaj.jar;%AXIS_LIB%\commons-discovery-0.2.jar;%AXIS_LIB%\commons-logging-1.0.4.jar

java -Djava.ext.dirs=%AXISCLASSPATH% org.apache.axis.client.AdminClient
 -S服務名\services\AdminService -p端口號(如果你的端口號不是默認的8080需要指定。
 例如:8899)deploy.wsdd
********************************》*


如此,我寫了一“makeWsdd.bat”文件。如下:

      * makeWsdd.bat*
*《********************************
set AXISCLASSPATH=C:\Axis_webservice\Tomcat_4.1\webapps\axis
set AXIS_LIB=C:\axis-1_4\lib
SET CLASSPATH=.;%CLASSPATH%;%AXIS_LIB%\wsdl4j-1.5.1.jar;%AXIS_LIB%\axis.jar;%AXIS_LIB%\jaxrpc.jar;
%AXIS_LIB%\saaj.jar;%AXIS_LIB%\commons-discovery-0.2.jar;%AXIS_LIB%\commons-logging-1.0.4.jar

java -Djava.ext.dirs=%AXISCLASSPATH% org.apache.axis.client.AdminClient
 -SBeanServer\services\AdminService -p 8080 deploy.wsdd
********************************》*

保存好,接下來架設Webservice.

環境架設:
首先,安裝JDK...(略)...本例用JDK版本號V1.4.
其次,安裝Tomcat...(略)...本例用Tomcat版本號V4.1.
再次,AXIS...(略)...本例用AXIS版本號V1.4. 去AXIS官方網站:http://www.apache.org下載AXIS,解壓后得,
   |- axis-1_4
        |- docs
     |- ..(略)...
 |- lib
     |- axis.jar
     |- axis-ant.jar
     |- commons-discovery-0.2.jar
     |- commons-logging-1.0.4.jar
     |- jaxrpc.jar
     |- log4j-1.2.8.jar
     |- log4j.properties
     |- saaj.jar
     |- wsdlj-1.5.1.jar
 |- samples
     |- ..(略)...
 |- webapps
     |- axis
        |- ..(略)...
 |- xmls
     |- ..(略)...
    將解壓后,C:\axis-1_4\webapps 目錄下的 axis 目錄 Copy 到 tomcat/webapps目錄(C:\Axis_webservice\Tomcat_4_1\webapps)下,

架設AXIS:
首先,將deploy.wsdd文件Copy到 %AXISCLASSPATH%/WEB-INF 目錄下;
其次,將之前的類編譯后,連路徑一起Copy到 %AXISCLASSPATH%/WEB-INF/classes目錄下,
最后,將tomcat的 catalina 服務啟動.
(即:C:\Axis_webservice\Tomcat_4.1\bin,

   [特別注意的是:]
       A。tomcat務必啟動。
       B。在寫如上的命令行時,務必注意參數的寫法。“-D” 與 “-S”與其值間不能有空格。切記!
       C。各XX的路徑里,最好是不要有空格,因為JAVA里對大小寫與路徑空格有校驗。
,)

測試:
命令行啟動方法;運行"cmd",在命令行里寫:"cd C:\Axis_webservice\Tomcat_4.1\bin",回車,再寫:"  catalina run ",回車,OK!
后臺會報錯:
"
- Unable to find config file.  Creating new servlet engine config file: /WEB-INF/server-config.wsdd
2007-1-20 10:07:48 org.apache.coyote.http11.Http11Protocol start
信息: Starting Coyote HTTP/1.1 on port 8080
"
說明,在../WEB-INF/下沒有"server-config.wsdd",暫時忽略。
在IE地址欄寫:http://localhost:8080/axis
可見,axis 歡迎首頁,點擊 "list" 便可看到默認情況下發布了兩個服務下各有一個方法。一切準備工作已經OK!


再回到,剛才我們寫的那個批處理文件:" makeWsdd.bat",
直接雙擊,便可執行, 有一個警告,可以忽略的。執行完成后,在相應的
%AXISCLASSPATH%/WEB-INF下便有一“server-config.wsdd”文件,如下:

      *server-config.wsdd*
*《********************************

<?xml version="1.0" encoding="UTF-8"?>
<deployment xmlns="http://xml.apache.org/axis/wsdd/" xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
 <globalConfiguration>
  <parameter name="sendMultiRefs" value="true"/>
  <parameter name="disablePrettyXML" value="true"/>
  <parameter name="adminPassword" value="admin"/>
  <parameter name="attachments.Directory" value="C:\Axis_webservice\Tomcat_4.1\webapps\axis\WEB-INF\attachments"/>
  <parameter name="dotNetSoapEncFix" value="true"/>
  <parameter name="enableNamespacePrefixOptimization" value="false"/>
  <parameter name="sendXMLDeclaration" value="true"/>
  <parameter name="sendXsiTypes" value="true"/>
  <parameter name="attachments.implementation" value="org.apache.axis.attachments.AttachmentsImpl"/>
  <requestFlow>
   <handler type="java:org.apache.axis.handlers.JWSHandler">
    <parameter name="scope" value="session"/>
   </handler>
   <handler type="java:org.apache.axis.handlers.JWSHandler">
    <parameter name="scope" value="request"/>
    <parameter name="extension" value=".jwr"/>
   </handler>
  </requestFlow>
 </globalConfiguration>
 <handler name="LocalResponder" type="java:org.apache.axis.transport.local.LocalResponder"/>
 <handler name="URLMapper" type="java:org.apache.axis.handlers.http.URLMapper"/>
 <handler name="Authenticate" type="java:org.apache.axis.handlers.SimpleAuthenticationHandler"/>
 <service name="AdminService" provider="java:MSG">
  <parameter name="allowedMethods" value="AdminService"/>
  <parameter name="enableRemoteAdmin" value="false"/>
  <parameter name="className" value="org.apache.axis.utils.Admin"/>
  <namespace>http://xml.apache.org/axis/wsdd/</namespace>
 </service>
 <service name="Version" provider="java:RPC">
  <parameter name="allowedMethods" value="getVersion"/>
  <parameter name="className" value="org.apache.axis.Version"/>
 </service>
 <service name="OrderProcessor" provider="java:RPC">
  <parameter name="allowedMethods" value="processOrder"/>
  <parameter name="className" value="samples.userguide.example5.BeanService"/>
  <beanMapping languageSpecificType="java:samples.userguide.example5.Order" qname="ns1:Order" xmlns:ns1="urn:BeanService"/>
 </service>
 <transport name="http">
  <requestFlow>
   <handler type="URLMapper"/>
   <handler type="java:org.apache.axis.handlers.http.HTTPAuthHandler"/>
  </requestFlow>
  <parameter name="qs:list" value="org.apache.axis.transport.http.QSListHandler"/>
  <parameter name="qs:wsdl" value="org.apache.axis.transport.http.QSWSDLHandler"/>
  <parameter name="qs.list" value="org.apache.axis.transport.http.QSListHandler"/>
  <parameter name="qs.method" value="org.apache.axis.transport.http.QSMethodHandler"/>
  <parameter name="qs:method" value="org.apache.axis.transport.http.QSMethodHandler"/>
  <parameter name="qs.wsdl" value="org.apache.axis.transport.http.QSWSDLHandler"/>
 </transport>
 <transport name="local">
  <responseFlow>
   <handler type="LocalResponder"/>
  </responseFlow>
 </transport>
</deployment>


********************************》*
 
再去打開:"http://localhost:8080/axis/servlet/AxisServlet",或者,再刷新。
便可以看到,我們新發布的一個webservice接口服務,其名為:"OrderProcessor "
此服務下的個方法:其名為:"processOrder "。

點擊服務對應的"(WSDL)"可見服務WSDL描述內容。在其中也可以得服務的訪問地址:
"http://localhost:8080/axis/services/OrderProcessor?wsdl"
服務器端的開發,搞定了!

-:)    -:)    -:)  

接下來,準備開發,客戶端的開發。

 


      * Client.java *
*《********************************
package samples.userguide.example5;

/**
 * This is a JavaBean which represents an order for some products.
 * Copyright: Copyright (c) 2007-1
 * @author Black skin (blackskin@126.com)
 * @version 1.0
 */

import java.net.URL;

import org.apache.axis.AxisFault;
import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
import org.apache.axis.utils.Options;

import javax.xml.namespace.QName;
import javax.xml.rpc.ParameterMode;

public class Client {
 public static void main(String[] args) throws Exception {
  //Options options = new Options(args);
  String urlWsdl = "http://localhost:8080/axis/services/OrderProcessor?wsdl";

  Order order = new Order();
  order.setCustomerName("Black Skin");
  order.setShippingAddress("275 Grove Street, Newton, MA");

  String[] items = new String[] { "apple", "160ml-Milk" };
  int[] quantities = new int[] { 8, 4 };

  order.setItemCodes(items);
  order.setQuantities(quantities);

  Service service = new Service();
  Call call = (Call) service.createCall();
  QName qn = new QName("urn:BeanService", "Order");

  call.registerTypeMapping(Order.class, qn,
    new org.apache.axis.encoding.ser.BeanSerializerFactory(
      Order.class, qn),
    new org.apache.axis.encoding.ser.BeanDeserializerFactory(
      Order.class, qn));
  String result;
  try {
   //call.setTargetEndpointAddress(new java.net.URL(options.getURL()));
   call.setTargetEndpointAddress(new java.net.URL(urlWsdl));
   call.setOperationName(new QName("OrderProcessor", "processOrder"));
   call.addParameter("arg1", qn, ParameterMode.IN);
   call.setReturnType(org.apache.axis.encoding.XMLType.XSD_STRING);

   result = (String) call.invoke(new Object[] { order });
  } catch (AxisFault fault) {
   result = "Error : " + fault.toString();
  }

  System.out.println(result);
 }
}

********************************》*

oK! 到此,一個完整的Webservice例子就搞定了。

另外,Axis 還提供了一些工具,如:" wsdl2java "、" java2wsdl "

處理的方式與方法:
  java2wsdl:
   1. 以上為例,在以上工程的class輸出目錄新建一BAT文件:名為:“java2wsdl.bat”
   2. 其內容為:
         * java2wsdl.bat *
*《********************************
set AXIS_LIB=C:\axis-1_4\lib
SET CLASSPATH=.;%CLASSPATH%;%AXIS_LIB%\wsdl4j-1.5.1.jar;%AXIS_LIB%\axis.jar;%AXIS_LIB%\jaxrpc.jar;%AXIS_LIB%\saaj.jar;%AXIS_LIB%\commons-discovery-0.2.jar;%AXIS_LIB%\commons-logging-1.0.4.jar

java org.apache.axis.wsdl.Java2WSDL -o Order.wsdl  -l"http://localhost:8080/axis/services/OrderProcessor" -n "urn:BeanService"  -p"samples.userguide.example5.Order" "urn:Order" samples.userguide.example5.BeanService
********************************》*

把AXIS_LIB設為正確的本地包路徑,再運行“java2wsdl.bat”,
便可以在目錄下看到一個文件:“Order.wsdl”,通過這個WSDL文件,可以生成Webservice接口服務的框架,
既可以是服務器端,也可以是客戶端框架。其細節,可以參考下一節。


處理的方式與方法:
  wsdl2java :
   1. 以上為例,把Order.wsdl拷貝過來,在其目錄下新建一BAT文件:名為:“wsdl2java.bat”
   2. 其內容為:
       * wsdl2java.bat *
*《********************************
set AXIS_LIB=C:\axis-1_4\lib
SET CLASSPATH=.;%CLASSPATH%;%AXIS_LIB%\wsdl4j-1.5.1.jar;%AXIS_LIB%\axis.jar;%AXIS_LIB%\jaxrpc.jar;%AXIS_LIB%\saaj.jar;%AXIS_LIB%\commons-discovery-0.2.jar;%AXIS_LIB%\commons-logging-1.0.4.jar

java org.apache.axis.wsdl.WSDL2Java Order.wsdl
********************************》*

或者有另外的作法:把服務端的應用啟動,直接寫成:

java org.apache.axis.wsdl.WSDL2Java http://localhost:8080/axis/services/OrderProcessor?wsdl

保存好后,運行這個BAT文件,
便會自動生成:
BeanService_pkg\
  BeanService.java
  BeanServiceService.java
  BeanServiceServiceLocator.java
  OrderProcessorSoapBindingStub.java   
  Order.java

ok.



菠蘿 2007-08-30 12:32 發表評論
]]>
使用Apache Axis部署 Web服務時的常見問題及其解決方法http://m.tkk7.com/boluobn/articles/137337.html菠蘿菠蘿Thu, 16 Aug 2007 09:04:00 GMThttp://m.tkk7.com/boluobn/articles/137337.htmlhttp://m.tkk7.com/boluobn/comments/137337.htmlhttp://m.tkk7.com/boluobn/articles/137337.html#Feedback0http://m.tkk7.com/boluobn/comments/commentRss/137337.htmlhttp://m.tkk7.com/boluobn/services/trackbacks/137337.html本文詳細介紹了在Linux環境下以Apache Axis+ Resin作為Web服務平臺部署Web服務時的常見問題及解決方法。衷心希望本文對Web服務的開發人員或對Web服務感興趣的讀者能起到一定的幫助作用。

1 引言


隨著Web服務技術的發展和成熟,其方便性和易用性已逐漸被人們所接受,越來越多的合作伙伴之間開始利用Web服務來實現合作方之間的數據接口。使用Apache Axis和Linux平臺是一種低成本的Web服務解決方案,但Apache Axis文檔的FAQ對開發者來說內容還不夠豐富,本文作者將自己使用Axis時遇到的問題和解決方法整理成文,奉獻給Web服務的開發人員和對此感興趣的讀者朋友,旨在幫助大家節約一些寶貴的時間。有關Web服務的基礎知識,讀者可以閱讀參考文獻中推薦的文檔。作者未在文中介紹Apache和Resin的安裝方法,讀者可以參考相關網站的說明文檔。

作者使用的軟件環境如下。

操作系統:Red Hat Linux 7.2

Web服務器: Apache 1.3.27

應用服務器:Resin 2.1.8 ( http://www.caucho.com/ )

SOAP服務器:Apache Axis 1.1

XML解析器:Xerces 2.5.0,Xalan 2.5.1

JDK版本:JDK 1.4.1

2 使用Axis時的常見問題及其解決方法

2.1 Axis運行需要哪些jar文件

對Axis解包后,將axis-1_1/webapps/axis/WEB-INF/lib/目錄下的jar文件復制到/usr/local/apache/htdocs/WEB-INF/lib目錄下(Web應用程序的目錄)。應包括以下jar文件。

axis-ant.jar
            axis.jar
            commons-discovery.jar
            commons-logging.jar
            jaxrpc.jar
            log4j-1.2.8.jar
            name.txt
            saaj.jar
            wsdl4j.jar
            

如果需要使用axis提供的測試頁面,還要將axis-1_1/webapps/axis/目錄下的文件復制到/usr/local/apache/htdocs/axis/目錄下。應包括以下募?

EchoHeaders.jws
            fingerprint.jsp
            happyaxis.jsp
            index.html
            

2.2 應該使用哪一種XML解析器

XML解析器選用不當,經常會導致使用Apache Axis時出現一些莫名其妙的問題。

由于Apache Axis 并未對Resin內置的xml解析器進行過測試,因此推薦讀者使用已通過測試的Xerces xml解析器。可以從 http://xml.apache.org/xalan-j/index.html 處下載Xalan的Java版XSLT處理器,其中包含了Xerces的Java版XML解析器,不需要再單獨下載xml解析器。

Xalan 2.5.1解包后,將bin/目錄下的xercesImpl.jar、xml-apis.jar和xalan.jar復制到resin安裝目錄的lib/目錄下,例如/usr/local/resin/lib。

編輯/etc/目錄下的profile文件,找到設置CLASSPATH環境變量的位置,在其后加入下面的內容(B shell)。

XMLPARSER=$RESIN_HOME/lib/xalan.jar:$RESIN_HOME/lib/xercesImpl.jar:$RESIN_HOME/lib/xml-apis.jar
            export CLASSPATH=$XMLPARSER:$CLASSPATH
            

2.2.1 注意事項
如果CLASSPATH中包含其它的XML解析器設置,應將其從CLASSPATH環境變量的設置中去掉,以免發生沖突。

2.3 如何在Resin中使用Xerces的XML解析器

通過修改resin.conf將resin的XmlParser置換為Xerces的XmlParser。在resin.conf對應的Web應用程序配置中加入以下設置。

<system-property javax.xml.transform.TransformerFactory="org.apache.xalan.processor.TransformerFactoryImpl"/>
            <system-property javax.xml.parsers.DocumentBuilderFactory="org.apache.xerces.jaxp.DocumentBuilderFactoryImpl"/>
            <system-property javax.xml.parsers.SAXParserFactory="org.apache.xerces.jaxp.SAXParserFactoryImpl"/>
            <system-property org.xml.sax.driver="org.apache.xerces.parsers.SAXParser"/>
            

配置完成后重新啟動Resin。

2.4 如何排除XML解析器出現的異常

2.4.1 問題描述

使用http://test.com/axis查看已部署的服務時出現Axis內部錯,顯示有關WSDD配置的異常信息。如果把WEB-INF目錄下的server-config.wsdd刪除,再查看就正常了,但只能看到AdminService和Version兩個系統缺省的服務,后來部署的服務都看不到了。

2.4.2 原因分析

Axis會在WEB應用程序的WEB-INF/目錄下自動生成一個名字為server-config.wsdd的xml文件,其中記錄了已部署的WEB服務。每部署一個新的WEB服務時,Axis都會將新服務的描述信息加入到server-config.wsdd中。

故障站點使用的XmlParser是resin內置的XmlParser,Axis并未對其對進行過兼容性測試,查看WEB服務信息時需要從server-config.wsdd(這是一個xml文件)取得已部署的WEB服務描述信息,當server-config.wsdd的內容較復雜時,resin內置的XmlParser因某種原因出現異常,導致Axis內部錯誤。Server-config.wsdd中記錄的Web服務描述信息較少時不會出現異常。

2.4.3 解決方法

修改resin.conf,將resin的XmlParser置換為Xerces的XmlParser。置換方法參見2.3節。

2.4.4 小結

如果Axis報告的錯誤中有關于xml解析器的錯誤,建議讀者參照本小節描述的方法更換應用服務器的xml解析器,將會有助于問題的解決。

2.5 如何將Axis集成到Resin或其它應用服務器

Axis是以Servlet的方式運行的,而Resin的作用相當于Servlets容器(Container),因此只要配置得當,就可以使Axis在Resin環境中運行,這一點也適用于Resin以外的其它應用服務器。在Resin中配置Axis的方法如下。

將axis-1_1/webapps/axis/WEB-INF/web.xml中的Servlet配置項復制到resin.conf中對應的Web應用程序配置中。通常應包括以下內容。

 <!-- Axis Web-Service Configuration Start -->
            <servlet>
            <servlet-name>AxisServlet</servlet-name>
            <display-name>Apache-Axis Servlet</display-name>
            <servlet-class>
            org.apache.axis.transport.http.AxisServlet
            </servlet-class>
            </servlet>
            <servlet>
            <servlet-name>AdminServlet</servlet-name>
            <display-name>Axis Admin Servlet</display-name>
            <servlet-class>
            org.apache.axis.transport.http.AdminServlet
            </servlet-class>
            <load-on-startup>100</load-on-startup>
            </servlet>
            <servlet>
            <servlet-name>SOAPMonitorService</servlet-name>
            <display-name>SOAPMonitorService</display-name>
            <servlet-class>
            org.apache.axis.monitor.SOAPMonitorService
            </servlet-class>
            <init-param>
            <param-name>SOAPMonitorPort</param-name>
            <param-value>5001</param-value>
            </init-param>
            <load-on-startup>100</load-on-startup>
            </servlet>
            <servlet-mapping>
            <servlet-name>AxisServlet</servlet-name>
            <url-pattern>/axis/servlet/AxisServlet</url-pattern>
            </servlet-mapping>
            <servlet-mapping>
            <servlet-name>AxisServlet</servlet-name>
            <url-pattern>*.jws</url-pattern>
            </servlet-mapping>
            <servlet-mapping>
            <servlet-name>AxisServlet</servlet-name>
            <url-pattern>/services/*</url-pattern>
            </servlet-mapping>
            <servlet-mapping>
            <servlet-name>SOAPMonitorService</servlet-name>
            <url-pattern>/SOAPMonitor</url-pattern>
            </servlet-mapping>
            <!-- uncomment this if you want the admin servlet -->
            <!--
            <servlet-mapping>
            <servlet-name>AdminServlet</servlet-name>
            <url-pattern>/axis/servlet/AdminServlet</url-pattern>
            </servlet-mapping>
            -->
            <!-- currently the W3C havent settled on a media type for WSDL;
            http://www.w3.org/TR/2003/WD-wsdl12-20030303/#ietf-draft
            for now we go with the basic 'it's XML' response -->
            <mime-mapping>
            <extension>wsdl</extension>
            <mime-type>text/xml</mime-type>
            </mime-mapping>
            <mime-mapping>
            <extension>xsd</extension>
            <mime-type>text/xml</mime-type>
            </mime-mapping>
            <!-- Axis Web-Service Configuration End -->
            

2.6 Axis提供了哪些開發工具

Apache Axis提供了WSDL2Java和Java2WSDL兩個開發工具。

WSDL2Java利用已知的WSDL文件生成服務端和客戶端代碼。該WSDL文件可以是由合作伙伴提供的,也可以是利用Java2WSDL生成的。Java2WSDL根據已有的Java類文件生成WSDL文件,Java類文件可以是接口類文件,并不需要實現細節。

此外Axis還提供了SoapMonitorApplet和TCPMon工具,可用于監測Web服務。

2.7 如何生成Web服務的服務端和客戶端代碼

2.7.1 生成或取得WSDL文件

Java2WSDL是Axis提供的利用Java類文件得到WSDL文件的工具。類文件可以使用接口文件編譯生成,例如下面的接口文件SoftwarePrice.java。

package samples.userguide.example6;
            /**
            * Interface describing a web service to set and get software prices.
            **/
            public interface SoftwarePrice {
            public void setWidgetPrice(String softWareName, String price);
            public String getWidgetPrice(String softWareName);
            

編譯SoftwarePrice.java。

javac SoftwarePrice.java
            

將SoftwarePrice.class復制到正確的package路徑下。

執行下面的命令:

java org.apache.axis.wsdl.Java2WSDL -o sp.wsdl  -l"http://test.com:80/services/SoftwarePrice" -n "urn:SoftwarePrice"
            -p"samples.userguide.example6" "urn:Example6" samples.userguide.example6.SoftwarePrice
            

各參數的含義如下。

-o:指定輸出的WSDL文件的文件名。
            
-l:指定服務的位置。
-n:WSDL文件的目標名字空間。
-p:指定從package到名字空間的映射,這里可以有多個映射。

最后面的類文件包含了Web服務的接口。

該命令執行后,將生成sp.wsdl文件。

如果按CLASSPATH的設置找不到指定的類文件,Axis將報告異常,如下所示。

java.lang.ClassNotFoundException: samples.userguide.example6.SoftwarePrice
            at java.net.URLClassLoader$1.run(URLClassLoader.java:198)
            at java.security.AccessController.doPrivileged(Native Method)
            ……
            

如果出現上面的問題,請檢查是否已將有關類文件復制到正確的位置或CLASSPATH設置是否正確。

生成WSDL文件以后,就可以利用Axis提供的WSDL2Java工具生成Web服務的服務端代碼和客戶端代碼了。

2.7.1.1 注意事項

WSDL文件也可以由合作伙伴提供。這種情況下合作伙伴往往是Web服務的提供者或標準接口的制定者,開發者只要按照既定的WSDL文件生成客戶端或服務端代碼就可以了。

2.7.2 生成客戶端或服務端代碼

WSDL2Java工具用于從WSDL文件生成客戶端存根(stub)代碼,服務端框架(skeleton)代碼以及WSDL中的數據類型文件(生成與之對應的Java代碼)。開發人員只需向框架代碼中補充相關的業務邏輯代碼即可得到完整的Web服務代碼,因此該工具極大地減輕了開發人員的編碼負擔。WSDL2Java的使用舉例如下。

java org.apache.axis.wsdl.WSDL2Java --server-side --skeletonDeploy true MyService.wsdl
            

執行上述命令后將生成下列文件。

No. 文件 用途
1. deploy.wsdd MyService服務的部署描述文件
2. MyService.java MyService服務的接口文件
3. MyServiceService.java 獲得MyService服務的接口文件
4. MyServiceServiceLocator.java 實現MyServiceService接口
5. MyServiceSoapBindingImpl.java 實現MyService接口,應向其中補充業務邏輯
6. MyServiceSoapBindingSkeleton.java MyService服務的服務端框架代碼,實現MyService, org.apache.axis.wsdl.Skeleton接口
7. MyServiceSoapBindingStub.java MyService服務的客戶端存根代碼,實現MyService接口
8. undeploy.wsdd 注銷MyService服務的部署描述文件

2.7.3 編寫Web服務客戶端代碼

Web服務的客戶端程序完成對Web服務的調用,其程序結構如下。

import com.chinavnet.zx.service.v1_0.*;// WSDL2Java生成的package的名字空間;
            public class TestClient {
            public static void main (String[] args) throws Exception
            {
            com.chinavnet.zx.service.v1_0.SPInterfaceForVNetLocator locator = new  SPInterfaceForVNetLocator();//獲得一個locator對象
            locator.setMaintainSession(true);
            com.chinavnet.zx.service.v1_0.SPInterfaceForVNetSoap service = locator.getSPInterfaceForVNetSoap();//獲得服務對象
            com.chinavnet.zx.service.v1_0.DetailLedgerFeedbackResult feedbackRes = null;
            //初始化Web服務中定義的數據類型
            try {
            feedbackRes =  service.generalLedgerFeedback();//調用Web服務的方法并取得返回值
            System.out.println("FeedbackResult :");
            if(feedbackRes != null)
            {
            System.out.println("SPID: " +feedbackRes.getSPID());
            System.out.println("errorDesc: " +feedbackRes.getErrorDescription());
            System.out.println("result: " +feedbackRes.getResult());
            }else
            {
            System.out.println("feedbackRes is null!");
            }
            } catch (java.rmi.RemoteException re) {
            //           throw new junit.framework.AssertionFailedError("Remote Exception caught: " + re );
            re.printStackTrace();
            }
            }//End of main()
            }//End of TestClient class
            

測試客戶端程序是非常簡單的,將客戶端程序編譯后,執行"java TestClient"即可。

2.8 如何編寫服務端代碼

向MyServiceSoapBindingImpl.java添加相關的業務邏輯代碼后,將WSDL2Java生成的源程序編譯,打包成jar文件,復制到/usr/local/apache/htdocs/WEB-INF/lib/目錄下。

2.9 如何發布Web服務

有了deploy.wsdd文件并準備好類文件后,就可以發布MyService服務了。Axis在安裝后自動發布了AdminService,利用它可以發布新的Web服務。方法如下。

java org.apache.axis.client.AdminClient -lhttp://localhost:80/services/AdminService deploy.wsdd
            上面的命令執行后,有如下提示。
            Processing file deploy.wsdd
            <Admin>Done processing</Admin>
            

2.10 執行WSDL2Java時報告" 類型被引用但未定義"

2.10.1 問題描述

執行WSDL2Java時報告下面的異常:

java.io.IOException: Type {http://schemas.xmlsoap.org/wsdl/} ArrayOfFailedRecord is referenced but not defined.
            

2.10.2 原因分析

出現上述情況可能的原因有:

類型未定義就被引用。

使用了錯誤的名字空間。

WSDL文件中存在輸入錯誤。

2.10.3 解決方法

經過仔細檢查發現wsdl文件中的

<s:element minOccurs="0" maxOccurs="1" name="FailedRecords" type="s0:ArrayOfFailedRecord" />
            

的type=" s0:ArrayOfFailedRecord"中的s0:前面有一個空格,將空格刪除后問題解決了。

2.10.4 小結

WSDL文件中出現的編輯錯誤有可能導致執行WSDL2Java時出現"類型被引用但未定義"錯誤。

2.11 server-config.wsdd的作用是什么

server-config.wsdd記錄了axis已發布的Web服務的描述信息。

2.12 發布Web服務時報告"Exception:: (404)Not Found"

2.12.1 問題描述

執行java org.apache.axis.client.AdminClient -lhttp://localhost:80/services/AdminService deploy.wsdd命令發布WEB服務時報告如下內容。
            Processing file deploy.wsdd
            Exception:: (404)Not Found
            

Apache的access_log顯示如下。

127.0.0.1 - - [17/Sep/2003:15:56:33 +0800] "POST /services/AdminService HTTP/1.0" 404 293
            

2.12.2 原因分析

出現這個問題的比較簡單的原因可能是端口不對,或URL路徑不對(例如路徑中多寫了目錄),Axis的SoapMonitor服務按指定的端口或URL找不到AdminService,需要檢查正確的端口號和URL路徑。

比較深層次的原因就復雜得多了。

本文作者遇到的是下面的情況。

AdminService是一個已發布的WEB服務。

AdminClient使用soap協議同AdminService通信,需要按指定的端口和URL定位AdminService,而原來使用的resin.conf中,有兩個web-app配置項,配置A的摘要如下所示。

<host id=' '>
            <app-dir>/usr/local/apache/htdocs/</app-dir>
            

配置B的摘要如下所示。

<host id='test.com'>
            <app-dir>/usr/local/apache/htdocs/esales/</app-dir>
            

Axis的有關配置在配置B中。

Httpd.conf中的DocumentRoot是/usr/local/apache/htdocs/。

使用java org.apache.axis.client.AdminClient -lhttp://localhost:80/services/AdminService deploy.wsdd發布WEB服務時,需要按http協議解析url: //localhost:80/services/AdminService。由于htdocs/目錄下并沒有services/目錄(services是Axis在resin.conf中的servlet-mapping),因此應用服務器按resin.conf中的配置去定位AdminService ,因為url的主機名為localhost,因此resin不會到<host id='test.com'>(配置B)中去定位url,而是到配置A中去定位,在配置A中并沒有Axis的配置,找不到與AdminService相關的url,因此報告了前面描述的異常情況。

2.12.3 解決方法

知道了原因后,按如下方法就可以解決了。

將配置B中全部關于Axis的配置移到配置A中,注意相應地要改變/etc/profile中的CLASSPATH變量的值。

保存resin.conf后,重新登錄服務器(使新的CLASSPATH生效),重新啟動resin。再次發布WEB服務。

java org.apache.axis.client.AdminClient -lhttp://localhost:80/services/AdminService deploy.wsdd
            

屏幕顯示如下。

Processing file deploy.wsdd
            <Admin>Done processing</Admin>
            

WEB服務終于發布成功了。

在發布成功的情況下apache的access_log中會看到如下的log:

tail -f access_log|grep vice
            127.0.0.1 - - [17/Sep/2003:16:05:00 +0800] "POST /services/AdminService HTTP/1.0" 200 296 "-" "Axis/1.1"
            

2.12.4 小結

本小節描述的問題可能是讀者遇到的出現最多的異常,但原因并不是唯一的。遇到該問題時,建議讀者冷靜分析出現問題的可能原因,多實驗幾種解決方法,最終一定可以成功!

2.13 如何監測SOAP請求和響應流

2.13.1 引言

發布了Web服務以后,如何觀察請求和響應數據呢?記錄運行日志是一種傳統且有效的方法,但對于調試程序來講還不夠方便和直觀。值得欣慰的是,Axis為我們提供了在客戶端觀察SOAP請求和響應流數據的工具SoapMonitor,經過適當配置后,可以實時地觀察到Web服務的SOAP請求和響應數據。SoapMonitor是一個Java Applet程序,通過瀏覽器下載到客戶端運行。下面就介紹SoapMonitor的配置和使用方法。

2.13.2 準備SOAPMonitor 小應用程序

在Axis 1.1中,沒有為我們編譯SOAPMonitor.java程序,但我們可以在axis-1_1/webapps/axis/目錄下找到名字為SOAPMonitorApplet.java的源程序文件,自己進行編譯。該程序編譯后,會生成如下的類文件:

SOAPMonitorApplet.class
            SOAPMonitorApplet$ServiceFilterPanel.class
            SOAPMonitorApplet$SOAPMonitorData.class
            SOAPMonitorApplet$SOAPMonitorFilter.class
            SOAPMonitorApplet$SOAPMonitorPage.class
            SOAPMonitorApplet$SOAPMonitorTableModel.class
            SOAPMonitorApplet$SOAPMonitorTextArea.class
            

讀者需要把上述類文件復制到自己的Web應用程序目錄下,本例中是/usr/local/apache/htdocs/目錄。

在瀏覽器地址樣中輸入SOAPMonitor的地址,例如 http://test.com/SOAPMonitor ,瀏覽器會提示用戶正在下載Applet程序,下載完畢后,讀者可以在瀏覽器窗口中看到如圖4-1所示的用戶界面。如果上述類文件的位置不正確,瀏覽器會報告"找不到類"的錯誤。此時應檢查是否已將上述類文件復制到正確的目錄下。



圖 2-1 SOAPMonitor的界面

2.13.3 發布SOAPMonitor服務

圖2-1所示的SOAPMonitor界面出現后,并不意味著就可以觀察到Web服務的SOAP請求流與響應流了,首先需要發布SOAPMonitorService。該Web服務是由Axis提供的,但需要由用戶自己進行發布,方法如下。

獲得SOAPMonitor服務的WSDD文件deploy.wsdd,內容如下(也可到 http://www.sosnoski.com/presents/java-xml/axis/axis-monitor.html 復制該文件):

<deployment xmlns="http://xml.apache.org/axis/wsdd/"
            xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
            <handler name="soapmonitor"
            type="java:org.apache.axis.handlers.SOAPMonitorHandler">
            <parameter name="wsdlURL"
            value="/axis/SOAPMonitorService-impl.wsdl"/>
            <parameter name="namespace"
            value="http://tempuri.org/wsdl/2001/12/SOAPMonitorService-impl.wsdl"/>
            <parameter name="serviceName" value="SOAPMonitorService"/>
            <parameter name="portName" value="Demo"/>
            </handler>
            <service name="SOAPMonitorService" provider="java:RPC">
            <parameter name="allowedMethods" value="publishMessage"/>
            <parameter name="className"
            value="org.apache.axis.monitor.SOAPMonitorService"/>
            <parameter name="scope" value="Application"/>
            </service>
            </deployment>
            

發布SOAPMonitor服務:

java org.apache.axis.client.AdminClient -lhttp://localhost:80/services/AdminService deploy.wsdd
            

2.13.4 修改deploy.wsdd

發布SOAPMonitor服務后,還要對被監測的Web服務進行配置。方法是先注銷該Web服務,然后修改該服務對應的WSDD文件,在其中增加請求流和響應流的配置,否則是觀測不到SOAP請求和響應流的。

注銷Web服務的方法如下。

進入該Web服務的undeploy.wsdd文件所在的目錄,執行

Java org.apache.axis.client.AdminClient -lhttp://localhost:80/services/AdminService undeploy.wsdd
            

修改WSDD文件的方法如下。

以Axis提供的MyService為例,對MyService的WSDD文件做如下修改。

修改前:

...
            <service name="MyService" provider="java:RPC">
            <parameter name="className" value="samples.userguide.example3.MyService"/>
            <parameter name="allowedMethods" value="*"/>
            ...
            

修改后: (有下劃線的行是新加入的內容)

...
            <service name="MyService" provider="java:RPC">
            <requestFlow>
            <handler type="soapmonitor"/>
            </requestFlow>
            <responseFlow>
            <handler type="soapmonitor"/>
            </responseFlow>
            <parameter name="className" value="samples.userguide.example3.MyService"/>
            <parameter name="allowedMethods" value="*"/>
            ...
            

修改WSDD文件后,重新發布MyService服務:

java org.apache.axis.client.AdminClient -lhttp://localhost:80/services/AdminService deploy.wsdd
            

2.13.5 啟動SOAPMonitor小應用程序

按2.13.2節介紹的方法啟動SOAPMonitor小應用程序。

使用客戶端程序測試MyService服務:

#  java samples.userguide.example3.Client -lhttp://vnet.sohu.com/services/MyService "test"
            結果為:You typed : test
            

注意,一定要先啟動SOAPMonitor小應用程序,后調用Web服務才能觀察到SOAP請求和響應流。

2.13.6 觀察SOAP請求和響應流

這時在SoapMonitorApplet的窗口中可以觀察到SOAP和請求和響應消息,如圖2-2所示。



圖2-2 MyService的Soap請求和響應流

2.14 使用客戶端程序測試Web服務時報告"Exception:: (404)Not Found"

2.14.1 問題描述

WEB服務接口編寫完成并發布后,客戶端測試程序收不到WEB服務的返回結果,Apache或Resin的log中也看不到訪問記錄。但測試程序返回結果為0(成功),在沒有部署該WEB服務的情況下,也是這個結果,因此懷疑調用的是WSDL文件的提供者自己測試用的WEB服務接口,可能與另一方提供的WSDL文件有關。

2.14.2 原因分析

合作伙伴調用WEB服務就能夠成功,從WEB服務主機自己的客戶端調用就接收不到數據,估計與合作伙伴提供的WSDL文件有關,該WSDL文件影響了WSDL2Java生成的客戶端stub代碼。檢查stub代碼,發現其soapAction都指向了合作伙伴的測試地址。

2.14.3 解決方法

修改stub代碼中的soapAction,改為sp(Service Provider)自己的WEB服務URL。重新編譯程序并發布Web服務,問題解決。

_call.setSOAPActionURI("sp自己的Web服務地址");

2.14.4 小結

本小節描述的問題出現于Web服務提供方按合作伙伴統一提供的WSDL文件生成客戶端代碼的情況。遇到這類問題,讀者可直接檢查WSDL2Java自動生成的代碼的有關部分。

在WSDL文件中可以看到與下列內容相似的設置。

<wsdl:service name="SPInterfaceForVNet">
            <wsdl:port binding="impl:SPInterfaceSoapSoapBinding" name="SPInterfaceForVNetSoap">
            <wsdlsoap:address location="http://test.com/services/SPInterfaceSoap" />
            </wsdl:port>
            </wsdl:service>
            

其中 http://test.com/services/SPInterfaceSoap即為已發布的WEB服務的URL,供客戶端調用。

2.15 如何列出已發布的Web服務

使用下面的命令:

java org.apache.axis.client.AdminClient -lhttp://localhost:80/services/  list
            

實際上該命令的輸出就是server-config.wsdd文件的內容。

2.16 發布Web服務時報告"調用目標異常"

2.16.1 問題描述

在部署WEB服務時報告:java.lang.reflect.InvocationTargetException異常。

2.16.2 原因分析

在WSDL文件中自定義的名字空間與Axis的services名字空間沖突。

2.16.3 解決方法

修改WSDL文件,將services改為別的名字。

2.17 WSDL文件中的targetNamespace的作用是什么

TargetNamespace指明目標名字空間,用于驗證xml文檔。

在WSDL文件中,<definitions>中的targetNamespace與<types>中的targetNamespace應保持一致。

2.18 Web服務部署成功但檢測不到

2.19 客戶端程序找不到可用的Web服務

2.19.1 問題描述

執行
            java org.apache.axis.client.AdminClient -lhttp://localhost:80/services/AdminService deploy.wsdd
            

時顯示<Admin>Done processing</Admin>,卻檢查不到新的服務,在WEB-INF/目錄下的server-config.wsdd文件中也看不到相應的配置項。

2.19.2 原因分析

新的WEB服務的類文件沒有重新編譯并復制到正確的位置。

2.19.3 解決方法

WEB服務的類文件可以打包為jar文件。在CLASSPATH環境變量中正確設置jar文件的路徑。例如:

jar cvf  SPInterfaceSoap.jar com/zx/service/v1_0/*.class
            

將SPInterfaceSoap.jar復制到WEB-INF/lib/目錄下,重新發布WEB服務。

2.20 如何排除原因不明的錯誤

有時,在對WEB服務執行客戶端測試時會出現慕名其妙的錯誤。為保證環境是正確的,可以按下面的步驟排除原因不明的錯誤。

1. Undeploy被測試的服務

java org.apache.axis.client.AdminClient -lhttp://localhost:80/services/AdminService undeploy.wsdd
            

2. 重新啟動resin: /usr/local/resin/bin/httpd.sh restart(如果是其它的應用服務器,請按相應的方法重新啟動)

3. 重新發布WEB服務

4. 進行測試


3 小結


目前有很多可以使用的應用服務器和Web服務平臺軟件,本文僅以Apache Axis和Resin為例介紹了在部署Web服務的過程中可能遇到的問題及其解決方法,其中并未討論Web服務的安全性問題。對于如何高效地開發和部署Web服務以及如何確保Web服務的安全性,還希望對此感興趣的讀者共同參與討論,對于文中存在的錯誤和不足之處也希望讀者朋友們能夠不吝批評指正。




菠蘿 2007-08-16 17:04 發表評論
]]>
生成客戶端client stub文件http://m.tkk7.com/boluobn/articles/137288.html菠蘿菠蘿Thu, 16 Aug 2007 07:40:00 GMThttp://m.tkk7.com/boluobn/articles/137288.htmlhttp://m.tkk7.com/boluobn/comments/137288.htmlhttp://m.tkk7.com/boluobn/articles/137288.html#Feedback0http://m.tkk7.com/boluobn/comments/commentRss/137288.htmlhttp://m.tkk7.com/boluobn/services/trackbacks/137288.html  說道Web Service的程序開發,八個月前我加班調試公司和中國電信的商務領航系統的接口的時候,用的就是Web Service,Web Service有很多優點,使用Web Service可以在不同編程語言間實現數據交換,而我那時對Web Service也不熟,就由同事幫我生成了一大堆Web Service的框架代碼,我則只單獨開發業務代碼。

  這次的另外一個項目也要用Web Service了,不過人手也少了,沒有人幫做Web Service了,只好自己動手。

  好在開發前,有個同事先給我們不熟悉Web Service的程序員進行了一些培訓,我才知道原來以前的Web Service都是可以自動生成代碼的,而且也不難,試了一個下午客戶端和服務器端的Web Service代碼就都調試通過了,真不錯。

  為了更多喜愛開發的程序員也能迅速了解Web Service的開發,我這里整理了一些通過Axis開發Web Service的一些要點,希望能讓不熟悉Web Service的開發人員能夠迅速掌握Web Service。

  一、Axis環境的安裝

  1、安裝環境 J2SE SDK 1.4,Tomcat 5.0,eclipse 3.2。

  2、到 http://xml.apache.org 網站下載Axis安裝包。

  3、將Axis相關包文件放在WEB-INF\lib目錄下。

  4、Axis可選的包:activation.jar; mail.jar; xmlsec-1.4.Beta1.jar拷貝到WEB-INF目錄下,生成客戶端時候需要使用。

  Axis支持三種web service的部署和開發,分別為:

  1、Dynamic Invocation Interface (DII)

  2、Dynamic Proxy方式

  3、Stubs方式

  前兩種方式我就不介紹了,同事告訴我他們自己都不使用前兩種方式,他們建議我們使用Stubs方式,因此我就主要就介紹一下第三種方式。注意,我自己的Java源代碼是放在D:\workspace\test\目錄下,Axis相關包文件放在D:\workspace\test\WEB-INF目錄下。

  二、編寫wsdd發布web服務,編寫stub client訪問web服務

  1、編寫服務端程序server,SayHello.java,編譯server.SayHello.java

package server;
public class SayHello
{
    public String getName(String name)
    {
        return "hello "+name;
    }
}

  2、編寫wsdd文件

  deploy.wsdd文件內容如下:

<deployment xmlns="http://xml.apache.org/axis/wsdd/" xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
 <service name="SayHello" provider="java:RPC">
  <parameter name="className" value="server.SayHello.getName"/>
  <parameter name="allowedMethods" value="*"/>
 </service>
</deployment>

  3、發布服務:

  編輯一個deploy.bat,Axis_Lib為axis.jar路徑。內容如下:

set Axis_Lib=D:\workspace\test\WEB-INF\lib
set Java_Cmd=java -Djava.ext.dirs=%Axis_Lib%
set Axis_Servlet=http://localhost:8080/test/servlet/AxisServlet
%Java_Cmd% org.apache.axis.client.AdminClient -l%Axis_Servlet% deploy.wsdd

  執行這個批處理文件,這時候,如果提示成功的話,訪問http://localhost:8080/test/services 就會顯示服務列表。

  4、生成客戶端client stub文件

  在瀏覽器上訪問服務器端的服務,可以下載到WSDL文件,通過Axis的相關工具,可以自動從WSDL文件中生成Web Service的客戶端代碼。

  編寫一個WSDL2Java.bat文件,其內容如下:

set Axis_Lib=D:\workspace\test\WEB-INF\lib
set Java_Cmd=java -Djava.ext.dirs=%Axis_Lib%
set Output_Path=D:\workspace\test\src
set Package=server.SayHello
%Java_Cmd% org.apache.axis.wsdl.WSDL2Java -o%Output_Path% -p%Package% SayHello.wsdl

  執行這個批處理文件就可以生成client stub.

  生成的stub client文件列表為:SayHello.java,SayHelloService.java,SayHelloServiceLocator.java,SayHelloSoapBindingStub.java .

  5、編寫客戶端程序,編譯并執行

  下面是一段junit測試客戶端代碼。

import java.net.URL;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;

public class TestWSClient extends TestCase {

    public TestWSClient(String string) {
        super(string);
    }

    public void SayHelloClient() throws Exception {

        SayHelloService service = new SayHelloServiceLocator();
        SayHello_PortType client = service.getSayHello() ;
        String retValue = client.getName("clientname");
        System.out.println(retValue);

    }

    public static Test suite() {
        TestSuite suite = new TestSuite();
        suite.addTest(new TestWSClient("SayHelloClient"));
        return suite;
    }
}

  至此,整個服務器端和客戶端的Web Service框架代碼就完成了,剩下的就是在里面加入你的業務代碼了,怎么樣,Web Service并不難開發吧。



菠蘿 2007-08-16 15:40 發表評論
]]>
AXIS學習筆記(一)http://m.tkk7.com/boluobn/articles/137207.html菠蘿菠蘿Thu, 16 Aug 2007 05:24:00 GMThttp://m.tkk7.com/boluobn/articles/137207.htmlhttp://m.tkk7.com/boluobn/comments/137207.htmlhttp://m.tkk7.com/boluobn/articles/137207.html#Feedback0http://m.tkk7.com/boluobn/comments/commentRss/137207.htmlhttp://m.tkk7.com/boluobn/services/trackbacks/137207.html一、軟件環境

 1、axis-1_2  (從apache網站下載最新axis-bin-1_2.zip解壓即可)

 2、Tomcat5.0

 3、JDK5.0

二、相關配置

 1、在你的%TOMCAT_HOME%\common\lib下需要加入三個包 activation.jar、mail.jar、tools.jar

 2、環境變量設置

     AXIS_HOME 即axis-bin-1_2.zip解壓的目錄(我的是在F:\soap\axis-1_2)

     AXIS_LIB    即 %AXIS_HOME%\lib

    AXISCLASSPATH 即 %AXIS_LIB%\axis.jar;%AXIS_LIB%\commons-discovery-0.2.jar;%AXIS_LIB%\commons-logging-1.0.4.jar;%AXIS_LIB%\jaxrpc.jar;%AXIS_LIB%\saaj.jar;%AXIS_LIB%\log4j-1.2.8.jar;也就是把%AXIS_LIB%下所用JAR文件都導入

三、實驗一下

   在%AXIS_HOME%\webapps下找到axis文件夾,將其整個拷貝到%TOMCAT_HOME%\webapps下,啟動

  Tomcat,打開瀏覽器訪問http://localhost:8080/axis/,出現以下頁面說明你配置成功了。很簡單吧:)

 

四、發布我們的第一個程序

   第一個程序簡單的返回HELLO WORLD!

  HelloWorld.java

public class HelloWorld {
  public String sayHello()
  {
    return "HELLO WORLD!";
  } 
}

我們的第一種發布方式:

將HelloWorld.java拷貝到%TOMCAT_HOME%\webapps\axis下,然后將其改名為HelloWorld.jws,這樣AXIS就自然將其發布了。現在寫個客戶端程序訪問一下:

TestClient.java

import org.apache.axis.client.Call;
import org.apache.axis.client.Service;

import javax.xml.rpc.ParameterMode;

public class TestClient
{
   public static void main(String [] args) throws Exception {
       
       String endpoint = "http://localhost/:" +"8080"+ "/axis/HelloWorld.jws";//指明服務所在位置

       Service  service = new Service();  //創建一個Service實例,注意是必須的!
       Call     call    = (Call) service.createCall();//創建Call實例,也是必須的!

     call.setTargetEndpointAddress( new java.net.URL(endpoint) );//為Call設置服務的位置

        call.setOperationName( "sayHello" );//注意方法名與HelloWorld.java中一樣!!

         String res = (String) call.invoke( new Object[] {} );//返回String,沒有傳入參數

                         System.out.println( res );
   }
}

我的測試是在jbuilder2005中,注意項目中要導入其自帶的AXIS包(當然應該把其中JAR文件替換一下),可以看到程序返回了 "HELLO WORLD!"

可以看到在AXIS里發布服務其實是一件很容易的事,這是因為這個服務很簡單的原因:)下面我們介紹第二種發布方式,這是常用的。

我們的第二種發布方式:

1、將HelloWorld.java編譯成HelloWorld.class,放到%TOMCAT_HOME%\webapps\axis\WEB-INF\classes

      下

2、在%TOMCAT_HOME%\webapps\axis\WEB-INF下新建deploy.wsdd文件,即SOAP服務發布描述文件

     deploy.wsdd

<deployment xmlns="http://xml.apache.org/axis/wsdd/" xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
    <service name="HelloWorld" provider="java:RPC">
        <parameter name="className" value="HelloWorld"/>
        <parameter name="allowedMethods" value="sayHello"/>
    </service>
</deployment>

在DOS下轉換目錄到%TOMCAT_HOME%\webapps\axis\WEB-INF,命令:

java -cp %AXISCLASSPATH% org.apache.axis.client.AdminClient deploy.wsdd

你會發現目錄下多了一個server-config.wsdd文件,這就是AXIS的配置文件,以后所有的服務發布描述都會在里面找到。(當然,你可以直接修改它,不用再寫deploy.wsdd)然后打開瀏覽器http://localhost:8080/axis/servlet/AxisServlet,你就會看到你的服務已發布

同樣用客戶端程序訪問一下:(注意和上邊的差別!!)

HelloClient.java

import org.apache.axis.client.Call;
import org.apache.axis.client.Service;

public class HelloClient
{
   public static void main(String [] args) throws Exception {

       String endpoint = "http://localhost/:" +"8080"+ "/axis/services/HelloWorld";//注意!差別僅僅在這里!!

       Service  service = new Service();
       Call     call    = (Call) service.createCall();
       call.setTargetEndpointAddress( new java.net.URL(endpoint) );
        call.setOperationName("sayHello"  );

         String res = (String) call.invoke( new Object[] {} );

                         System.out.println( res );
   }
}



菠蘿 2007-08-16 13:24 發表評論
]]>
AXIS-是用AdminClient部屬時要注意的http://m.tkk7.com/boluobn/articles/137206.html菠蘿菠蘿Thu, 16 Aug 2007 05:23:00 GMThttp://m.tkk7.com/boluobn/articles/137206.htmlhttp://m.tkk7.com/boluobn/comments/137206.htmlhttp://m.tkk7.com/boluobn/articles/137206.html#Feedback0http://m.tkk7.com/boluobn/comments/commentRss/137206.htmlhttp://m.tkk7.com/boluobn/services/trackbacks/137206.html如果使用java -cp %AXISCLASSPATH% org.apache.axis.client.AdminClient  deploy.wsdd

將自動部署到axis web應用的server-config.wsdd

要想部署到自己的web 應用下,比如boyoi,要使用以下的方式

java -cp %AXISCLASSPATH% org.apache.axis.client.AdminClient
     -lhttp://localhost:8080/boyoi/services/AdminService deploy.wsdd



菠蘿 2007-08-16 13:23 發表評論
]]>
AXIS全攻略(一)http://m.tkk7.com/boluobn/articles/137203.html菠蘿菠蘿Thu, 16 Aug 2007 05:20:00 GMThttp://m.tkk7.com/boluobn/articles/137203.htmlhttp://m.tkk7.com/boluobn/comments/137203.htmlhttp://m.tkk7.com/boluobn/articles/137203.html#Feedback0http://m.tkk7.com/boluobn/comments/commentRss/137203.htmlhttp://m.tkk7.com/boluobn/services/trackbacks/137203.html一、Axis簡介


1. 什么是SOAP

SOAP是一個基于XML的用于應用程序之間通信數據編碼的傳輸協議。最初由微軟和Userland Software提出,隨著不斷地完善和改進,SOAP很快被業界廣泛應用,目前完全發布版本是1.1。在其發展過程中,W3C XML標準工作小組積極促成SOAP成為一個真正的開放標準。在寫作此文檔之時,SOAP1.2草案已經發布,1.2對1.1中相對混亂的部分做了改進。
SOAP被廣泛作為新一代跨平臺、跨語言分布計算Web Services的重要部分。


2. 什么是Axis

Axis是Apache組織推出的SOAP引擎,Axis項目是Apache組織著名的SOAP項目的后繼項目,目前最新版本是采用Java開發的1.1版本,C++的版本正在開發之中。Axis v1.1軟件包可以從http://ws.apache.org/axis/dist/1_1/下載得到。
但是Axis不僅僅是一個SOAP引擎,它還包括:
    一個獨立運行的SOAP服務器
    一個servlet引擎的插件,這個servlet引擎可以是Tomcat
    對WSDL的擴展支持
    一個將WSDL的描述生成JAVA類的工具
    一些示例代碼
    還有一個監控TCP/IP包的工具
 
二、Axis的安裝

應用Axis開發Web Services,你需要安裝如下軟件:
1.JDK1.4.2
2.一個支持Servlet的服務器引擎,比如廣為人知的Tomcat。

當安裝好Tomcat之后,只需將下載的Axis軟件包解壓縮,將其中的“webapps”目錄下的“axis”目錄整個拷貝到Tomcat安裝目錄下的“webapps”目錄下即可。

三、Axis的配置

Axis基于Java開發,可以部署于多種操作系統,使用前需要配置一系列的系統變量,在此假定你已經在本機上裝好了Tomcat 4.0以上的版本,需要配置的系統變量如下表所示:

CATALINA_HOME
C:\Tomcat_4_1

(此處應為Tomcat的安裝位置,注意路徑名中不要有空格)

AXIS_HOME
%CATALINA_HOME%\webapps\axis

AXIS_LIB
%AXIS_HOME%\lib

AXISCLASSPATH
%AXIS_LIB%\axis.jar;%AXIS_LIB%\commons-discovery.jar; %AXIS_LIB%\commons-logging.jar;%AXIS_LIB%\jaxrpc.jar; %AXIS_LIB%\saaj.jar;%AXIS_LIB%\log4j-1.2.8.jar; %AXIS_LIB%\xml-apis.jar;%AXIS_LIB%\xercesImpl.jar

CLASSPATH 中加入:
%AXIS_LIB%\axis.jar;%AXIS_LIB%\commons-discovery.jar; %AXIS_LIB%\commons-logging.jar;%AXIS_LIB%\jaxrpc.jar; %AXIS_LIB%\saaj.jar;%AXIS_LIB%\log4j-1.2.8.jar; %AXIS_LIB%\xml-apis.jar;%AXIS_LIB%\xercesImpl.jar

四、Axis的測試

安裝配置完畢后,應測試一下是否Axis可以正確運行了。

  啟動Tomcat服務器,在瀏覽器中訪問http://localhost:8080/axis/happyaxis.jsp,如果頁面顯示有錯誤,則需要回頭檢查一下相關配置是否正確,如果瀏覽頁面能正確顯示出系統組件、屬性等參數配置信息,則表示安裝成功。現在可以開始開發你的Web Services應用了。

五、服務的發布
Axis提供了兩種服務發布方式,一種是即時發布(Instant Deployment),一種是定制發布(Custom Deployment)。

1. 使用即時發布 Java Web Service(JWS)

  對即時發布的支持是Axis的特色之一,使用即時發布使用戶只需有提供服務的Java類的源代碼,即可將其迅速發布成Web服務。每當用戶調用這類服務的時候,Axis會自動進行編譯,即使服務器重啟了也不必對其做任何處理,使用非常簡單快捷。

  使用即時發布首先需要一個實現服務功能的Java源文件,將其擴展名改為.jws(Java Web Service的縮寫),然后將該文件放到“……\webapps\axis”目錄下即可。
    在此給出一個從英里到公里的長度單位轉換的服務,其源碼如下:

文件Distance.jws

public class Distance
{
    public double convertMile2Kilometre( double mile )
    { 
 return mile * 1.609;  //實現英里到公里的距離轉換
    }
}

將其放到“……\webapps\axis”目錄,通過訪問http://localhost:8080/axis/Distance.jws?wsdl可以看到這個服務的WSDL描述文件,這說明Distance服務被成功發布了。描述的WDSL代碼如下:
<?xml version="1.0" encoding="UTF-8" ?>
- <wsdl:definitions targetNamespace="- <wsdl:message name="convertMile2KilometreRequest">
  <wsdl:part name="mile" type="xsd:double" />
  </wsdl:message>
- <wsdl:message name="convertMile2KilometreResponse">
  <wsdl:part name="convertMile2KilometreReturn" type="xsd:double" />
  </wsdl:message>
- <wsdl:portType name="Distance">
- <wsdl:operation name="convertMile2Kilometre" parameterOrder="mile">
  <wsdl:input message="impl:convertMile2KilometreRequest" name="convertMile2KilometreRequest" />
  <wsdl:output message="impl:convertMile2KilometreResponse" name="convertMile2KilometreResponse" />
  </wsdl:operation>
  </wsdl:portType>
- <wsdl:binding name="DistanceSoapBinding" type="impl:Distance">
  <wsdlsoap:binding style="rpc" transport="
- <wsdl:operation name="convertMile2Kilometre">
  <wsdlsoap:operation soapAction="" />
- <wsdl:input name="convertMile2KilometreRequest">
  <wsdlsoap:body encodingStyle="
http://defaultnamespace/" use="encoded" />
  </wsdl:input>
- <wsdl:output name="convertMile2KilometreResponse">
  <wsdlsoap:body encodingStyle="  </wsdl:output>
  </wsdl:operation>
  </wsdl:binding>
- <wsdl:service name="DistanceService">
- <wsdl:port binding="impl:DistanceSoapBinding" name="Distance">
  <wsdlsoap:address location="
  </wsdl:port>
  </wsdl:service>
  </wsdl:definitions>

需要注意的是:JWS的web服務發布是一個很簡單的Web服務發布方式,在頁面中你不能使用包,而且由于代碼是在運行期被編譯的,所以在部署之后,你也很難找到錯誤所在。

2. 使用定制發布 Web Service Deployment Descriptor(WSDD)

  即時發布是一項令人激動的技術,它使Web服務的開發變得如此簡單;然而即時發布并不總是最好的選擇,比如有些應用系統是第三方提供的,我們沒有購買源代碼,只有.class文件,但我們又希望將這個應用系統的一些功能對外發布成Web服務,使其能夠在更大范圍內產生作用,這個時候即時發布技術就無能為力了。此外,即時發布技術并不靈活,無法進行更多的服務配置,這使得它并不能滿足一些特定系統的需求。

  因此,Axis提供了另一種服務發布方式,這就是定制發布。

  在此給出一個從加侖到升的容積單位轉換的服務,其源碼如下:

  文件Capacity.java
    package samples.capacity;
    public class Capacity
    {
        public double convertGallon2Litre( double gallon )
 {
     return gallon * 4.546;//實現加侖到升的容積轉換
 }//convertGallon2Litre()

    }/* Capacity */
 
    將其編譯成.class文件,放置到“……\webapps\axis\samples\capacity”目錄下,即可著手進行發布。
    定制發布不需要構建.jws文件,但必須創建服務發布描述文件deploy.wsdd(Web Service Deployment Descriptor的縮寫),這個文件負責描述服務的名稱、入口等信息,其內容如下:
    文件deploy.wsdd

    <deployment xmlns=" <parameter name="className" value="samples.capacity.Capacity"/>
 <parameter name="allowedMethods" value="*"/>
 </service>
    </deployment>

    在這里服務的提供者是“java:RPC”,它被內建在Axis中,而且指明了一個JAVA RPC服務,做這個處理的類是org.apache.axis.providers.java.RPCProvider。
    我們是通過一個<parameter>標簽告訴RPC服務應該調用的類,而另外一個<parameter>標簽則告訴引擎,它可以調用這個類中的任何的Public方法。你也可以指定通過使用名字空間或者一些可以調用的方法列表,來指明那些方法可以被調用。

  將該文件也放到“……\webapps\axis\samples\capacity”目錄下,然后可以采用Axis提供的一個客戶端管理工具——AdminClient來完成服務的定制發布。
   在“……\webapps\axis\samples\capacity”目錄下,運行:

   java -cp %AXISCLASSPATH% org.apache.axis.client.AdminClient deploy.wsdd

   如果運行時說沒有找到類,那么可能是類路徑沒有配置好,建議將所有的與axis相關的jar都寫到classpath中去。這樣只要運行:

   java org.apache.axis.client.AdminClient deploy.wsdd
   可以看到以下運行結果:

 Processing file deploy.wsdd
 <Admin>Doneprocessing</Admin>

  這表明Capacity服務定制發布完成。
 
   你也可以調用:
 java org.apache.axis.client.AdminClient undeploy.wsdd  來取消部署。

   你也可以調用:
 java org.apache.axis.client.AdminClient list 來獲得所有的已經部署的服務的列表。在這里你會看到services, handlers, transports等等,注意這個調用只是列出了WEB-INF\server-config.wsdd的文件內容。

   一定要注意:編譯后的class文件要拷貝到web-inf/classes的目錄中,如果該文件中有包存在的話,別忘了還要在classes目錄下創建包的目錄
   通過訪問
http://localhost:8080/axis/services/Capacity?wsdl可以看到這個服務的WSDL描述文件,這說明Capacity服務被成功發布了。
   你也可以通過訪問http://localhost:8080/axis/servlet/AxisServlet查看所有定制發布的服務。
   WDSL如下:
  <?xml version="1.0" encoding="UTF-8" ?>
- <wsdl:definitions targetNamespace="http://localhost:8080/axis/services/Capacity" xmlns="    xmlns:apachesoap="http://localhost:8080/axis/services/Capacity" xmlns:intf="http://localhost:8080/axis/services/Capacity" xmlns:soapenc="  <wsdl:part name="convertGallon2LitreReturn" type="xsd:double" />
  </wsdl:message>
- <wsdl:message name="convertGallon2LitreRequest">
  <wsdl:part name="in0" type="xsd:double" />
  </wsdl:message>
- <wsdl:portType name="Capacity">
- <wsdl:operation name="convertGallon2Litre" parameterOrder="in0">
  <wsdl:input message="impl:convertGallon2LitreRequest" name="convertGallon2LitreRequest" />
  <wsdl:output message="impl:convertGallon2LitreResponse" name="convertGallon2LitreResponse" />
  </wsdl:operation>
  </wsdl:portType>
- <wsdl:binding name="CapacitySoapBinding" type="impl:Capacity">
  <wsdlsoap:binding style="rpc" transport="
- <wsdl:operation name="convertGallon2Litre">
  <wsdlsoap:operation soapAction="" />
- <wsdl:input name="convertGallon2LitreRequest">
  <wsdlsoap:body encodingStyle="
  </wsdl:input>
- <wsdl:output name="convertGallon2LitreResponse">
  <wsdlsoap:body encodingStyle="
http://localhost:8080/axis/services/Capacity" use="encoded" />
  </wsdl:output>
  </wsdl:operation>
  </wsdl:binding>
- <wsdl:service name="CapacityService">
- <wsdl:port binding="impl:CapacitySoapBinding" name="Capacity">
  <wsdlsoap:address location="http://localhost:8080/axis/services/Capacity" />
  </wsdl:port>
  </wsdl:service>
  </wsdl:definitions>

  WSDD 的高級功能:
  (1) AXIS支持三種對象范圍:
     "request"范圍:這是默認的情況,每一次Soap請求的時候都將創建新的對象。
     "application"范圍:將會為所有的請求生成一個單獨的共享的對象。
     "session"范圍:為每一個session期的客戶端請求創建一個對象。
  指定方法如下:
  <service name="MyService"...>
  <parameter name="scope" value="value"/>
  ...
  </service>
  (2) 更多部署內容:Handlers and Chains
  讓我們來深入挖掘一下Axis引擎的更強大的特性。如果我們想跟蹤我們的服務被調用了多少次,那么我們只需要包含一個簡單的handler,它存放在samples/log目錄下。要使用這個handler,你就首先應該部署這個handler,然后使用在部署服務時給它指定的名字。下面是一個wsdd文件的例子:
  <deployment xmlns="      <parameter name="filename" value="MyService.log"/>
    </handler>
 
   <!-- define the service, using the log handler we just defined -->
    <service name="LogTestService" provider="java:RPC">
     <requestFlow>
       <handler type="track"/>
     </requestFlow>
 
     <parameter name="className" value="samples.userguide.example4.Service"/>
     <parameter name="allowedMethods" value="*"/>
    </service>
  </deployment>

  第一段指明了一個名為track的handler,它是samples.userguide.example4.LogHandler類的實例。另外還指定了一個參數filename,用于指定日志文件名稱。
  下面的那段指明了一個RPC服務,和我們在上面的例子中看到的一樣,所不同的是在service標簽中的<requestFlow>標簽,它指定了一些在調用服務前應該被調用的handler集。也就是由于我們在部署中插入了這個"track"的引用,所以我們確定每次調用服務的時候都將被記錄到日志文件中去。
 
  (3)遠程管理:
  <service name="AdminService" provider="java:MSG">
 <parameter name="className" value="org.apache.axis.util.Admin"/>
 <parameter name="allowedMethods" value="*"/>
 <parameter name="enableRemoteAdmin" value="true"/>
  </service>
  WARNING: enabling remote administration may give unauthorized parties access to your machine. If you do this, please make sure to add security to your configuration!
  所以遠程管理涉及到安全問題,不建議采用。



菠蘿 2007-08-16 13:20 發表評論
]]>
結合Axis和Ant開發Web服務http://m.tkk7.com/boluobn/articles/136198.html菠蘿菠蘿Sun, 12 Aug 2007 09:04:00 GMThttp://m.tkk7.com/boluobn/articles/136198.htmlhttp://m.tkk7.com/boluobn/comments/136198.htmlhttp://m.tkk7.com/boluobn/articles/136198.html#Feedback0http://m.tkk7.com/boluobn/comments/commentRss/136198.htmlhttp://m.tkk7.com/boluobn/services/trackbacks/136198.html本文結合一個簡單示例講解了怎樣把AxisAnt結合起來進行Web服務的開發。幫助讀者從簡單的java源代碼或者從一個服務描述文件(wsdl)開始,用Ant工具進行構建,設置,并把服務部署到Axis

 

首先假定您熟悉 AXIS 處理系統和Ant工具。文中示例所需要的軟件如下:

l         Apache Axis 1.1

l         Apache Ant 1.5.3

l         Jarkat Tomcat 4.1.24

在開始前,假定上述軟件已經安裝和配置好了。

 

AxisAnt簡介

Axis 框架是來自 Apache Group 的、基于 java 的、最新的 SOAP 規范(SOAP 1.2)和 SOAP with Attachments 規范(來自 Apache Group )的開放源代碼實現。其本質上是一個SOAP引擎--一個構建諸如客戶端、服務器、網關等SOAP處理器的框架。是Apache SOAP的后繼項目。但是,Axis使用SAX(基于事件)解析器獲得了比Apache SOAP早期版本(使用DOM解析)非常明顯的速度優勢。另外,它還具有很強的靈活性和穩定性,支持Web服務描述語言1.1版。

Apache AntApache軟件基金會jakarta項目中的一個子項目,是一個基于Java的構建工具,類似于make,但它沒有make那么復雜繁瑣。Ant由一些內置任務(task)和可選擇的任務組成,還可以配置第三方提供的任務。它的構建配置文件基于XML的,所以容易書寫和維護,而且結構清晰。Ant還可以集成到一些開發環境中(例如visual age,jbuilder,Elipse)

 

AxisAnt的支持

Axis為支持Ant構建,提供了一個axis-ant.jar文件。該文件包含三個可選任務(task)的定義和實現:axis-wsdl2javaaxis-java2wsdlaxis-admin。任務axis-wsdl2javaAxis提供的工具WSDL2Java具有同樣的功能,根據web服務描述文件生成對應的Java源程序,它的屬性設置與WSDL2Java的命令參數設置類似。而任務axis-java2wsdl則相反,它與Java2WSDL工具一樣,是根據已有的類文件來生成Web服務描述文件。最后一個任務axis-admin是用于web服務的部署和取消部署的,對應于AxisAminClient工具。

為了使Ant能夠正確使用上述三個任務(task),還需要做一些配置。注意:Apache Ant的版本必須是1.5.1或更高版本。

1.設置系統的環境變量CLASSPATH包含Axis提供的axis-ant.jar文件,或者在Ant的配置文件(通常是build.xml)中設置路徑包含它。例如,

    <path id="axis.classpath">

     <fileset dir="${axis.home}/lib">

               <include name="**/*.jar" />

      </fileset>

    </path>

   

2.然后使用<taskdef>聲明導入axis-ant.jar文件中的屬性文件所定義的任務(task)列表。

    <taskdef resource="axis-tasks.properties"

 classpathref="axis.classpath" />

    3.設置在構建過程中可能要需要的java包,例如, Axis所有的jar包,wsdl4j.jarjunit.jar等等。

 

實例開發

下面就用一個實例來講解怎樣把AntAxis結合來開發Web服務。為了注重本文的目的,我們開發一個比較簡單的Web服務,它接受客戶端傳入的字符串數組,如果傳入的參數為null,則拋出一個自定義的異常,否則把每個字符串連接起來返回給客戶端。

首先定義一個Web服務接口Hello,如下所示:

 

 package com.bidlink.hello;

 public interface Hello{

     public String echo(String[] content ) throws                       

               java.rmi.RemoteException,com.bidlink.hello.MyException;

 }

 

 自定義異常MyException包含一個時間值,以記錄異常出現的時間,如下:

 

 package com.bidlink.hello;

public class MyException extends org.apache.axis.AxisFault implements java.io.Serializable{

    private java.util.Calendar occurTime;

   

    public MyException() {

    }

 

    public MyException(

           java.util.Calendar occurTime) {

        super();

        this.occurTime = occurTime;

    }

 

    public java.util.Calendar getOccurTime() {

        return occurTime;

    }

 

    public void setOccurTime(java.util.Calendar occurTime) {

        this.occurTime = occurTime;

    }           

}

 

1axis-java2wsdl:從類文件生成服務描述文件

編譯上面定義的兩個文件Hell.javaMyException.java。接著編寫Ant的配置文件build.xml(文件詳細信息請查看示例源代碼),使用axis-java2wsdl任務根據類Hello來生成Web服務描述文件hello.wsdl。任務具體配置如下:

    <axis-java2wsdl classname="com.bidlink.hello.Hello"

                        location="http://localhost:8080/axis/services/Hello"

                        namespace="http://hello.bidlink.com"

                        output="hello.wsdl"

                        style="RPC"

                        extraclasses="com.bidlink.hello.MyException">

         <classpath>

             <pathelement path="${dist}"/>

         </classpath>

        </axis-java2wsdl>

       

其中,<pathelement path="${dist}"/>指出Hello.classMyException.class文件的位置。

運行命令ant java2wsdl,構建出Web服務描述文件hello.wsdl

2axis-wsdkl2java:從服務描述文件生成服務源程序

下面講解怎樣根據剛剛得到的hello.wsdl文件生成服務所需要的java源程序。在這里需要用到任務axis-wsdl2java。任務屬性設置如下:

     <axis-wsdl2java all="true"

                     url="hello.wsdl"

                     deployscope="Request"

                     output="${gensrc}"

                     serverside="true"

                     skeletondeploy="false"

                     testcase="true"

                     noimports="false"

                     typemappingversion="1.2">

       

        </axis-wsdl2java>

     運行ant wsdl2java,根據axis-wsdl2java任務的屬性配置生成相應的java源程序,本例所生成的文件包括:服務端服務接口文件Hello.java及其實現HelloSoapBindingImpl.java,以及客戶端的HelloService.javaHelloServiceLocator.javaHelloServiceLocator.java和客戶端存根文件HelloSoapBindingStub.java。又因為屬性testcase="true",所以還生成了測試文件HelloServiceTestCase.java。當然,自定義異常MyException也是重新生成的。

3axis-admin:向Axis部署Hello服務

服務源程序生成后,需要根據服務的功能修改HelloSoapBindingImpl.java文件,以真正實現該Web服務。修改如下:

 /**

 * HelloSoapBindingImpl.java

 *

 * This file was auto-generated from WSDL

 * by the Apache Axis WSDL2Java emitter.

 */

 

package com.bidlink.hello;

 

public class HelloSoapBindingImpl implements com.bidlink.hello.Hello{

    public java.lang.String echo(java.lang.String[] in0) throws java.rmi.RemoteException, com.bidlink.hello.MyException {

        if(in0 == null)

           throw new MyException(java.util.Calendar.getInstance());

          

       

        String retStr = "";

        for(int i=0; i< in0.length; i++)

           retStr += in0[i];

        return retStr;

    }

 

}

   

編譯所有的生成的源程序,最后使用axis-admin任務向Axis部署Hello Web服務。

    <axis-admin

           port="${target.port}"

               hostname="${target.server}"

            failonerror="true"

            servletpath="${target.appname}/services/AdminService"

            debug="true"

            xmlfile="deploy.wsdd"/>

       運行ant deploy,部署Hello服務。

    測試

現在可以測試所部署的Web服務hello。可以通過瀏覽器,也可以利用剛才生成的測試文件HelloServiceTestCase.java來進行該項工作。如果利用測試文件HelloServiceTestCase.java,那么還需要對它進行稍作修改。具體來說,就是添加一個main函數,然后修改所生成的測試方法。



菠蘿 2007-08-12 17:04 發表評論
]]>
用Axis開發基于Java的Web服務http://m.tkk7.com/boluobn/articles/134812.html菠蘿菠蘿Mon, 06 Aug 2007 14:47:00 GMThttp://m.tkk7.com/boluobn/articles/134812.htmlhttp://m.tkk7.com/boluobn/comments/134812.htmlhttp://m.tkk7.com/boluobn/articles/134812.html#Feedback0http://m.tkk7.com/boluobn/comments/commentRss/134812.htmlhttp://m.tkk7.com/boluobn/services/trackbacks/134812.html概述

  本文介紹了一個比較簡單實用的基于Java的SOAP引擎——Apache組織推出的Axis——的安裝、配置和應用開發方法,希望對有興趣做基于Java的Web Services應用開發的朋友有所幫助。

  Axis簡介

  Axis是Apache組織推出的SOAP引擎,Axis項目是Apache組織著名的SOAP項目的后繼項目,目前最新版本是采用Java開發的1.1版本,C 的版本正在開發之中。Axis v1.1軟件包可以從http://ws.apache.org/axis/dist/1_1/下載得到。

  Axis的安裝

  應用Axis開發Web Services,你需要有一個支持Servlet的服務器引擎,比如廣為人知的Tomcat(Tomcat也是由Apache組織所提供的,目前的最新版本為4.1.24,下載地址為http://jakarta.apache.org/builds/jakarta-tomcat-4.0/release/v4.1.24/)。在此之前當然你機器必須已經裝好了JDK1.3以上的版本,當安裝好Tomcat之后,只需將下載的Axis軟件包解壓縮,將其中的“webapps”目錄下的“axis”目錄整個拷貝到Tomcat安裝目錄下的“webapps”目錄下即可。

  Axis的配置

  Axis基于Java開發,可以部署于多種操作系統,使用前需要配置一系列的系統變量,在此假定你已經在本機上裝好了Tomcat 4.0以上的版本,需要配置的系統變量如下表所示:

CATALINA_HOME
C:\Tomcat_4_1

(此處應為Tomcat的安裝位置,注意路徑名中不要有空格)

AXIS_HOME
蔜ALINA_HOME%\webapps\axis

AXIS_LIB
%AXIS_HOME%\lib

AXISCLASSPATH
%AXIS_LIB%\axis.jar;%AXIS_LIB%\commons-discovery.jar; %AXIS_LIB%\commons-logging.jar;%AXIS_LIB%\jaxrpc.jar; %AXIS_LIB%\saaj.jar;%AXIS_LIB%\log4j-1.2.8.jar; %AXIS_LIB%\xml-apis.jar;%AXIS_LIB%\xercesImpl.jar

  如果你不愿做這么繁瑣的類路徑設置,可以直接將axis軟件包中“lib”目錄下的所有.jar文件加入到系統環境變量CLASSPATH中即可。

  Axis的測試

  安裝配置完畢后,應測試一下是否Axis可以正確運行了。

  啟動Tomcat服務器,在瀏覽器中訪問http://localhost:8080/axis/happyaxis.jsp,如果頁面顯示有錯誤,則需要回頭檢查一下相關配置是否正確,如果瀏覽頁面能正確顯示出系統組件、屬性等參數配置信息,則表示安裝成功,如下圖所示:



  現在可以開始開發你的Web Services應用了。


  概述

  本文介紹了一個比較簡單實用的基于Java的SOAP引擎——Apache組織推出的Axis——的安裝、配置和應用開發方法,希望對有興趣做基于Java的Web Services應用開發的朋友有所幫助。

  Axis簡介

  Axis是Apache組織推出的SOAP引擎,Axis項目是Apache組織著名的SOAP項目的后繼項目,目前最新版本是采用Java開發的1.1版本,C 的版本正在開發之中。Axis v1.1軟件包可以從http://ws.apache.org/axis/dist/1_1/下載得到。

  Axis的安裝

  應用Axis開發Web Services,你需要有一個支持Servlet的服務器引擎,比如廣為人知的Tomcat(Tomcat也是由Apache組織所提供的,目前的最新版本為4.1.24,下載地址為http://jakarta.apache.org/builds/jakarta-tomcat-4.0/release/v4.1.24/)。在此之前當然你機器必須已經裝好了JDK1.3以上的版本,當安裝好Tomcat之后,只需將下載的Axis軟件包解壓縮,將其中的“webapps”目錄下的“axis”目錄整個拷貝到Tomcat安裝目錄下的“webapps”目錄下即可。

  Axis的配置

  Axis基于Java開發,可以部署于多種操作系統,使用前需要配置一系列的系統變量,在此假定你已經在本機上裝好了Tomcat 4.0以上的版本,需要配置的系統變量如下表所示:

CATALINA_HOME
C:\Tomcat_4_1

(此處應為Tomcat的安裝位置,注意路徑名中不要有空格)

AXIS_HOME
蔜ALINA_HOME%\webapps\axis

AXIS_LIB
%AXIS_HOME%\lib

AXISCLASSPATH
%AXIS_LIB%\axis.jar;%AXIS_LIB%\commons-discovery.jar; %AXIS_LIB%\commons-logging.jar;%AXIS_LIB%\jaxrpc.jar; %AXIS_LIB%\saaj.jar;%AXIS_LIB%\log4j-1.2.8.jar; %AXIS_LIB%\xml-apis.jar;%AXIS_LIB%\xercesImpl.jar

  如果你不愿做這么繁瑣的類路徑設置,可以直接將axis軟件包中“lib”目錄下的所有.jar文件加入到系統環境變量CLASSPATH中即可。

  Axis的測試

  安裝配置完畢后,應測試一下是否Axis可以正確運行了。

  啟動Tomcat服務器,在瀏覽器中訪問http://localhost:8080/axis/happyaxis.jsp,如果頁面顯示有錯誤,則需要回頭檢查一下相關配置是否正確,如果瀏覽頁面能正確顯示出系統組件、屬性等參數配置信息,則表示安裝成功,如下圖所示:



  現在可以開始開發你的Web Services應用了。

 

服務的發布

  Axis提供了兩種服務發布方式,一種是即時發布(Instant Deployment),一種是定制發布(Custom Deployment)。

 

  使用即時發布

  對即時發布的支持是Axis的特色之一,使用即時發布使用戶只需有提供服務的Java類的源代碼,即可將其迅速發布成Web服務。每當用戶調用這類服務的時候,Axis會自動進行編譯,即使服務器重啟了也不必對其做任何處理,使用非常簡單快捷。

使用即時發布首先需要一個實現服務功能的Java源文件,將其擴展名改為.jws(Java Web Service的縮寫),然后將該文件放到“……\webapps\axis”目錄下即可。

  在此給出一個從英里到公里的長度單位轉換的服務,其源碼如下:

文件Distance.jws

/**

* @author 飛鷹

*/

public class Distance

{

public double convertMile2Kilometre( double mile )

{

//實現英里到公里的距離轉換

return mile * 1.609;

}//convertMile2Kilometre()

}/* Distance */

  將其放到“……\webapps\axis”目錄,通過訪問http://localhost:8080/axis/Distance.jws?wsdl可以看到這個服務的WSDL描述文件,這說明Distance服務被成功發布了。如下圖所示:



  使用定制發布

  即時發布是一項令人激動的技術,它使Web服務的開發變得如此簡單;然而即時發布并不總是最好的選擇,比如有些應用系統是第三方提供的,我們沒有購買源代碼,只有.class文件,但我們又希望將這個應用系統的一些功能對外發布成Web服務,使其能夠在更大范圍內產生作用,這個時候即時發布技術就無能為力了。此外,即時發布技術并不靈活,無法進行更多的服務配置,這使得它并不能滿足一些特定系統的需求。

  因此,Axis提供了另一種服務發布方式,這就是定制發布。

  在此給出一個從加侖到升的容積單位轉換的服務,其源碼如下:

  文件Capacity.java

package samples.capacity;

 

/**

* @author 飛鷹

*/

public class Capacity

{

public double convertGallon2Litre( double gallon )

{

//實現加侖到升的容積轉換

return gallon * 4.546;

}//convertGallon2Litre()

}/* Capacity */

  將其編譯成.class文件,放置到“……\webapps\axis\samples\capacity”目錄下,即可著手進行發布。

  定制發布不需要構建.jws文件,但必須創建服務發布描述文件deploy.wsdd(Web Service Deployment Descriptor的縮寫),這個文件負責描述服務的名稱、入口等信息,其內容如下:

  文件deploy.wsdd

<deployment xmlns="http://xml.apache.org/axis/wsdd/"

xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">

 

<service name="Capacity" provider="java:RPC">

<parameter name="className" value="samples.capacity.Capacity"/>

<parameter name="allowedMethods" value="*"/>

</service>

 

</deployment>

  將該文件也放到“……\webapps\axis\samples\capacity”目錄下,然后可以采用Axis提供的一個客戶端管理工具——AdminClient來完成服務的定制發布。

  在“……\webapps\axis\samples\capacity”目錄下,運行:

java -cp %AXISCLASSPATH% org.apache.axis.client.AdminClient deploy.wsdd

  可以看到以下運行結果:

Processing file deploy.wsdd

<Admin>Doneprocessing</Admin>

  這表明Capacity服務定制發布完成。

  通過訪問http://localhost:8080/axis/services/Capacity?wsdl可以看到這個服務的WSDL描述文件,這說明Capacity服務被成功發布了。如下圖所示:

 

服務的訪問

  GET方式的服務訪問

  一般的SOAP消息都是采用POST方式實現傳遞,但也可以通過GET方式來訪問。比如以下給出的一個服務——“HelloWorld”,其源碼如下:

 

文件HelloWorld.jws

/**

* @author 飛鷹

*/

public class HelloWorld

{

public String helloWorld()

{

//在服務器端打印輸出

System.out.println( "Hello World!" );

 

//返回相應字符串

return "Hello World!";

}//helloWorld()

 

}/* HelloWorld */

  這個服務給出一個名位“helloWorld”的無入口參數的操作,返回一個內容為“Hello World!的字符串”,同時在服務器端打印“Hello World!”,將該文件放到“……\webapps\axis”目錄下,即可通過GET方法直接訪問該服務,訪問的地址為http://localhost:8080/axis/HelloWorld.jws?method=helloWorld,可以看到返回的SOAP信封消息,同時服務器端給出了相應的顯示信息“Hello World!”這表明HelloWorld服務被成功訪問了。如下圖所示:



  客戶端服務訪問編程

  Axis提供了一套API來實現SOAP,從http://localhost:8080/axis/docs/apiDocs/index.html可以看到Axis的API文檔。

  其中,org.apache.axis.client.Call和org.apache.axis.client.Service是兩個比較常用的類,一般的客戶端程序欲訪問一個Web Service時,都要生成一個客戶端的Service對象和Call對象,在訪問服務之前,首先要對Call對象設置相應的參數,包括服務的位置、操作名、入口參數、返回值類型等,最后調用Call對象的invoke方法訪問服務。

  以下給出了一個客戶端訪問Web服務的例程——AXISTest.java:

  文件AXISTest.java

package axisexercise;

 

import org.apache.axis.client.Call;

import org.apache.axis.client.Service;

import org.apache.axis.encoding.XMLType;

 

import javax.xml.rpc.ParameterMode;

/**

* @author 飛鷹

*/

public class AXISTest

{

public static void main( String[] args ) throws Exception

{

Service service = new Service();

Call call = ( Call ) service.createCall();

 

 

//////////訪問即時發布的Distance服務

//設置訪問點

call.setTargetEndpointAddress( "http://localhost:8080/axis/Distance.jws" );

 

//設置操作名

call.setOperationName( "convertMile2Kilometre" );

 

//設置入口參數

call.addParameter( "op1", XMLType.XSD_DOUBLE, ParameterMode.IN );

call.setReturnType( XMLType.XSD_DOUBLE );

Double d1 = new Double( 190 );

 

//調用服務

System.out.println( d1 " 英里相當于 "

call.invoke( new Object[] {d1} ) " 公里!" );

 

 

 

//////////訪問定制發布的Capacity服務

call = ( Call ) service.createCall();

//設置訪問點

call.setTargetEndpointAddress( "http://localhost:8080/axis/services/Capacity" );

 

//設置操作名

call.setOperationName( "convertGallon2Litre" );

 

//設置入口參數

call.addParameter( "op1", XMLType.XSD_DOUBLE, ParameterMode.IN );

call.setReturnType( XMLType.XSD_DOUBLE );

d1 = new Double( 10.00 );

 

//調用服務

System.out.println( d1 " 加侖相當于 "

call.invoke( new Object[] {d1} ) " 升!" );

} //main()

}/* AXISTest */

  編譯運行后運行可以看到以下的結果:

  190.0英里相當于305.71公里!

  10.0加侖相當于45.46升!
 
  注意程序在訪問即時發布的Distance服務和定制發布的Capacity服務時的不同,前者的服務訪問點地址為http://localhost:8080/axis/HelloWorld.jws,而后者的則為http://localhost:8080/axis/services/Capacity。

  總結

  Web Services是未來網絡應用的發展方向,SOAP和WSDL是Web Services的核心協議,Axis給出了一個很好的SOAP實現,它使得開發Web Services應用變得輕松而有趣。



菠蘿 2007-08-06 22:47 發表評論
]]>
用jws來創建web services http://m.tkk7.com/boluobn/articles/134811.html菠蘿菠蘿Mon, 06 Aug 2007 14:44:00 GMThttp://m.tkk7.com/boluobn/articles/134811.htmlhttp://m.tkk7.com/boluobn/comments/134811.htmlhttp://m.tkk7.com/boluobn/articles/134811.html#Feedback0http://m.tkk7.com/boluobn/comments/commentRss/134811.htmlhttp://m.tkk7.com/boluobn/services/trackbacks/134811.html1.編寫一個java文件,經javac編譯后沒有錯誤,把該文件另存為.jws文件。例如合HelloWorld.jws:
  public class HelloWorld{
  public String sayHello(String name){
         return "Hello"+name;
         }
      }
然后把它放到對應的webapps/axis下.
2。啟動服務器,axis會自動把它變成一個服務,生成相關的wsdl文檔,并把jws用java編譯成class文件放到axis\WEB-INF\jwsClasses目錄下。打開IE,輸入:http://127.0.0.1:7001/axis/HelloWorld.jws,即可發現有一個wsdl和該服務。
3。編寫一應用程序客戶端來訪問該web services.例如:
import javax.xml.rpc.ParameterMode;
import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
import org.apache.axis.encoding.XMLType;
public class ServiceClient{
 public static void main(String[] args) throws Exception{
  String endpoint="  String name="gaolong1";
  Service service=new Service();
  Call call=(Call) service.createCall();
  call.setUsername("glong1");
  call.setPassword("131001");//這是服務所用的安全的認證
  call.setTargetEndpointAddress(new java.net.URL(endpoint));
  call.setOperationName("sayHello");
  call.addParameter("name",XMLType.XSD_STRING,ParameterMode.IN);
  call.setReturnType(XMLType.XSD_STRING);//XMLType.XSD_STRING);
  String ret=(String)call.invoke(new Object[] {name});
  System.out.println(ret);
 }
}
運行后,會顯示其調用信息。
在使用的過程中,要用到tcpmontor來監聽截取soap消息:
用:java org.apache.axis.utils.tcpmon 7003 localhost 7001 (其中前者是截聽得代理端口,中間是目標地址,后者是所用的目標端口)
 通過tcpmontor來監聽tcp:7001得到的soap消息如下:
請求消息:
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="
<soapenv:Body>
  <sayHello soapenv:encodingStyle="
      <name xsi:type="xsd:string">gaolong1</name>
  </sayHello>
</soapenv:Body></soapenv:Envelope>
回應消息:
<?xml version="1.0" encoding="utf-8"? >
 <soapenv:Envelope xmlns:soapenv="
<soapenv:Body>
  <sayHelloResponse soapenv:encodingStyle="
       <sayHelloReturn xsi:type="xsd:string">Hellogaolong1</sayHelloReturn>
  </sayHelloResponse>
</soapenv:Body></soapenv:Envelope>

菠蘿 2007-08-06 22:44 發表評論
]]>
用wsdd來開發web services http://m.tkk7.com/boluobn/articles/134810.html菠蘿菠蘿Mon, 06 Aug 2007 14:43:00 GMThttp://m.tkk7.com/boluobn/articles/134810.htmlhttp://m.tkk7.com/boluobn/comments/134810.htmlhttp://m.tkk7.com/boluobn/articles/134810.html#Feedback0http://m.tkk7.com/boluobn/comments/commentRss/134810.htmlhttp://m.tkk7.com/boluobn/services/trackbacks/134810.html用wsdd(服務部署描述語言),主要是編寫java文件和編寫wsdd文件。
1。編寫java文件,最好是定義在某一個包下,否則便以后直接放到\WEB-INF\classes下,有時會出錯,原因是在用deploy.wsdd部署時映射不對。然后直接包對應的包放到\WEB-INF\classes中。HelloWorldG.java文件:
    package test.gaolong;
public class HelloWorldG{
  public String sayHelloG(String name){
         return "HelloG "+name;
         }
      }
2。編寫wsdd文件,根據wsdd文件的規范編寫相關文檔。例如:(deploy.wsdd)
   <deployment xmlns="    <parameter name="className" value="test.gaolong.HelloWorldG"/><--對應的主類--->
    <parameter name="allowedMethods" value="*"/><---注冊相應的方法,如果只有一個方法,可以直接注冊方法名--->
    <parameter name="allowedRoles" value="user"/><--定義用戶認證--->
    <requestFlow><-用戶認證的描述文件-->
   <handler type="java:org.apache.axis.handlers.SimpleAuthenticationHandler"/>
   <handler type="java:org.apache.axis.handlers.SimpleAuthenticationHandler"/>
  </requestFlow>
  </service>
</deployment>
3。部署wsdd文件:打開命令口,切換到deploy.wsdd目錄下,運行java org.apache.axis.client.AdminClient即可完成部署。
      這兒可能出錯,正確的顯示:
D:\bea\user_projects\domains\mydomain\applications\axis\WEB-INF\classes>java org.apache.axis.client.AdminClient  -p 7001  deploy.wsdd
Processing file deploy.wsdd
<Admin>Done processing</Admin>
      當在wsdl中使用deploy.wsdd來部署時,對于服務器是要打開的,而且當服務器的端口不是8080時,采用要求java org.apache.axis.client.AdminClient -p <port> deploy.wsdd 來指定并進行服務部署。
4。打開server-config.wsdd會發現增加了語句描述:<service name="HelloWorldG" provider="java:RPC">
  <requestFlow>
   <handler type="java:org.apache.axis.handlers.SimpleAuthenticationHandler"/>
   <handler type="java:org.apache.axis.handlers.SimpleAuthenticationHandler"/>
  </requestFlow>
  <parameter name="allowedRoles" value="user"/>
  <parameter name="allowedMethods" value="*"/>
  <parameter name="className" value="test.gaolong.HelloWorldG"/>
 </service>
其實直接到該文件中增加該內容,不必用org.apache.axis.client.AdminClient來部署描述。
打開IE,可以在
http://127.0.0.1:7001/axis/servlet/AxisServlet看到該服務部署到服務列表上。
5。編寫測試application客戶端,其代碼如下:
import javax.xml.rpc.ParameterMode;
import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
import org.apache.axis.encoding.XMLType;
import javax.xml.namespace.QName;

public class ServiceClient{
 public static void main(String[] args) throws Exception{
  String endpoint="  String name="gaong1";
  Service service=new Service();
  Call call=(Call) service.createCall();//回調服務
  call.setUsername("gaolong1");
  call.setPassword("8001");//用戶認證
  call.setTargetEndpointAddress(new java.net.URL(endpoint));
 // call.setOperationName("sayHelloG");
  call.setOperationName(new QName("
  call.addParameter("name",XMLType.XSD_STRING,ParameterMode.IN);
  call.setReturnType(XMLType.XSD_STRING);//XMLType.XSD_STRING);
  String ret=(String)call.invoke(new Object[] {name});
  System.out.println(ret);
 }
}
 運行之后有關的顯示。
6。通過tcpmonitor來監聽的soap消息如下:
請求soap:
<?xml version="1.0" encoding="UTF-8"?><soapenv:Envelope xmlns:soapenv="
<soapenv:Body>
      <ns1:sayHelloG soapenv:encodingStyle="
      </ns1:sayHelloG>
</soapenv:Body></soapenv:Envelope>
回應soap:
<?xml version="1.0" encoding="utf-8"?><soapenv:Envelope xmlns:soapenv="
<soapenv:Body>
 <ns1:sayHelloGResponse soapenv:encodingStyle="


菠蘿 2007-08-06 22:43 發表評論
]]>
用DataHandler來實現一個帶附件的soap請求的web services http://m.tkk7.com/boluobn/articles/134809.html菠蘿菠蘿Mon, 06 Aug 2007 14:40:00 GMThttp://m.tkk7.com/boluobn/articles/134809.htmlhttp://m.tkk7.com/boluobn/comments/134809.htmlhttp://m.tkk7.com/boluobn/articles/134809.html#Feedback0http://m.tkk7.com/boluobn/comments/commentRss/134809.htmlhttp://m.tkk7.com/boluobn/services/trackbacks/134809.html2.編寫服務程序(.java),既支持文本文件,也支持二進制文件。
package test.gaolong;

import java.io.*;
import javax.activation.*;

public class FileService{
  public static String Repository="./files/";
  public String putFile(DataHandler dh,String name){
   if(name==null)
       name="test.tmp";
       System.out.println("test");
   try{
    File dir=new File(Repository);
    if(!dir.exists()){
         dir.mkdir(); System.out.println("makedir"+"test");
      }
    InputStream input=dh.getInputStream();
    FileOutputStream fos=new FileOutputStream(new File(dir,name));
    System.out.println("test");
    byte[] buffer=new byte[1024*4];
    int n=0;
    while((n=input.read(buffer))!=-1){
     fos.write(buffer,0,n);
     System.out.println(buffer);
    }
    System.out.println("test");
    input.close();
    fos.close();
   }catch(IOException e){
    e.printStackTrace();
   }
  return name+"send OK";
 }
 public DataHandler getFile(String name){
  File dir=new File(Repository);
  if(!dir.exists())
  dir.mkdir();
  File data=new File(dir,name);
  if(data.exists())
         return new DataHandler(new FileDataSource(data));
  else
         return null;
  }
}
3。寫deploy.wsdd部署描述文件如下:
<deployment xmlns="http://localhost:7001/axis/services/FileService" >
  <service name="FileService" provider="java:RPC">
    <parameter name="className" value="test.gaolong.FileService"/>
    <parameter name="allowedMethods" value="*"/>
    <parameter name="allowedRoles" value="user"/>
    <operation name="getFile" returnQName="returnqname" returnType="ns1:DataHandler" xmlns:SchemaNS="      <parameter name="name" type="SchemaNS:string"/>
    </operation>
     <operation name="putFile" returnQName="returnqname" returnType="ns1:DataHandler" xmlns:SchemaNS="
      <parameter name="dh" type="ns1:DataHandler"/>
      <parameter name="name" type="SchemaNS:string"/>
    </operation>
    <typeMapping deserializer="org.apache.axis.encoding.ser.JAFDataHandlerDeserializerFactory" type="java:javax.activation.DataHandler" qname="ns1:DataHandler" serializer="org.apache.axis.encoding.ser.JAFDataHandlerSerializerFactory" encodingStyle="
http://schemas.xmlsoap.org/soap/encoding/%22/%3E//注意見下面的。
  </service>
</deployment>

注:對于soap1.2而言,要使用上面的<typeMaping>,而對于soap1.1而言,則有一點區別如下:
 <typeMapping deserializer="org.apache.axis.encoding.ser.JAFDataHandlerDeserializerFactory" lanuageSpecificType="java:javax.activation.DataHandler" qname="ns1:DataHandler" serializer="org.apache.axis.encoding.ser.JAFDataHandlerSerializerFactory" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/%22/>
4。啟動服務器,用java org.apache.axis.client.AdminClient  -p 7001  deploy.wsdd部署webservices即可訪問。
5。編寫客戶端應用訪問程序如下:
 import javax.xml.rpc.ParameterMode;
import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
import org.apache.axis.encoding.XMLType;
import javax.xml.namespace.QName;
import org.apache.axis.soap.SOAP11Constants;
import java.net.URL;
import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import org.apache.axis.encoding.ser.*;
public class ServiceClient{
 public static void main(String[] args) throws Exception{
  String filename="HelloWorld.java";
  DataHandler dh=new DataHandler(new FileDataSource(filename));
  String endpoint="  String name="gaolong1";
  Service service=new Service();
  Call call=(Call) service.createCall();
     call.setTargetEndpointAddress(new java.net.URL(endpoint));
     call.setOperationName(new QName("
        QName qnameattachment=new QName("FileService","DataHandler");
        call.registerTypeMapping(dh.getClass(),qnameattachment,JAFDataHandlerSerializerFactory.class,JAFDataHandlerDeserializerFactory.class);
        call.addParameter("s1",qnameattachment,ParameterMode.IN);
        call.addParameter("s2",XMLType.XSD_STRING,ParameterMode.IN);
  call.setReturnType(XMLType.XSD_STRING);//XMLType.XSD_STRING);//用Class.forName("java.lang.String")來獲取java類型
  String ret=(String)call.invoke(new Object[] {dh,"HelloWorld.java"});
  System.out.println(ret);
 }
}
6。成功執行客戶端應用程序,可以找到上傳文件。
請求的soap消息:
POST /axis/services/FileService HTTP/1.0
Content-Type: multipart/related; type="text/xml"; start="<3165C8664597DC7EF29D5BFAC8972562>";  boundary="----=_Part_0_21866740.1141202759484"
Accept: application/soap+xml, application/dime, multipart/related, text/*
User-Agent: Axis/1.2.1
Host: localhost:7003
Cache-Control: no-cache
Pragma: no-cache
SOAPAction: ""
Content-Length: 1050


------=_Part_0_21866740.1141202759484
Content-Type: text/xml; charset=UTF-8
Content-Transfer-Encoding: binary
Content-Id: <3165C8664597DC7EF29D5BFAC8972562>

<?xml version="1.0" encoding="UTF-8"?><soapenv:Envelope xmlns:soapenv="http://www.w3.org/2001/XMLSchema-instance%22%3E%3Csoapenv:Body%3E%3Cns1:putFile soapenv:encodingStyle="------=_Part_0_21866740.1141202759484
Content-Type: application/octet-stream
Content-Transfer-Encoding: binary
Content-Id: <03D9C1D3A9E0788D274934C3ABD52811>

public class HelloWorld{
  public String sayHello(String name){
         return "Hello"+name;
         }
      }
------=_Part_0_21866740.1141202759484--
上傳后的文件的位置:/*在該目錄下創建文件夾:D:\bea\user_projects\domains\mydomain\files,并把相應的文件存入該目錄下*/
7.另一種基于java mail的帶附件的傳輸,是基于xmlDOM+servlet可以來實現,只是比較底層而已。



菠蘿 2007-08-06 22:40 發表評論
]]>
為什么需要Web Service http://m.tkk7.com/boluobn/articles/134808.html菠蘿菠蘿Mon, 06 Aug 2007 14:35:00 GMThttp://m.tkk7.com/boluobn/articles/134808.htmlhttp://m.tkk7.com/boluobn/comments/134808.htmlhttp://m.tkk7.com/boluobn/articles/134808.html#Feedback0http://m.tkk7.com/boluobn/comments/commentRss/134808.htmlhttp://m.tkk7.com/boluobn/services/trackbacks/134808.html從前,分布式的應用程序邏輯需要使用分布式的對象模型,諸如:微軟的分布式組件對象模型(DCOM)、對象管理集團的公用對象請求代理程序體系結構(CORBA)或Sun的遠程方法調用(RMI)。通過使用這種基本結構,開發人員仍可擁有使用本地模型所提供的豐富資源和精確性,并可將服務置于遠程系統中。

當我已經有了我中意的中間件平臺(RMI, Jini, CORBA, DCOM 等等)時,為什么還要為Web而煩惱呢?中間件確實提供了強大的服務實現手段,但是,這些系統有一個共同的缺陷,那就是它們無法擴展到互聯網上:它們要求服務客戶端與系統提供的服務本身之間必須進行緊密耦合,即要求一個同類基本結構。這樣的系統往往十分脆弱:如果一端的執行機制發生變化,那么另一端便會崩潰。例如,如果服務器應用程序的接口發生更改,那么客戶端便會崩潰。

要求提供緊密耦合的基本結構,無可厚非,許多應用程序均是基于這種系統構建而成的。但是,當各個公司需要相互合作、或信息技術提供商擴大業務范圍時,便很難實現單一而統一的基本結構。您根本無法保證您希望與之進行遠程通信的管道的另一端,具備所有您需要的基本結構:對于它使用的操作系統、對象模型或編程語言,您可能一無所知。

相反,Web服務彼此是松散偶合的。連接中的任何一方均可更改執行機制,卻不影響應用程序的正常運行。從技術角度講,人們已轉向使用一種基于消息的異步技術來實現高可靠性的系統性能,通過使用諸如HTTP、簡單郵件傳輸協議(SMTP)以及至為重要的XML來實現統一的連接。

Web作為信息發布者的力量就在于簡單且無處不在,這對解決現在這樣一個分裂中間件世界很重要。Web通過在傳統中間件平臺上更有效實現的Services,來提供一個統一且廣泛適用的接口,這樣就改善了這個平臺。

從一個N層應用程序結構的角度來看,web service只是一個方便程序訪問的包裝,服務還是要靠中間件來實現。訪問包括服務請求處理(監聽者)和一個支持商業邏輯操作的接口,商業邏輯本身是由傳統的中間件平臺實現的。

從理論上講,開發人員可通過調用Web應用編程接口(API)(就像調用本地服務一樣),將Web服務集成到應用程序中,不同的是Web API調用可通過互聯網發送給位于遠程系統中的某一服務。例如,Microsoft Passport服務使得開發人員能夠對某應用程序進行驗證。通過Passport服務編程,開發人員可以充分利用Passport的基本結構,通過運行Passport來維護用戶數據庫,以確保它的正常運行、定期備份等等。

消息傳遞系統將通信的基本單元打包成自我描述型的數據包(又稱作消息),并將其放到網絡纜線中。消息傳遞系統與分布式對象系統之間的本質區別在于:要求發送方辨識接收方的基本結構的程度有所不同。在分布式系統中,發送方需對接收方的情況作出種種猜測:應用程序是如何激活或拆包的,調用的是什么樣的界面,等等。

另一方面,消息傳遞系統會在纜線格式級上創建合同。發送方既不需考慮消息被接收后的情況,也不需考慮接發雙方之間的通信情況,唯一需要考慮的是接收方是否能辯識發送的消息內容。

在纜線格式級上創建合同的優勢不言而喻。例如,接收方可在任何時刻進行更改,而不會干擾發送方的消息發送,只要它仍可辯識原有消息的內容。另外,發送方無需任何特殊的軟件即可與接收方通信:只要它發出正確格式的消息,接收方就可以響應。



菠蘿 2007-08-06 22:35 發表評論
]]>
WebService之axis的復雜對象傳輸 http://m.tkk7.com/boluobn/articles/134807.html菠蘿菠蘿Mon, 06 Aug 2007 14:32:00 GMThttp://m.tkk7.com/boluobn/articles/134807.htmlhttp://m.tkk7.com/boluobn/comments/134807.htmlhttp://m.tkk7.com/boluobn/articles/134807.html#Feedback0http://m.tkk7.com/boluobn/comments/commentRss/134807.htmlhttp://m.tkk7.com/boluobn/services/trackbacks/134807.html寫一個deploy.wsdd 文件:
<deployment xmlns="http://xml.apache.org/axis/wsdd/" xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
<service name="mShop" provider="java:RPC">
<parameter name="className" value="tests.shop"/>
<parameter name="allowedMethods" value="*"/>
<typeMapping deserializer="org.apache.axis.encoding.ser.BeanDeserializerFactory"
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
qname="ns1:book"
serializer="org.apache.axis.encoding.ser.BeanSerializerFactory"
type="java:tests.book"
xmlns:ns1="http://127.0.0.1:8080/axis/services/mShop"/>

</service>
</deployment>

服務發布后,以上的發布信息都會被添加到server-config.wsdd文件里~
若服務發布出了什么問題(比如View里面看不到任何服務等……==!)一個考慮的就是這個server-config.wsdd~
上面的高亮顯示,這是關鍵,它在server端定義如何序列化和反序列化complexType
若沒有這個,那么你在客戶端registry.getDefaultTypeMapping()將什么都得不到~~

這里的<typeMapping .../>定義了一個book對象,它是服務方法 public book[] getAllBooks() 的返回類型,類定義在tests.book,namespace是服務的namespace
具體的wsdd文件說明在axisUserguide里面,具體位置 : %axis_home%/docs/reference.html
以此類推,服務中所有的非原子類型返回都必須typeMapping一下~~~(= =!汗)

注冊復雜類型的客戶端代碼:


org.apache.axis.client.Service service = new org.apache.axis.client.Service();
TypeMappingRegistry registry = service.getTypeMappingRegistry();
TypeMapping map = registry.getDefaultTypeMapping();
QName qType = new QName("http://localhost/tests","book");
Class qClass = Class.forName("tests.book");
map.register(qClass,qType,new BeanSerializerFactory(qClass, qType),
new BeanDeserializerFactory(qClass, qType));

要注意,Service是org.apache.axis.client.Service,而不是javax.xml.rpc.Service,如果用錯了axis會發出一大堆http500來抱怨的~~~

菠蘿 2007-08-06 22:32 發表評論
]]>
Servlet與Web服務 http://m.tkk7.com/boluobn/articles/134804.html菠蘿菠蘿Mon, 06 Aug 2007 14:23:00 GMThttp://m.tkk7.com/boluobn/articles/134804.htmlhttp://m.tkk7.com/boluobn/comments/134804.htmlhttp://m.tkk7.com/boluobn/articles/134804.html#Feedback0http://m.tkk7.com/boluobn/comments/commentRss/134804.htmlhttp://m.tkk7.com/boluobn/services/trackbacks/134804.html===============================================================================================

為了能讓web服務先跑起來,先給出一個Web服務的原型,以便于后面的討論。
我們從一個最簡單的例子開始,只給出必須的東西。

所需軟件:
1.Tomcat4.1.2
2.一個Java編譯器,jdk或JBuilder等等,這是為了編譯我們的Java源程序,于web服務無關。

所需文件:
1.sayHello.java
2.web.xml
3.server-config.xml
4.Java Packages: axis.jar,jaxrpc.jar,tt-bytecode.jar,wsdl4j.jar,xercesImpl.jar,xml-apis.jar

至于Tomcat怎么安裝我就不說了,網上關于Tomcat安裝的文章有很多。
這六個package,從ibm和apache的網站上都可以下得到。

只需要這些,我們就可以部署自己的Web服務了。。
下面是目錄結構:
webapps/test/WEB-INF/web.xml
webapps/test/WEB-INF/server-config.wsdd
webapps/test/WEB-INF/classes/sayHello.class
webapps/test/WEB-INF/lib/xxx.jar ---所需得六個packages


web.xml
---------------------------------------------

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN" "http://java.sun.com/j2ee/dtds/web-app_2_2.dtd">

<web-app>

<servlet>
    <servlet-name>Axis</servlet-name>
    <!--實際servlet程序,這里是AxisServlet-->
    <servlet-class>org.apache.axis.transport.http.AxisServlet</servlet-class>
</servlet>

<!-- ### 定義servlet和url的對應關系-->

<servlet-mapping>
    <servlet-name>Axis</servlet-name>
    <url-pattern>/services/*</url-pattern>
</servlet-mapping>

</web-app>

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

server-config.wsdd
---------------------------------------------
<?xml version="1.0" encoding="UTF-8"?>
<deployment xmlns:java="http://xml.apache.org/axis/wsdd/providers/java" xmlns="http://xml.apache.org/axis/wsdd/">

<handler type="java:org.apache.axis.handlers.http.URLMapper" name="URLMapper"/>
  
<service name="sayHelloService" provider="java:RPC">
  <parameter name="className" value="sayHello"/>
  <parameter name="allowedMethods" value="sayHelloTo"/>
</service>

<transport name="http">
  <requestFlow>
    <handler type="URLMapper"/>
  </requestFlow>
</transport>

</deployment>
---------------------------------------------

sayHello.java
---------------------------------------------
public class sayHello
{
  public String sayHelloTo(String aname)
  {
    return "How are you, " + aname;
  }
}
---------------------------------------------


假設ip地址192.168.0.1,端口號是80,我們輸入下面的url得到服務列表(當然這里只有一個):
http://192.168.0.1/test/services
如果你的端口號是8080,就應該輸入http://192.168.0.1:8080/test/services,后面同理。

瀏覽器顯示:
——————————————
|And now... Some Services |
| sayHelloService (wsdl)  |
|  .sayHelloTo            |   
——————————————

sayHelloService是我們的服務名,右側的 (wsdl)是一個鏈接指向sayHelloService的WSDL文檔,
這個文檔是由Axis自動生成的。
sayHelloTo當然就是我們的方法了。。。

點擊(wsdl)鏈接或輸入下面的url,得到WSDL:
http://192.168.0.1/test/services/sayHelloService?wsdl

瀏覽器顯示sayHelloService的WSDL文檔:

<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions targetNamespace="http://192.168.0.1/test/services/sayHelloService/test/services/sayHelloService" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:apachesoap="http://xml.apache.org/xml-soap" xmlns:impl="http://192.168.0.1/test/services/sayHelloService/test/services/sayHelloService-impl" xmlns:intf="http://192.168.0.1/test/services/sayHelloService/test/services/sayHelloService" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <wsdl:message name="sayHelloToResponse">
    <wsdl:part name="return" type="xsd:string"/>
  </wsdl:message>
  <wsdl:message name="sayHelloToRequest">
    <wsdl:part name="aname" type="xsd:string"/>
  </wsdl:message>
  <wsdl:portType name="sayHello">
    <wsdl:operation name="sayHelloTo" parameterOrder="aname">
      <wsdl:input message="intf:sayHelloToRequest" name="sayHelloToRequest"/>
      <wsdl:output message="intf:sayHelloToResponse" name="sayHelloToResponse"/>
    </wsdl:operation>
  </wsdl:portType>
  <wsdl:binding name="sayHelloServiceSoapBinding" type="intf:sayHello">
    <wsdlsoap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
    <wsdl:operation name="sayHelloTo">
      <wsdlsoap:operation soapAction=""/>
      <wsdl:input name="sayHelloToRequest">
        <wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://192.168.0.1/test/services/sayHelloService/test/services/sayHelloService" use="encoded"/>
      </wsdl:input>
      <wsdl:output name="sayHelloToResponse">
        <wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://192.168.0.1/test/services/sayHelloService/test/services/sayHelloService" use="encoded"/>
      </wsdl:output>
    </wsdl:operation>
  </wsdl:binding>
  <wsdl:service name="sayHelloService">
    <wsdl:port binding="intf:sayHelloServiceSoapBinding" name="sayHelloService">
      <wsdlsoap:address location="http://192.168.0.1/test/services/sayHelloService"/>
    </wsdl:port>
  </wsdl:service>
</wsdl:definitions>



我們甚至不用客戶端,就可以查看服務是否部署成功以及獲得返回結果
用Get方法獲得soap流,我們要用下面的url:
(真正調用Web服務,用的是Post方法,這個后面會講)

http://192.168.0.1/test/services/sayHelloService?method=sayHelloTo&aname=everybody

瀏覽器顯示的是亂碼,我們點右鍵查看源文件,結果如下:

<p>Got response message</p>
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <soapenv:Body>
  <sayHelloToResponse soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
   <sayHelloToReturn xsi:type="xsd:string">How are you, everybody</sayHelloToReturn>
  </sayHelloToResponse>
 </soapenv:Body>
</soapenv:Envelope>

這就是我們想要的結果嗎?這只是服務器端送回來的SOAP消息,不過我們想要的結果在里面。。。


為了真正調用我們的Web服務,下面給出一個Client:

import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
import javax.xml.namespace.QName;

  public class test
  {
    public static void main(String [] args)
    {
      try {
             String endpoint = "http://192.168.0.1/test/services/sayHelloService";
             Service  service = new Service();
             Call     call    = (Call) service.createCall();
             call.setTargetEndpointAddress( new java.net.URL(endpoint) );
             call.setOperationName(new QName("http://sayHelloService", "sayHelloTo"));
             String ret = (String) call.invoke( new Object[] { args[0] } );
             System.out.println(ret);
         } catch (Exception e) {
             e.printStackTrace();
         }
    }
  }

  注意要配置好正確的classpath,確保編譯器能找的到axis.jar和jaxrpc.jar,否則編譯不會通過。
  用下面的命令行運行這個class:
  java test everybody
  我們會得到:How are you, everybody

  這才是我們真正想要的。。。



2.追根究底,我們的Web服務是怎樣跑起來的
===============================================================================================


前面給出的兩個配置文件web.xml和server-config.wsdd,或許不是能一下子就看懂的。

先讓我們回顧一下servlet的映射模式。

我們知道,servlet是從javax.servlet.http.HttpServlet繼承的,在服務器端被載入JVM執行,然后向客戶端輸出html流。
servlet的web.xml文件(位于 webapps/foo/WEB-INF目錄):

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN"
                         "http://java.sun.com/j2ee/dtds/web-app_2.2.dtd">
<web-app>
<servlet-mapping>
<servlet-name>invoker</servlet-name>
<url-pattern>/servlet/*</url-pattern>
</servlet-mapping>
</web-app>


invoker servlet 其實是:org.apache.catalina.servlets.InvokerServlet
按類名提供小服務程序。例如,如果您調用 foo/servlet/HelloServlet,
invoker servlet將裝入該HelloServlet(如果它在其類路徑中的話)并執行。

初看上面的web.xml,好像只給出了一個servlet映射,而沒有定義invoker servlet。
其實,invoker servlet 是在tomcat的conf目錄中的web.xml中定義的::
 <servlet>
        <servlet-name>invoker</servlet-name>
        <servlet-class>
          org.apache.catalina.servlets.InvokerServlet
        </servlet-class>
        <init-param>
            <param-name>debug</param-name>
            <param-value>0</param-value>
        </init-param>
        <load-on-startup>2</load-on-startup>
    </servlet>

所以,如果拋開Tomcat_HOME/conf/web.xml,我們這樣定義一個web.xml,似乎更能清楚的說明問題:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN"
                         "http://java.sun.com/j2ee/dtds/web-app_2.2.dtd">
<web-app>
<servlet-name>MyInvoker</servlet-name>
<servlet-class>
org.apache.catalina.servlets.InvokerServlet
</servlet-class>
<init-param>
<param-name>debug</param-name>
<param-value>0</param-value>
</init-param>
<load-on-startup>2</load-on-startup>
</servlet>

<servlet-mapping>
<servlet-name>MyInvoker</servlet-name>
<url-pattern>/servlet/*</url-pattern>
</servlet-mapping>
</web-app>


即所有/servlet/* 模式的url,都會交給org.apache.catalina.servlets.InvokerServlet來處理。
或者說,所有/servlet/* 模式的url,其實都是調用InvokerServlet這個類,而InvokerServlet本身也是
一個servlet,它也是從 HttpServlet 繼承而來的。

這樣,我們自己的servlet就能夠通過特定的url執行,即 /servlet/OurServlet。
當然,如果你高興,可以定義任何的 url pattern,而不一定是 /servlet/*,這一點,正如我們后面
看到的Axis處理Soap消息的方法。


再進一步,如果不想讓 InvokerServlet 在中間“搗鬼”,我們當然可以直接定義自己的servlet:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN"
                         "http://java.sun.com/j2ee/dtds/web-app_2.2.dtd">
<web-app>
<servlet-name>MyInvoker2</servlet-name>
<servlet-class>
com.foo.MyServlet
</servlet-class>
</servlet>

<servlet-mapping>
<servlet-name>MyInvoker2</servlet-name>
<url-pattern>/AnyName/*</url-pattern>
</servlet-mapping>
</web-app>


JSP也是一樣的道理,有了上面的分析,
看看Tomcat_HOME/conf/web.xml中的如下語句就可以JSP的處理方法了,這里就不再廢話了:
....
<servlet>
        <servlet-name>jsp</servlet-name>
        <servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
        <init-param>
            <param-name>logVerbosityLevel</param-name>
            <param-value>WARNING</param-value>
        </init-param>
        <load-on-startup>3</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>jsp</servlet-name>
    <url-pattern>*.jsp</url-pattern>
</servlet-mapping>
....


下面進入正題。


我們先來看部署Web Service的web.xml:

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN" "http://java.sun.com/j2ee/dtds/web-app_2_2.dtd">

<web-app>

<servlet>
    <servlet-name>Axis</servlet-name>
    <!--實際servlet程序,這里是AxisServlet-->
    <servlet-class>org.apache.axis.transport.http.AxisServlet</servlet-class>
</servlet>

<!-- ### 定義servlet和url的對應關系-->

<servlet-mapping>
    <servlet-name>Axis</servlet-name>
    <url-pattern>/services/*</url-pattern>
</servlet-mapping>

</web-app>


所有 /services/* 模式的 url 都會交給org.apache.axis.transport.http.AxisServlet處理,
AxisServlet當然也是從HttpServlet繼承而來的。這就是為什么我們部署的Web服務在調用時都要在
服務名稱前加上 services/ 了。

可以說,AxisServlet是所有Web服務調用的入口。
那么AxisServlet在接手Web服務調用后都做了哪些工作呢?

客戶端用call.invoke()調用web服務用的是POST,所以入口是AxisServlet.doPost...
而不是AxisServlet.doGet...


先來看看AxisServlet的doPost函數,這里只給出了關鍵語句及注釋:

    /**
     * Process a POST to the servlet by handing it off to the Axis Engine.
     * Here is where SOAP messages are received
     * @param req posted request
     * @param res respose
     * @throws ServletException trouble
     * @throws IOException different trouble
     */
     public void doPost(HttpServletRequest req, HttpServletResponse res)
        throws ServletException, IOException
    {
msgContext = createMessageContext(engine, req, res);//獲取客戶請求信息

engine.invoke(msgContext); //調用客戶端請求的服務

responseMsg = msgContext.getResponseMessage();//得到調用的返回結果

sendResponse(getProtocolVersion(req), contentType, res, responseMsg);//將結果送至客戶端
     }

這樣一來,Web服務調用的來龍去脈就大致清楚了。。。

為了高清楚前面我們的三個url
http://192.168.0.1/test/services
http://192.168.0.1/test/services/sayHelloService?wsdl
http://192.168.0.1/test/services/sayHelloService?method=sayHelloTo&aname=everybody
是怎樣獲得輸出結果的,再來看看AxisServlet的doGet函數,這里只給出了流程框架及注釋:

**
* Process GET requests. Because Axis does not support the GET-style
* pseudo execution of SOAP methods, this handler deals with queries
* of various kinds, not real SOAP actions.
*
* @todo for secure installations, dont stack trace on faults
* @param request request in
* @param response request out
* @throws ServletException
* @throws IOException
*/
public void doGet(HttpServletRequest req, HttpServletResponse res)
        throws ServletException, IOException
{

//如果路徑為空,比如:http://localhost/wstk/services 或 http://localhost/wstk/services/*
if((pathInfo == null || pathInfo.equals("")) && !realpath.endsWith(".jws"))

{
//從server-config.wsdd文件中讀取所有部署的服務信息,向向客戶端列出所有部署的服務,
//包括每個服務可調用的方法。

}else
//如果路徑不為空,比如:http://localhost/wstk/services/sayHelloService
if(realpath != null)
{
//如果請求wsdl,比如:http://localhost/wstk/services/sayHelloService?wsdl
if(wsdlRequested)
{
//創建sayHelloService的WSDL文件并傳送至客戶端
} else
//這里是利用url調用Web服務的入口,比如http://192.168.0.1/test/services/sayHelloService?method=sayHelloTo&aname=everybody
if(req.getParameterNames().hasMoreElements())
{
//如果客戶端調用的方法正確,則Axis會調用相應的JavaBean,并把JavaBean的返回結果
//封裝為Soap消息流返回給客戶端。
}
}
}


而Axis怎樣找到我們所請求的JavaBean呢?答案是server-config.wsdd文件。

server-config.wsdd

<?xml version="1.0" encoding="UTF-8"?>
<deployment xmlns:java="http://xml.apache.org/axis/wsdd/providers/java" xmlns="http://xml.apache.org/axis/wsdd/">

<service name="sayHelloService" provider="java:RPC">
  <parameter name="className" value="sayHello"/>
  <parameter name="allowedMethods" value="sayHelloTo"/>
</service>

<handler type="java:org.apache.axis.handlers.http.URLMapper" name="URLMapper"/>

<transport name="http">
  <requestFlow>
    <handler type="URLMapper"/>
  </requestFlow>
</transport>

</deployment>

WSDD是web service deployment descriptor的縮寫。

最外面的<deployment>元素指示這是WSDD,并定義了java的名字空間。

接著的 <service>元素定義了service。一個service是一個目標鏈,包括請求request、內容提供者provider、響應response。
在這個例子中,我們指出service名字是sayHelloService ,provider是"java:RPC",它是axis 的標記,指示這是一個java的RPC service,
而處理它的真正的class是org.apache.axis.providers.java.RPCProvider。

接著我們要在<parameter>中告訴RPCProvider,它如何實例化并調用正確的class(如:com.foo.MyService)。
<parameter>元素的className指示class名,allowedMethods告訴引擎那些共用的方法要通過soap來調用。
"*"表示所有的公共方法,我們也列出方法名字列表,可以空格或逗號分割它們。

菠蘿 2007-08-06 22:23 發表評論
]]>
主站蜘蛛池模板: 亚洲黄片手机免费观看| 亚洲av永久无码精品天堂久久| 男人天堂2018亚洲男人天堂| 日本免费一区二区三区| 亚洲AV日韩AV永久无码久久| 最近免费字幕中文大全| 久久国产亚洲精品麻豆| 在线毛片片免费观看| 亚洲嫩模在线观看| 亚洲一区二区三区免费观看| 亚洲性69影院在线观看| 黄页网站在线看免费| 麻豆狠色伊人亚洲综合网站| 在线观看免费毛片| 男女污污污超污视频免费在线看| www.91亚洲| 国内永久免费crm系统z在线| 91亚洲国产在人线播放午夜| 青娱乐免费在线视频| 亚洲码欧美码一区二区三区| 亚洲AⅤ优女AV综合久久久| 久久久精品国产亚洲成人满18免费网站 | 免费的一级片网站| 中美日韩在线网免费毛片视频| 国产成人麻豆亚洲综合无码精品 | 中文字幕免费在线| 久久亚洲精品国产精品婷婷 | 少妇太爽了在线观看免费视频| 亚洲国产日韩在线成人蜜芽| 日本一道一区二区免费看| 午夜肉伦伦影院久久精品免费看国产一区二区三区 | 亚洲欧美一区二区三区日产| 亚洲综合色视频在线观看| 久久精品无码专区免费东京热| 亚洲无人区码一二三码区别图片 | 亚洲精品中文字幕无码A片老| 国产精品xxxx国产喷水亚洲国产精品无码久久一区 | 久久久久国产精品免费网站| 亚洲午夜精品一区二区麻豆| 亚洲熟妇中文字幕五十中出| 国产在线a免费观看|