基于SAAJ的客户端
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基于SAAJ的客户端相关的知识,希望对你有一定的参考价值。
概述
SAAJ - SOAP with Attachments API for JAVA
结构图如下:
正文
1. 如何获取soap请求的关键参数
关键的参数有四个:
- xmlns - xml命名空间
如果你对命名空间没有概念,请参考:w3school - XML命名空间。 - 服务的地址
- service的name
- port的name
获取:
- 在wsdl文档的root元素的targetNamespace可以获取到xmlns:
- 在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>
关于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); } }
以上是关于基于SAAJ的客户端的主要内容,如果未能解决你的问题,请参考以下文章
SAAJ0537:无效的内容类型。可能是错误消息而不是 SOAP 消息
java.lang.LinkageError:com / sun / xml / messaging / saaj / soap / SOAPDocumentImpl