深入探索SOAP1.1--使用SAAJ1.2.1

本文的预定作者应该对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是基于JavaMailTM API (1.2) 、 JavaBeansTM 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.com
Content-Type: text/xml; charset="utf-8"
Content-Length: nnnn
SOAPAction: "Some-URI"

<SOAP-ENV:Envelope
  xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
  SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>              <------------这是信封标志
   <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)关闭提供程序连接;
       一下是我写的一个例子:

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.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","http://www.cun.edu.cn/jws"));
		headerElement.addTextNode("JWS0229043");

		//添加消息主体
		Name bodyName = soapEnvelope.createName("getStudentInfo", "stu","http://www.cun.edu.cn/jws");

		SOAPBodyElement bodyElement = soapBody.addBodyElement(bodyName);

		Name eleName = soapEnvelope.createName("StudentName");
		SOAPElement se = bodyElement.addChildElement(eleName);
		se.addTextNode("Wang wenyin");

		//添加SOAP附件
		URL url = new URL("http://img20.photo.163.com/gdanthrowwy/5123911/80707051.jpg");
		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");
		URL urlEndpoint = new URL("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();
		System.out.println(message.toString());
		sender.send(message);
	}
}

  然后编译,注意classpath变量的设置要把以上的那些包加进去(可以设置一个脚本来完成,熟悉Ant的话,那就更加简单了)。
     编译成功后,我们等到了一个Sender.class文件,这是发送方文件。当你运行java Sender的时候,就会把SOAP消息发向我们的同伴http://localhost/saaj/StudentInfoServlet ,并等待返回。以下我们继续编写一个Servlet好接收刚才发送的消息。
三、接收方Servlet应用程序saaj.war。

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="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
    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文件,在控制台上输出。

参考文献:http://blog.csdn.net/jwsh1984/article/details/285574

时间: 2024-10-11 18:07:40

深入探索SOAP1.1--使用SAAJ1.2.1的相关文章

GLSProv WebUI Framework 探索阶段成果所得(1)

作为我的处子随笔,我就凭着我所想到的记录一下这段时间探索我所做的这个Feature的历程以及所学,所感. 先说一下背景,Provisiong一直是我们COM组项目里比较重要的配置环节,诞生10来年,一直是Java Swing作为主要的GUI界面,配合后台的OMCP Server 与网元以及数据库打交道.自从COM web 化以来,Swing Gui 从纯Java 演变为了WEB Swing, 但是本质上并没有什么变化, 较差的客户体验一直让老美不爽,所以经"董事会"们开会研究,先拿规模

使用Visual Studio快速开发STM32F4-Discovery探索板入门

本本将主要介绍如何使用Visual Studio创建一个基于STM32F4-Discovery探索板的简单工程. 本文使用以下硬件和软件: ●      Microsoft Visual Studio ●      VisualGDB ●      STM32F4-Discovery探索板 我们将创建一个简单的“LED闪烁”的工程,然后进行构建,并使用调试器进行单步调试. 1.    启动Visual Studio.选择File-> New-> Project. 2.    选择VisualG

数据探索

一.查看数据 首先,我们查看iris数据集的大小和结构,其维度和名称分别使用函数dim()和names()获取. 函数str()和attributes()返回数据的结构和属性 二.单变量分析 > head(iris) Sepal.Length Sepal.Width Petal.Length Petal.Width Species1 5.1 3.5 1.4 0.2 setosa2 4.9 3.0 1.4 0.2 setosa3 4.7 3.2 1.3 0.2 setosa4 4.6 3.1 1.

地统计分析笔记——探索数据

来自:http://blog.csdn.net/kikitamoon/article/details/49925147 在执行地统计分析之前,浏览.熟悉.检查自己的数据是至关重要的.绘制和检查数据是地统计分析过程中的必要阶段,我们可以从这些工作中获得一些先验知识,指导后续的工作. Stage 1 绘制数据 通过ArcMap的图层渲染方案绘制数据,我们可以获得对数据的第一印象. 例如,使用单一符号渲染了解采样点的疏密分布,通过分类渲染了解采样点高值低值的分布,等等. Stage 2 检查数据 绘制

C++随笔:.NET CoreCLR之GC探索(2)

首先谢谢 @dudu 和 @张善友 这2位大神能订阅我,本来在写这个系列以前,我一直对写一些核心而且底层的知识持怀疑态度,我为什么持怀疑态度呢?因为一般写高层语言的人99%都不会碰底层,其实说句实话,我以前也不看这些东西,只是因为自己觉得对C++感兴趣,索性乱写点东西,如果有写得不好的地方,还请上面2位大神指出. 其实我现在虽然写的是C++,但是我打算在后面把C++和.NET的一些基础类库融合起来,我发现写CLR的文章特别少,不知道什么原因.反正,废话不多,开始今天的写作吧,今天依然是把重点集中

探索Oracle之数据库升级二 11.2.0.3升级到11.2.0.4完整步骤

探索Oracle之数据库升级二  11.2.0.3升级到11.2.0.4完整步骤 说明:         这篇文章主要是记录下单实例环境下Oracle 11.2.0.1升级到11.2.0.3的过程,当然RAC的升级是会有所不同.但是他们每个版本之间升级步骤都是差不多的,先升级Database Software,再升级Oracle Instance. Oracle 11.2.0.4的Patchset No:19852360下载需要有Oracle Support才可以.  Patchset包含有7个

[ 测试思维 ] 探索式软件测试

非常不错的关于探索式软件测试的学习资料 1.探索式测试简析 作者:微软 史亮 http://pan.baidu.com/s/1c2D4tAo 2.探索式测试白皮书 作者:淘宝 季哥 http://pan.baidu.com/s/1qYFNG3y

探索 ConcurrentHashMap 高并发性的实现机制

简介 ConcurrentHashMap 是 util.concurrent 包的重要成员.本文将结合 Java 内存模型,分析 JDK 源代码,探索 ConcurrentHashMap 高并发的具体实现机制. 由于 ConcurrentHashMap 的源代码实现依赖于 Java 内存模型,所以阅读本文需要读者了解 Java 内存模型.同时,ConcurrentHashMap 的源代码会涉及到散列算法和链表数据结构,所以,读者需要对散列算法和基于链表的数据结构有所了解. Java 内存模型 由

JVM中class文件探索与解析(一)

一直想成为一名优秀的架构师的我,转眼已经工作快两年了,对于java内核了解甚少,闲来时间,看看JVM,吧自己的一些研究写下来供大家参考,有不对的地方请指正. 废话不多说,一起来看看JVM中类文件是如何加载和运行的. (1)首先,编写简单代码,对其编译生成的class文件进行研究,其java代码如下: 1 public class test { 2 private static int count = 0; 3 public static void recursion(){ 4 count++;