本文的預定作者應該對SOAP1.1的基本規范有所了解,并熟悉了j2ee的基本開發,如果不熟悉的話,可以看一下我的Blog:
使用SOAP開發java web服務--Axis開發方案 ,詳細標準可以查看w3c的官方網站,連接如下:
http://www.w3.org/TR/2000/NOTE-SOAP-20000508/ 。本文主要是探討SAAJ(SOAP with Attachment API for Java),JAXM(Java API for XML Messaging),了解SOAP在j2ee開發中的作用與其接口。JAXM和SAAJ均支持針對B2B和Web服務應用程序、基于XML的消息交換,支持諸多行業標準,包括SOAP和ebXML。
SAAJ是JWSDP的組成部分之一,JWSDP目前已經更新到了1.5版,SAAJ可以從SUN的網站單獨下載:
http://java.sun.com/xml/downloads/saaj.html,JAXM是用于XML消息交換的標準,不在JWSDP1.5的發行包內,可以另外下載:
http://java.sun.com/xml/jaxm/downloads/index.html ,由于SAAJ是基于JavaMail
TM API (1.2) 、 JavaBeans
TM Activation Framework (JAF) (1.1.3)和JAXP(1.2.6) 的,所以也要把他們下載下來,SUN的官方網站都有提供的,好了,現在我們得到了以下包(按我下載的名稱):activation.jar(JAF),jaxm-api.jar(JAXM),mail.jar(JavaMail),saaj-api.jar(SAAJ),saaj-impl.jar(SAAJ),我的JAXP已經包括在jdk1.5中了。另外還要有個支持Servlet的容器。
好了,準備工作完畢了,下面開始我們的學習:
一、 SAAJ可用于將XML文檔作為SOAP消息發送和接收,而無需JAXM提供商的基礎程序結構,也無需處理基于SOAP的HTTP請求/響應。SAAJ最初是JAXM1.0API軟件包的組成部分,而從JAXM1.1開始,該軟件包更名為SAAJ1.1API。
以下我們先了解一個簡單的SOAP1.1消息:
POST /StockQuote HTTP/1.1
Host:
www.stockquoteserver.comContent-Type: text/xml; charset="utf-8"
Content-Length: nnnn
SOAPAction: "Some-URI"
<SOAP-ENV:Envelope
xmlns:SOAP-ENV=" SOAP-ENV:encodingStyle="> <------------這是信封標志
<SOAP-ENV:Header> <------------這是消息頭標志
<t:Transaction
xmlns:t="some-URI"
SOAP-ENV:mustUnderstand="1">
5
</t:Transaction>
</SOAP-ENV:Header>
<SOAP-ENV:Body> <------------這是主體標志
<m:GetLastTradePrice xmlns:m="Some-URI">
<symbol>DEF</symbol>
</m:GetLastTradePrice>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
SAAJ API為我們提供了一個高層次SOAP消息封裝接口,如:信封接口:javax.xml.soap.SOAPEnvelope,并提供了操作getHeader(),該方法返回一個消息頭:javax.xml.soap.SOAPHeader。所以,通過調用SAAJ的接口函數,我們就可以對SOAP消息進行操作。
二、現在我們來討論一下在不使用消息交換提供程序的JAXM時,應用程序客戶端通過SOAP直接與其遠程伙伴發送和接收消息操作(定義了點到點的交互作用和同步通信模型,其中發送方和接收方以請求和響應的形式交換消息。發送方發送消息并等待鎖定目標位置的響應)。
發送方步驟:
1)創建SOAP連接;
2)創建消息工廠;
3)創建消息;
4)填充消息;
5)添加消息;
6)添加SOAP附件;
7)發送消息并接收響應;
8)關閉提供程序連接;
一下是我寫的一個例子:
/**
*Sender.java
*Copyright 2005-2-10
*/
import javax.xml.soap.SOAPConnectionFactory;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPConnection;
import javax.xml.soap.MessageFactory;
import javax.xml.soap.SOAPMessage;
import javax.xml.soap.SOAPPart;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPHeader;
import javax.xml.soap.SOAPBody;
import javax.xml.soap.SOAPBodyElement;
import javax.xml.soap.SOAPHeaderElement;
import javax.xml.soap.Name;
import javax.xml.soap.SOAPElement;
import java.net.URL;
import javax.xml.messaging.URLEndpoint;
import javax.activation.DataHandler;
import java.io.IOException;
public class Sender{
public SOAPMessage getMessage() throws SOAPException,Exception{
//消息工廠
MessageFactory msgFactory=MessageFactory.newInstance();
SOAPMessage message=msgFactory.createMessage();
//獲得一個SOAPPart對象
SOAPPart soapPart=message.getSOAPPart();
//獲得信封
SOAPEnvelope soapEnvelope=soapPart.getEnvelope();
//獲得消息頭
SOAPHeader soapHeader=soapEnvelope.getHeader();
//獲得SOAP主體
SOAPBody soapBody=soapEnvelope.getBody();
//添加頭元素
SOAPHeaderElement headerElement=soapHeader.addHeaderElement(
soapEnvelope.createName("StudentNo","stu","
//添加消息主體
Name bodyName=soapEnvelope.createName("getStudentInfo","stu","
SOAPBodyElement bodyElement=soapBody.addBodyElement(bodyName);
Name eleName=soapEnvelope.createName("StudentName");
SOAPElement se=bodyElement.addChildElement(eleName);
se.addTextNode("Wang wenyin");
//添加SOAP附件
URL url=new URL("
DataHandler dataHandler=new DataHandler(url);//use the JAF
message.addAttachmentPart(message.createAttachmentPart(dataHandler));
//更新SOAP消息
message.saveChanges();
return message;
}
public void send(SOAPMessage message) throws SOAPException,IOException{
//創建SOAP連接
SOAPConnectionFactory scf=SOAPConnectionFactory.newInstance();
SOAPConnection sc=scf.createConnection();
//發送SOAP消息到目的地,并返回一個消息
URLEndpoint urlEndpoint=new URLEndpoint("http://localhost/saaj/StudentInfoServlet");
SOAPMessage response=sc.call(message,urlEndpoint);
if(response!=null){
//輸出SOAP消息到控制臺
System.out.println("Receive SOAP message from localhost:");
response.writeTo(System.out);
}else{
System.err.println("No response received from partner!");
}
sc.close();
}
public static void main(String[] args) throws SOAPException,Exception{
Sender sender=new Sender();
SOAPMessage message=sender.getMessage();
sender.send(message);
}
}
然后編譯,注意classpath變量的設置要把以上的那些包加進去(可以設置一個腳本來完成,熟悉Ant的話,那就更加簡單了)。
編譯成功后,我們等到了一個Sender.class文件,這是發送方文件。當你運行java Sender的時候,就會把SOAP消息發向我們的同伴http://localhost/saaj/StudentInfoServlet ,并等待返回。以下我們繼續編寫一個Servlet好接收剛才發送的消息。
三、接收方Servlet應用程序saaj.war。
/**
*JAXMReceiveServlet.java
*Copyright 2005-2-10
*/
import javax.xml.messaging.JAXMServlet;
import javax.xml.messaging.ReqRespListener;
import javax.xml.soap.MessageFactory;
import javax.servlet.ServletException;
import javax.xml.soap.SOAPMessage;
import javax.xml.soap.SOAPEnvelope;
import javax.servlet.ServletConfig;
import java.io.FileOutputStream;
import java.io.File;
public class JAXMReceiveServlet extends JAXMServlet implements ReqRespListener{
static MessageFactory mf=null;
//創建一個消息工廠
static{
try{
mf=MessageFactory.newInstance();
}catch(Exception e){
e.printStackTrace();
}
};
public void init(ServletConfig sc) throws ServletException{
super.init(sc);
}
//處理傳過來的SOAP消息,并返回一個SOAP消息
public SOAPMessage onMessage(SOAPMessage msg){
SOAPMessage resp=null;
try{
System.out.println("傳入的消息:");
msg.writeTo(new FileOutputStream(new File("../webapps/soapmessage.xml")));
//創建一個返回消息
resp=mf.createMessage();
SOAPEnvelope se=resp.getSOAPPart().getEnvelope();
se.getBody().addChildElement(
se.createName("ResponseMessage")).addTextNode("Received Message,Thanks");
return resp;
}catch(Exception e){
e.printStackTrace();
}
return resp;
}
}
然后把相關的classpath添加進去,編譯(不會的話,自己去查有關Servlet的編程,篇幅有限)
web.xml部署文件:
<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app xmlns=" xmlns:xsi=" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee version="2.4">
<servlet>
<servlet-name>StudentInfoServlet</servlet-name>
<servlet-class>JAXMReceiveServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>StudentInfoServlet</servlet-name>
<url-pattern>/StudentInfoServlet</url-pattern>
</servlet-mapping>
</web-app>
至此 我們的基本工作完成了,部署好程序saaj,當你在瀏覽器訪問 http://localhost/saaj/StudentInfoServlet ,將會返回一個錯誤信息,因為這里使用的是SOAP協議。
四、測試
如果部署成功的話,那開始我們的測試。
我們繼續第二步的步驟,java Sender,接著我們就等待,我們在發送方創建了一個SOAP消息(有個jpg圖片的附件),并發送到Servlet容器中(我的是tomcat),在服務器方接送到消息,并在webapps文件夾下創建soapmessage.xml文件,把接收到的SOAP信息寫進去,并返回一個soap消息。
等過了一段時間后,sender方會返回一個soap格式的xml文件,在控制臺上輸出。
好了,今天的關于SOAP的深入探索就到這里了。