j2ee web service开发(三) SAAJ 带附件的soap消息

j2ee web service开发(三) SAAJ 带附件的soap消息
带附件的soap消息api,其内容很丰富,它是一个允许用soap消息而不是用jax-rpc来调用web service的API .它通过直接创建XML消息来完成web serivce的调用.SOAP API 简化了创建XML的工作. 取自j2ee文档的soap消息的结构图.
saaj-noAttach.gif 
完整的SAAJ客户端程序. 服务器端的程序在j2ee web service开发(一) 里可以找到.没有详细介绍saaj的一些类
的使用.好在它们都有很好的自解释性.
package array;

import javax.xml.soap.*;
import java.net.*;
import java.io.*;
import java.util.*;
import java.text.SimpleDateFormat;
public class SaajClient {
    public SaajClient() {
    }

    public static void main(String[] args) throws Exception {
        SaajClient client = new SaajClient();
        User[] user = new User[2];
        user[0] = new User("张三", "027-88888888", new Date());
        user[1] = new User("lisi", null, new Date());
        saajTest(user);

    }

    private static void saajTest(User[] user) throws MalformedURLException,
            IOException,
            UnsupportedOperationException, SOAPException {
        MessageFactory factory = MessageFactory.newInstance();//SAAJ的根工厂类
        SOAPMessage message = factory.createMessage();
        //SOAPMessage 对象需要一些元素,包括SOAPPart,SOAPEnvelope,SOAPHeader,SOAPBody对象
        //SAAJ通过返回一个新的已经包括这些元素的SOAPMessage对象来简化操作
        SOAPFactory s = SOAPFactory.newInstance();//通用工厂类,创建Name,SOAPElement对象

        Name countUser = s.createName("countUser", "mh", "http://array");
        //Name对象表示一个XML限定名称
        Name arrayOfUser_1 = s.createName("arrayOfUser_1");
        Name xsi = s.createName("xmlns:xsi");
        Name nullAttribute = s.createName("xsi:nil");

        //下面的代码创建soap对象
        SOAPBody body = message.getSOAPBody();
        SOAPBodyElement bodyChildElement = body.addBodyElement(countUser);
        SOAPElement arrayOfUser = bodyChildElement.addChildElement(
                arrayOfUser_1);
      //  arrayOfUser.addAttribute(xsi, "http://www.w3.org/2001/XMLSchema-instance");
        arrayOfUser.addNamespaceDeclaration("xsi","http://www.w3.org/2001/XMLSchema-instance");
        //定义arrayOfUser的 xmlns:xsi属性  该名称空间是XML模式实例命名空间,由XML模式规范定义,它定义了
        //可以在XML文档中使用的属于该命名空间的一些特性.
        for (int i = 0; i < user.length; i++) {
            //需要注意顺序,也就是和复杂类型的sequence元素的顺序对应
            Name valueName = s.createName("value");
            SOAPElement value = arrayOfUser.addChildElement(valueName);
            Name birthday = s.createName("birthDay");
            SOAPElement birthdayElement = value.addChildElement(birthday);

            if (user[i].getBirthDay() == null) {
                birthdayElement.addAttribute(nullAttribute, "1");
            } else {
                //日期类型必须进行格式化
                SimpleDateFormat format= new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
                birthdayElement.addTextNode(format.format(user[i].getBirthDay()));
            }
            Name name = s.createName("name");
            SOAPElement nameElement = value.addChildElement(name);
            if (user[i].getName() == null) {
                //传送空值
                nameElement.addAttribute(nullAttribute, "1");
            } else {
                nameElement.addTextNode(user[i].getName());
            }
            Name phone = s.createName("phone");
            SOAPElement phoneElement = value.addChildElement(phone);
            if (user[i].getPhone() == null) {
                phoneElement.addAttribute(nullAttribute, "1");
            } else {
                phoneElement.addTextNode(user[i].getPhone());
            }

        }

        //发送soap消息
        SOAPConnectionFactory f = SOAPConnectionFactory.newInstance();
        SOAPConnection conn = f.createConnection();
        URL url = new URL("http://localhost:8082/complexType-array/services/CountUser");
        SOAPMessage response = conn.call(message, url);

        SOAPBody soapBody = response.getSOAPBody();
        Iterator it = soapBody.getChildElements();
        while (it.hasNext()) {
            SOAPBodyElement bodyElement = (SOAPBodyElement) it.next();
            String returnValue = bodyElement.getValue();
            System.out.println(bodyElement.getElementName().getLocalName() +
                               "      " + returnValue);
        }


        response.writeTo(System.out);
    }
}

程序向服务器端传送的数据:

POST /complexType-array/services/CountUser HTTP/1.1
SOAPAction: ""
Content-Type: text/xml; charset=UTF-8
User-Agent: Java/1.5.0_03
Host: localhost:8082
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Connection: keep-alive
Content-Length: 448

<env:Envelope xmlns:env='http://schemas.xmlsoap.org/soap/envelope/'>
   <env:Header/>
   <env:Body>
      <mh:countUser xmlns:mh='http://array'>
         <arrayOfUser_1 xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'>
            <value>
               <birthDay>2006-11-08T22:36:13</birthDay>
               <name>张三</name>
               <phone>027-88888888</phone>
            </value>
            <value>
               <birthDay>2006-11-08T22:36:13</birthDay>
               <name>lisi</name>
               <phone xsi:nil='1'/>
            </value>
         </arrayOfUser_1>
      </mh:countUser>
   </env:Body></env:Envelope>
从传送的数据来看,就是一个符合soap规范的xml文档.既然是xml文档,也就是说可以用jdom api 来操作它
事实上就是这样,soap api 可以跟 jdom api混合使用.
如果你想赐教或者讨论,欢迎加入QQ群:30406099



凡是有该标志的文章,都是该blog博主Caoer(草儿)原创,凡是索引、收藏
、转载请注明来处和原文作者。非常感谢。

你可能感兴趣的:(j2ee web service开发(三) SAAJ 带附件的soap消息)