IT源码网

基于SAAJ的客户端讲解

lxf 2021年06月07日 程序员 114 0

概述


SAAJ - SOAP with Attachments API for JAVA
结构图如下:

正文


1. 如何获取soap请求的关键参数

关键的参数有四个:
  1. xmlns - xml命名空间
    如果你对命名空间没有概念,请参考:w3school - XML命名空间
  2. 服务的地址
  3. service的name
  4. port的name
获取:
  1. 在wsdl文档的root元素的targetNamespace可以获取到xmlns:
  2. 在service元素可以获取其他三个参数

    上图黄色高亮标注了三个地方,分别可以获得service的name,port的name,服务的地址。
    值得一说的是,这里的service的name和wsdl文档root元素的name是相同的,但这只是巧合;这里的才“真的是”,那里的只是“长得像”。

2. 参数声明

/** 服务的地址 */ 
private static final String ADDRESS = "http://localhost:6666/service/interpret"; 
/** 目标命名空间 */ 
private static final String TARGET_NAME_SPACE = "http://service.chapter1.jws.sand.ljl.cn/"; 
/** service的名称 */ 
private static final String SERVICE_NAME = "InterpretServiceImplService"; 
/** port的名称 */ 
private static final String PORT_NAME = "InterpretServiceImplPort";

3. 创建消息

/** 
 * 创建并填充SOAP message. 
 * @return 
 * @throws SOAPException 
 */ 
private SOAPMessage createMessage() throws SOAPException { 
  // 1. 创建message 
  SOAPMessage message = MessageFactory.newInstance().createMessage(); 
  
  // 2. 获取Envelope 
  SOAPEnvelope envelope = message.getSOAPPart().getEnvelope(); 
  
  // 3. 获取body 
  SOAPBody body = envelope.getBody(); 
  
  // 4. 构造interpret元素 
  QName qname = new QName(TARGET_NAME_SPACE, "interpret", "ns"); 
  
  // 5. 向body中添加元素 
  SOAPBodyElement bodyElement = body.addBodyElement(qname); 
  
  // 6. 添加子元素 
  bodyElement.addChildElement("num").setValue("112358"); 
  
  return message; 
}

上述代码的创建结果:

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"> 
    <SOAP-ENV:Header/> 
    <SOAP-ENV:Body> 
        <ns:interpret xmlns:ns="http://service.chapter1.jws.sand.ljl.cn/"> 
            <num>112358</num> 
        </ns:interpret> 
    </SOAP-ENV:Body> 
</SOAP-ENV:Envelope>

关于QName

QName qname = new QName("http://service.chapter1.jws.sand.ljl.cn/", "interpret", "ns");

上述代码的三个参数,分别表示命名空间、本地名称、前缀。相当于创建了下述的xml元素:

<ns:interpret xmlns:ns="http://service.chapter1.jws.sand.ljl.cn/" />

关于打印SOAPMessage

使用javax.xml.soap.SOAPMessage.writeTo(OutputStream out)可以把消息打印到指定的输出流。

4. 发送消息

/** 
 * 发送SOAP message,并返回响应的SOAP message. 
 * @param request 
 * @return 
 * @throws MalformedURLException 
 */ 
private SOAPMessage send(SOAPMessage request) throws MalformedURLException { 
  // 1. 根据address、serviceName创建service 
  URL url = new URL(ADDRESS); 
  QName serviceName = new QName(TARGET_NAME_SPACE, SERVICE_NAME); 
  Service service = Service.create(url, serviceName); 
  
  // 2. 使用service,根据portName创建dispatch 
  QName portName = new QName(TARGET_NAME_SPACE, PORT_NAME); 
  Dispatch<SOAPMessage> dispatch = service.createDispatch(portName, 
       SOAPMessage.class, Service.Mode.MESSAGE); 
  
  // 3. 发送请求 
  SOAPMessage response = dispatch.invoke(request); 
  
  return response; 
}

上述代码获得的响应的结果:

