AXIS ตอนที่ 2 :: Create/Publish Service

posted on 01 Mar 2005 16:40 by somkiat

AXIS ตอนที่ 2

การสร้างตัวอย่าง webservice และการ publish webservice

Testing Requirement

  1. Apache AXIS 1.1

  2. Tomcat 5.0/IBM WebSphere Application Server 4.0/5.1

ก่อนที่จะสร้าง Service นั้นเรามาดูเรื่องของการ publish service ขึ้น server เพื่อให้ใช้งานกันก่อนครับ โดย AXIS จะมีการ publish 2 แบบ คือ

1. JWS (Java Web Service) Files

2. Custom Deployment

แต่ในตอนนี้ผมจะใช้การ publish แบบที่สองครับ เนื่องจาก Service ที่จะสร้างขึ้นมามีการใช้ Data type ชนิด Complex type ด้วยครับเช่น JavaBean, Vector เป้นต้นครับ

การ publish แบบที่สอง นี้จะมี config file 1 ตัวคือ deploy.wsdd

Wsdd == WebService Deployment Descriptor

ตัวอย่าง deploy.wsdd

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

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

<parameter name="className" value="com.ws.Test"/>

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

<beanMapping qname="myNS:TestBean" xmlns:myNS="urn:BeanService"

languageSpecificType="java:com.ws.TestBean"/>

</service>

</deployment>

คำอธิบาย

1. ผมตั้งชื่อ Service นี้ว่า TestService

2. service class ที่ทำการสร้างส่วนของ service อยู่ใน file com.ws.Test.java โดยจะทุกๆ method ใน class นี้เป้น service ทั้งหมดครับ

3. ส่วนของ Bean mapping นี้ผมจะ service ที่ทำการ return ค่าออกมาเป็น JavaBean ครับ ซึ่งคือ file com.ws.TestBean.java

ว่าแล้วเรามาเริ่มสร้าง WebService ด้วย AXIS กันเลยครับ ผมจะไม่มี HelloWorld หรือ Calculator program แล้วนะครับ ผมจะสร้างตัวอย่างที่ใช้พวก Complex Type กันเลย

ขั้นตอนการสร้าง

1. สร้าง class สำหรับ implement Service method จากตัวอย่างจะอยู่ใน com.ws.Test.java ดังนี้ครับ

package com.ws;

import java.util.Vector;

public class Test {

public Vector getDatas() {

Vector datas = new Vector();

TestBean p = new TestBean();

p.setName("Test Data");

datas.add(p);

return datas; }

}

package com.ws;

public class TestBean {

private String name;

/**

* @return

*/

public String getName() {

return name;

}

/**

* @param string

*/

public void setName(String string) {

name = string;

}

}

ทำการ compile code และนำ class ไปเก็บไว้ที่ %CATALINA_HOME%/webapps/axis/WEB-INF ด้วยนะครับ

แล้วก็ทำการ Start Tomcat Server ครับผม

2. หลังจากสร้าง Service เสร็จแล้วเราก็มาทำการ publish service ขึ้น server กันเลยครับ โดยจะต้องสร้าง deploy.wsdd ดังนี้

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

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

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

<parameter name="className" value="com.ws.Test"/>

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

<beanMapping qname="myNS:TestBean" xmlns:myNS="urn:BeanService"

languageSpecificType="java:com.ws.TestBean"/>

</service>

</deployment>

และทำการ run command ดังนี้

% java org.apache.axis.client.AdminClient deploy.wsdd

ผลลัพธ์ที่ถูกต้องคือ

<Admin>Done processing</Admin>

ในการ run java program นี้ผมใช้ tool ของ Eclipse/WebSphere ช่วยครับ ถ้าใครไม่มี tool เหล่านี้หรือ tool อื่นๆ จะต้อง set CLASSPATH ต่างๆ ที่จะใช้ให้ถูกต้องนะครับ เช่น

· axis-1_1/lib/axis.jar

· axis-1_1/lib/jaxrpc.jar

· axis-1_1/lib/saaj.jar

· axis-1_1/lib/commons-logging.jar

· axis-1_1/lib/commons-discovery.jar

· axis-1_1/lib/wsdl4j.jar

· A JAXP-1.1 compliant XML parser such as Xerces or Crimson. We recommend Xerces,

3. ทดสอบ service ว่า publish ขึ้น server แล้วหรือยัง

จากบทความก่อนหน้าผมอธิบายการติดตั้ง AXIS บน Tomcat ซึ่งจะอยู่ใน web context ชื่อว่า AXIS ซึ่งเราก็ start tomcat และเปิด browser ไปที่ http://localhost:8080/axis และไปที่ view hyperlink เพื่อดูว่า service ชื่อ TestService มีหรือไม่ ถ้ามีและมี method ต่างๆ แสดงว่าเราทำการ publish เสร็จเรียบร้อยแล้ว

