JAXM
(史帝芬, idealist@gcn.net.tw, J2SDK 1.4.2, JWSDP 1.4, JAXM 1.1.2, 2004/10/25)
JAXM提供B2B同步和非同步傳輸SOAP訊息,因為提供非同步傳輸,所以JAXM一定要在provider裡執行,
在提供非同步傳輸時,JAXM是以servlet的方式來實作。底下以一個簡單的例子說明JAXM,如果要更了解
JAXM可以參考安裝完成後的sample。因為我打算在WSAD 5.1.1上實作,所以Tomcat使用4.1.31版。(WSAD
尚不支援Tomcat 5)
下載並安裝Tomcat 4
以瀏覽器連線到http://jakarta.apache.org/site/binindex.cgi下載
Tomcat 4.1.31,並安裝到C:\Tomcat4,設定好環境變數,如不知如何安裝可參考http://my.so-net.net.tw/idealist/servlet/Tomcat.html。
下載並安裝JWSDP
以瀏覽器連線至http://java.sun.com/webservices/downloads/webservicespack.html
下載JWSDP,並安裝至c:\jwsdp-1.4。
下載並安裝JAXM 1.1.2
以瀏覽器連線至http://java.sun.com/xml/downloads/jaxm.html
下載JAXM,並安裝至c:\jaxm1.1.2。
設定環境
- 將C:\jwsdp-1.4\jaxp\lib\endorsed所有檔案拷貝至C:\Tomcat4\common\endorsed覆蓋所有檔案。
- 將C:\jwsdp-1.4\saaj\lib所有檔案拷貝至C:\Tomcat4\shared\lib。
- 將C:\jaxm1.1.2\lib所有檔案拷貝至C:\Tomcat4\shared\lib。
- 將C:\jaxm1.1.2\jaxm\jaxm-provider.war、C:\jaxm1.1.2\tools\jaxm-provideradmin.war拷貝至C:\Tomcat4\webapps。
- 將C:\jaxm1.1.2\samples所有檔案烤貝至C:\Tomcat4\webapps。
當設定好環境後,網友可以啟動Tomcat,並開啟C:\jaxm1.1.2\docs\index.html看看說明,依說明可以連線到
管理介面及sample。
接下來要在WSAD 5.1.1上實作一個sample,英文好的人可以直接看sun附的說明即可…
建立動態Web專案
開啟WSAD如圖1建立一個動態Web專案,命名為JAXM。

圖1
加入類別路徑
如圖2將底下檔案加入類別路徑…
- C:\jaxm1.1.2\lib\dom4j.jar
- C:\jaxm1.1.2\lib\jaxm-api.jar
- C:\jaxm1.1.2\lib\jaxm-runtime.jar
- C:\jwsdp-1.4\saaj\lib\saaj-api.jar
- C:\jwsdp-1.4\saaj\lib\saaj-impl.jar
- C:\jwsdp-1.4\jaxp\lib\endorsed\dom.jar
- C:\jwsdp-1.4\jaxp\lib\endorsed\sax.jar
- C:\jwsdp-1.4\jaxp\lib\endorsed\xalan.jar
- C:\jwsdp-1.4\jaxp\lib\endorsed\xercesImpl.jar

圖2
建立Java套件
在Java資源上按滑鼠右鍵,建立名為tw.idv.idealist.jaxm的套件 (圖3)。

圖3
建立接收端
建立Java類別,命名為ReceivingServlet,繼承JAXMServlet,實作ReqRespListener (圖4)。

圖4
填入如下source code…
package tw.idv.idealist.jaxm;
import java.util.*;
import javax.servlet.*;
import javax.xml.messaging.*;
import javax.xml.soap.*;
public class ReceivingServlet extends JAXMServlet implements ReqRespListener {
static MessageFactory fac = null;
private Map dic = new HashMap();
static {
try {
fac = MessageFactory.newInstance();
}
catch (Exception ex) {
ex.printStackTrace();
}
}
public void init(ServletConfig servletConfig) throws ServletException {
super.init(servletConfig);
dic.put("dog", "狗");
dic.put("cat", "貓");
dic.put("fish", "魚");
dic.put("bear", "熊");
dic.put("monkey", "猴");
}
public SOAPMessage onMessage(SOAPMessage message) {
System.out.println("收到訊息");
try {
System.out.println("開始處理訊息");
message.writeTo(System.out);
//取出請求之中欲查詢的英文字
SOAPEnvelope reqenvelope = message.getSOAPPart().getEnvelope();
SOAPBody reqbody = reqenvelope.getBody();
String tmp = "";
Iterator iter = reqbody.getChildElements(reqenvelope.createName("word"));
while (iter.hasNext()) {
SOAPElement element = (SOAPElement) iter.next();
tmp = element.getValue();
}
//查詢字典
String chinese;
chinese = (String) dic.get(tmp);
if (chinese == null) {
chinese = "你要查的字不在字典裡";
}
//送出回傳訊息
SOAPMessage msg = fac.createMessage();
SOAPEnvelope env = msg.getSOAPPart().getEnvelope();
env.getBody().addChildElement(env.createName("meaning")).addTextNode(chinese);
return msg;
}
catch (Exception e) {
return null;
}
}
}
建立URL mapping
開啟WebContent/WEB-INF/web.xml,選擇servlet頁面,按"新增",選ReceivingServlet,然後在URL對映處右邊按
"新增"更名為"receiver"。