<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"> 
  <S:Header/> 
  <S:Body> 
     <ns2:interpretResponse xmlns:ns2="http://service.chapter1.jws.sand.ljl.cn/"> 
       <chnum>一一二三五八</chnum> 
     </ns2:interpretResponse> 
  </S:Body> 
</S:Envelope>

5. 解析结果

Document doc = response.getSOAPPart().getEnvelope() 
       .getBody().extractContentAsDocument(); 
String result = doc.getElementsByTagName("chnum").item(0) 
       .getTextContent();

完整的demo


package cn.ljl.sand.jws.chapter2.client; 
import java.io.IOException; 
import java.net.MalformedURLException; 
import java.net.URL; 
import javax.xml.namespace.QName; 
import javax.xml.soap.MessageFactory; 
import javax.xml.soap.SOAPBody; 
import javax.xml.soap.SOAPBodyElement; 
import javax.xml.soap.SOAPEnvelope; 
import javax.xml.soap.SOAPException; 
import javax.xml.soap.SOAPMessage; 
import javax.xml.ws.Dispatch; 
import javax.xml.ws.Service; 
import org.junit.Assert; 
import org.junit.Test; 
import org.w3c.dom.Document; 
import cn.ljl.sand.jws.chapter1.service.InterpretService; 
/** 
 * 基于SAAJ的客户端.<br> 
 * 所访问的服务参考{@link InterpretService}. 
 *  
 * @author lijinlong 
 *  
 */ 
public class SAAJClient { 
    /** 服务的地址 */ 
    private static final String ADDRESS = "http://localhost:6666/service/interpret"; 
    /** 目标命名空间 */ 
    private static final String TARGET_NAME_SPACE = "http://service.chapter1.jws.sand.ljl.cn/"; 
    /** service的名称 */ 
    private static final String SERVICE_NAME = "InterpretServiceImplService"; 
    /** port的名称 */ 
    private static final String PORT_NAME = "InterpretServiceImplPort"; 
     
    /** 
     * 创建并填充SOAP message. 
     * @return 
     * @throws SOAPException 
     */ 
    private SOAPMessage createMessage() throws SOAPException { 
        SOAPMessage message = MessageFactory.newInstance().createMessage(); 
        SOAPEnvelope envelope = message.getSOAPPart().getEnvelope(); 
        SOAPBody body = envelope.getBody(); 
         
        QName qname = new QName(TARGET_NAME_SPACE, "interpret", "ns"); 
        SOAPBodyElement bodyElement = body.addBodyElement(qname); 
        bodyElement.addChildElement("num").setValue("112358"); 
         
        return message; 
    } 
     
    /** 
     * 发送SOAP message,并返回响应的SOAP message. 
     * @param request 
     * @return 
     * @throws MalformedURLException 
     */ 
    private SOAPMessage send(SOAPMessage request) throws MalformedURLException { 
        URL url = new URL(ADDRESS); 
        QName serviceName = new QName(TARGET_NAME_SPACE, SERVICE_NAME); 
        Service service = Service.create(url, serviceName); 
        QName portName = new QName(TARGET_NAME_SPACE, PORT_NAME); 
        Dispatch<SOAPMessage> dispatch = service.createDispatch(portName, 
                SOAPMessage.class, Service.Mode.MESSAGE); 
        SOAPMessage response = dispatch.invoke(request); 
        return response; 
    } 
     
    @Test 
    public void test() throws SOAPException, IOException { 
        SOAPMessage request = createMessage(); 
        request.writeTo(System.out); 
         
        SOAPMessage response = send(request); 
        response.writeTo(System.out); 
         
        Document doc = response.getSOAPPart().getEnvelope() 
               .getBody().extractContentAsDocument(); 
        String result = doc.getElementsByTagName("chnum").item(0) 
               .getTextContent(); 
        Assert.assertEquals("一一二三五八", result); 
    } 
}






发布评论

分享到:

IT源码网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!

SOAP消息的结构讲解
你是第一个吃螃蟹的人
发表评论

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。