จากหน้านี้เองเราสามารถที่จะ view/save wsdl file ได้ครับ ซึ่งจะนำไปใช้ในการสร้าง client application เพื่อใช้งาน service ที่เราสร้างขึ้นมา

4. มาลองสร้าง Client สำหรับเรียกใช้งาน Service กันโดยจะใช้ wsdj2java tool แต่ว่าผมไม่ใช้ครับผมจะใช้ Lomboz SOAP Client สำหรับการ generate java class จาก wsdl file ครับ

หลังจากที่เรา publish service ขึ้นไปบน server แล้วเราจะใช้งานโดย call service ดังกล่าวจะต้องใช้ wsdl filw ของ service นั้นๆ ครับ โดยผมจะ save wsdl ชือว่า testservice.wsdl

แล้วเราจะใช้งาน testservice.wsdl นี้อย่างไร

คำตอบก็คือเราสามารถทำได้ 2 แบบคือ

1. ใช้ java command เพื่อ run wsdl2java.exe ดังนี้

% java org.apache.axis.wsdl.WSDL2Java (WSDL-file-URL)

อย่าลืมว่าจะต้อง set Classpath ของ Library ต่างๆ ให้ครบด้วยครับ

2. ใช้ Plug-in ในการgenerate class จาก wsdl จะง่ายกว่าหน่อยครับ ซึ่งในตัวอย่างนี้ผมใช้ Lomboz plug-in for Elipse

หลังจากที่ทำการ generate java class (Proxy class) จากข้อ 2 แล้วจะได้ file ต่างๆ เหล่านี้ครับ

- Test.java

- TestBean.java

- TestBean_Helper.java

- TestService.java

- TestServiceLocator.java

- TestServiceSoapBindingStub.java

แล้วลองมาลองเรียกใช้งานดูกันนะครับ

Test service = new TestServiceLocator().getTestService();

Vector datas = service.getDatas();

for(Iterator it = datas.iterator(); it.hasNext();) {

TestBean value = (TestBean) it.next();

System.out.println(value.getName());

}

ผลลัพทธ์ที่ได้

Test Data

ลองทำตามผมดูนะครับ ถ้ามีปัญหาถามกันได้ครับ

Comment



smilebig smileopen-mounthed smileconfused smilesad smileangry smiletonguequestionembarrassedsurprised smilewinkdouble winkcry

Tweet

proxy class ต้องเอาไปไว้ที่ไหนครับ

#1 By nunu (203.113.67.39) on 2005-03-03 02:19

proxy class เป็นส่วนที่อยู่ฝั่ง client หรือ application ที่เรียกใช้ webservice ครับ

#2 By somkiat on 2005-03-03 23:10

เอ code ที่ัรันนี่จะเขียนใหม่หรือว่าอยู่ใน java ที่ gen มาได้ครับ

#3 By plynoi แว่วศรี on 2005-04-11 16:33

deploy.wsdd
save ไว้ไหน

#4 By (203.148.178.7 /171.1.1.133) on 2005-04-28 16:52

ได้แล้วคัย

#5 By (203.148.178.7 /171.1.1.133) on 2005-04-28 17:27

<deployment xmlns="http://xml.apache.org/axis/wsdd" xmlns:java="http://xml.apache.org/axis/wsdd/providers/java" xmlns:xsi="http://www.w3.org/2000/10/XMLSchema-instance">
<service name="DocService" style="message">
<parameter name="className" value="message.DocService"/>
<parameter name="allowedMethods" value="addNode2Doc"/>
</service>
</deployment>