圖5
建立發送端
建立Servlet,命名為Test (圖6) 按下一步,選doPost、doGet (圖7)。

圖6

圖7
填入如下source code…
package tw.idv.idealist.jaxm;
import java.io.IOException;
import javax.servlet.*;
import javax.servlet.http.*;
import java.net.URL;
import java.util.Iterator;
import javax.xml.soap.*;
public class Test extends HttpServlet implements Servlet {
static final String SIMPLE_SAMPLE_URI = "http://localhost:8080/JAXM/receiver";
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
public void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
try {
URL endpoint = null;
endpoint = new URL(SIMPLE_SAMPLE_URI);
SOAPConnectionFactory scf = SOAPConnectionFactory.newInstance();
SOAPConnection connection = scf.createConnection();
MessageFactory mf = MessageFactory.newInstance();
SOAPMessage msg = mf.createMessage();
SOAPPart soapPart = msg.getSOAPPart();
SOAPEnvelope envelope = soapPart.getEnvelope();
//填入想查詢的英文字
SOAPBody body = envelope.getBody();
Name name = envelope.createName("word");
SOAPElement word = body.addChildElement(name);
word.addTextNode("cat");
System.out.println("送出的SOAP訊息如下");
msg.saveChanges();
msg.writeTo(System.out);
System.out.println("送出訊息至: " + endpoint);
System.out.println("收到的SOAP訊息如下");
SOAPMessage reply = connection.call(msg, endpoint);
reply.writeTo(System.out);
System.out.println("====================");
//取出請求之中欲查詢的英文字
SOAPEnvelope resenvelope = reply.getSOAPPart().getEnvelope();
SOAPBody resbody = resenvelope.getBody();
String tmp = "";
Iterator iter = resbody.getChildElements(resenvelope.createName("meaning"));
while (iter.hasNext()) {
SOAPElement element = (SOAPElement) iter.next();
tmp = element.getValue();
}
System.out.println("中文意義為 " + tmp);
connection.close();
}
catch(Throwable e) {
e.printStackTrace();
}
}
}
建立伺服器及伺服器配置
在J2EE階層頁面的"伺服器"上按滑鼠右鍵,建立"伺服器及伺服器配置",命名為Tomcat_Test (圖8) 按下一步,
選擇Tomcat和JDK目錄後按"完成"。

圖8

圖9
測試
啟動伺服器 (圖10),開啟瀏覽器,輸入http://localhost:8080/JAXM/Test按Enter,在主控台可以看到如圖11的訊息,
顯示查詢得到"貓"。

圖10

圖11
匯入tag
JAXM提供了一組tag,方便在JSP中使用JAXM如圖12建立一個資料夾,命名為tld,然後如圖13匯入jaxm.tld。

圖12

圖13
建立JSP發送端
如圖14建立名為Test.jsp的JSP檔,按下一步後新增標示庫,如圖15,字首命名為jaxm。然後打開web.xml,
選擇"參照"頁面,按"新增"如圖16,選擇jaxm.tld,URI填入http://java.sun.com/jaxm後按"完成"。

圖14

圖15

圖16
開啟Test.jsp檔後填入如下source code。
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<HTML>
<HEAD>
<%@ page import="javax.xml.soap.*,java.util.*" %>
<%@ taglib uri="http://java.sun.com/jaxm" prefix="jaxm" %>
<%@ page language="java" contentType="text/html; charset=BIG5" pageEncoding="BIG5" %>
<META http-equiv="Content-Type" content="text/html; charset=BIG5">
<META http-equiv="Content-Style-Type" content="text/css">
<LINK href="theme/Master.css" rel="stylesheet" type="text/css">
<TITLE>英漢查詢</TITLE>
</HEAD>
<jaxm:context/>
<jaxm:call endpoint="http://localhost:8080/JAXM/receiver" resId="sres" msgId="sreq">
<jaxm:soapBody>
<word><%= request.getParameter("word") %></word>
</jaxm:soapBody>
</jaxm:call>
<H1>Request dump</H1>
<pre><jaxm:dump msgId="sreq"/></pre>
<hr>
<H1>Response dump</H1>
<pre><jaxm:dump msgId="sres"/></pre>
<hr>
<%
SOAPEnvelope resenvelope = sres.getSOAPPart().getEnvelope();
SOAPBody resbody = resenvelope.getBody();
String tmp = "";
Iterator iter = resbody.getChildElements(resenvelope.createName("meaning"));
while (iter.hasNext()) {
SOAPElement element = (SOAPElement) iter.next();
tmp = element.getValue();
}
%>
這個字翻譯為:<%= tmp %>
</HTML>
測試
啟動伺服器,開啟瀏覽器,打入http://localhost:8080/JAXM/Test.jsp?word=bear後按Enter,得到如圖17的結果。

圖17