C:\Program Files\Apache Software Foundation\Tomcat 5.0.19\webapps\axis\WEB-INF\DocService>java org.apache.axis.client.AdminClient deploy.wsdd
log4j:WARN No appenders could be found for logger (org.apache.axis.i18n.ProjectResourceBundle).
log4j:WARN Please initialize the log4j system properly.
Processing file deploy.wsdd
Exception: AxisFault
faultCode: {http://schemas.xmlsoap.org/soap/envelope/}Server.userException
faultSubcode:
faultString: java.lang.Exception: Unable to process the message -was it a valid
WSDD descriptor?
faultActor:
faultNode:
faultDetail:
{http://xml.apache.org/axis/}hostname:MyServer


แก้ไขอย่างไรครับ
ขอบคุณครับ

#6 By (203.148.178.7 /171.1.1.54) on 2005-05-03 15:50

log4j:WARN No appenders could be found for logger (org.apache.axis.i18n.ProjectResourceBundle).
log4j:WARN Please initialize the log4j system properly.
Processing file deploy.wsdd

คืออะไร และทำอย่างไร

#7 By (203.148.178.7 /171.1.1.54) on 2005-05-03 15:51

ตอบที่ละคำถามนะครับ

log4j:WARN No appenders could be found for logger (org.apache.axis.i18n.ProjectResourceBundle).
log4j:WARN Please initialize the log4j system properly.
Processing file deploy.wsdd

คืออะไร และทำอย่างไร


คือระบบหา file log4j.properties ไม่เจอครับ ทำให้ log4j ไม่สามารถทำงานได้ครับ แต่ว่า program ยังสามารถทำงานได้ปกติครับ

#8 By somkiat on 2005-05-16 17:39

ส่วน error ที่ส่งมานั้น ถ้าจะให้ดี กรุณาส่ง source code และ wsdd file มายัง somkiat_spns@hotmail.com แล้วจะตอบกลับโดยเร็วที่สุดครับ

ต้องขออภัยที่ตอบช้าๆๆๆ มาก เนื่องจากงานยุ่งครับ

ขออภัยอย่างแรงครับ

#9 By somkiat on 2005-05-16 17:43

Run JBOSS 4 & Axis 1.2.1 ได้ Error แบบนี้อ่ะครับ ช่วยดูที
- Exception:
org.xml.sax.SAXException: No deserializer for {urn:BeanService}TestBean
at org.apache.axis.encoding.DeserializerImpl.onStartElement(DeserializerImpl.java:453)
at org.apache.axis.encoding.DeserializerImpl.startElement(DeserializerImpl.java:393)
at org.apache.axis.encoding.DeserializationContext.startElement(DeserializationContext.java:1048)
at org.apache.axis.message.SAX2EventRecorder.replay(SAX2EventRecorder.java:165)
at org.apache.axis.message.MessageElement.publishToHandler(MessageElement.java:1141)
at org.apache.axis.encoding.DeserializerImpl.startElement(DeserializerImpl.java:369)
at org.apache.axis.encoding.DeserializationContext.startElement(DeserializationContext.java:1048)
at org.apache.axis.message.SAX2EventRecorder.replay(SAX2EventRecorder.java:165)
at org.apache.axis.message.MessageElement.publishToHandler(MessageElement.java:1141)
at org.apache.axis.encoding.DeserializerImpl.startElement(DeserializerImpl.java:369)
at org.apache.axis.encoding.DeserializationContext.startElement(DeserializationContext.java:1048)
at org.apache.axis.message.SAX2EventRecorder.replay(SAX2EventRecorder.java:165)
at org.apache.axis.message.MessageElement.publishToHandler(MessageElement.java:1141)
at org.apache.axis.message.RPCElement.deserialize(RPCElement.java:345)
at org.apache.axis.message.RPCElement.getParams(RPCElement.java:384)
at org.apache.axis.client.Call.invoke(Call.java:2448)
at org.apache.axis.client.Call.invoke(Call.java:2347)
at org.apache.axis.client.Call.invoke(Call.java:1804)
at localhost.axis.services.TestService.TestServiceSoapBindingStub.getDatas(TestServiceSoapBindingStub.java:100)
at test.Client.main(Client.java:60)
AxisFault
faultCode: {http://schemas.xmlsoap.org/soap/envelope/}Server.userException
faultSubcode:
faultString: org.xml.sax.SAXException: No deserializer for {urn:BeanService}TestBean
faultActor:
faultNode:
faultDetail:
{http://xml.apache.org/axis/}stackTrace:org.xml.sax.SAXException: No deserializer for {urn:BeanService}TestBean
at org.apache.axis.encoding.DeserializerImpl.onStartElement(DeserializerImpl.java:453)
at org.apache.axis.encoding.DeserializerImpl.startElement(DeserializerImpl.java:393)
at org.apache.axis.encoding.DeserializationContext.startElement(DeserializationContext.java:1048)
at org.apache.axis.message.SAX2EventRecorder.replay(SAX2EventRecorder.java:165)
at org.apache.axis.message.MessageElement.publishToHandler(MessageElement.java:1141)
at org.apache.axis.encoding.DeserializerImpl.startElement(DeserializerImpl.java:369)
at org.apache.axis.encoding.DeserializationContext.startElement(DeserializationContext.java:1048)
at org.apache.axis.message.SAX2EventRecorder.replay(SAX2EventRecorder.java:165)
at org.apache.axis.message.MessageElement.publishToHandler(MessageElement.java:1141)
at org.apache.axis.encoding.DeserializerImpl.startElement(DeserializerImpl.java:369)
at org.apache.axis.encoding.DeserializationContext.startElement(DeserializationContext.java:1048)
at org.apache.axis.message.SAX2EventRecorder.replay(SAX2EventRecorder.java:165)
at org.apache.axis.message.MessageElement.publishToHandler(MessageElement.java:1141)
at org.apache.axis.message.RPCElement.deserialize(RPCElement.java:345)
at org.apache.axis.message.RPCElement.getParams(RPCElement.java:384)
at org.apache.axis.client.Call.invoke(Call.java:2448)
at org.apache.axis.client.Call.invoke(Call.java:2347)
at org.apache.axis.client.Call.invoke(Call.java:1804)
at localhost.axis.services.TestService.TestServiceSoapBindingStub.getDatas(TestServiceSoapBindingStub.java:100)
at test.Client.main(Client.java:60)

{http://xml.apache.org/axis/}hostname:sunyaluk_mb

org.xml.sax.SAXException: No deserializer for {urn:BeanService}TestBean
at org.apache.axis.AxisFault.makeFault(AxisFault.java:101)
at org.apache.axis.client.Call.invoke(Call.java:2451)
at org.apache.axis.client.Call.invoke(Call.java:2347)
at org.apache.axis.client.Call.invoke(Call.java:1804)
at localhost.axis.services.TestService.TestServiceSoapBindingStub.getDatas(TestServiceSoapBindingStub.java:100)
at test.Client.main(Client.java:60)
Caused by: org.xml.sax.SAXException: No deserializer for {urn:BeanService}TestBean
at org.apache.axis.encoding.DeserializerImpl.onStartElement(DeserializerImpl.java:453)
at org.apache.axis.encoding.DeserializerImpl.startElement(DeserializerImpl.java:393)
at org.apache.axis.encoding.DeserializationContext.startElement(DeserializationContext.java:1048)
at org.apache.axis.message.SAX2EventRecorder.replay(SAX2EventRecorder.java:165)
at org.apache.axis.message.MessageElement.publishToHandler(MessageElement.java:1141)
at org.apache.axis.encoding.DeserializerImpl.startElement(DeserializerImpl.java:369)
at org.apache.axis.encoding.DeserializationContext.startElement(DeserializationContext.java:1048)
at org.apache.axis.message.SAX2EventRecorder.replay(SAX2EventRecorder.java:165)
at org.apache.axis.message.MessageElement.publishToHandler(MessageElement.java:1141)
at org.apache.axis.encoding.DeserializerImpl.startElement(DeserializerImpl.java:369)
at org.apache.axis.encoding.DeserializationContext.startElement(DeserializationContext.java:1048)
at org.apache.axis.message.SAX2EventRecorder.replay(SAX2EventRecorder.java:165)
at org.apache.axis.message.MessageElement.publishToHandler(MessageElement.java:1141)
at org.apache.axis.message.RPCElement.deserialize(RPCElement.java:345)
at org.apache.axis.message.RPCElement.getParams(RPCElement.java:384)
at org.apache.axis.client.Call.invoke(Call.java:2448)
... 4 more
Exception in thread "main"

#10 By somchai (202.44.71.10 /203.155.160.208) on 2005-07-24 11:28

#11 By (61.91.134.13) on 2005-08-16 18:11

http://www.link4u.com/value.htm

#12 By (202.9.121.178) on 2005-08-23 17:54

#13 By king (58.147.122.217) on 2005-09-06 03:31

คือว่าอยากทราบวิธีการเรียกใช้ที่ละเอียดว่านี้อะครับ เช่นต้องเอาไฟล์ของไคลเอนท์ไว้ที่ไหน และขอโค้ดแบบเต็มๆด้วยครับ

#14 By zofeus (61.7.139.128) on 2006-02-16 04:43

ตอนเรียกใช้ผมเกิด error ดังนี้ครับ

C:\Tomcat5.5\webapps\axis>javac Client.java
Client.java:8: unreported exception javax.xml.rpc.ServiceException; must be caug
ht or declared to be thrown
Test service= new TestServiceLocator().getTestService();
^
Client.java:10: unreported exception java.rmi.RemoteException; must be caught or
declared to be thrown
Vector datas =service.getDatas();
^
2 errors

#15 By zofeus (61.7.139.128) on 2006-02-16 04:45

ทำตามที่เขียนไว้ข้างบนแล้วนะคะ ไม่มี error ด้วย ได้ผลลัพธ์ ตาม <Admin>Done processing</Admin> แต่ขั้นตอนที่ 3 ไม่เจอ service ที่ประกาศไว้ ทำไมหรอคะ

#16 By Mr.L (58.147.36.115) on 2007-09-06 11:16