基于SAAJ的客户端
概述

正文
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>
<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
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的客户端的更多相关文章
- C#基于RabbitMQ实现客户端之间消息通讯实战演练
一.背景介绍和描述 MQ消息队列已经逐渐成为企业IT系统内部通信的核心手段.它具有低耦合.可靠投递.广播.流量控制.最终一致性等一系列功能,成为异步RPC的主要手段之一.何时需要消息队列?当你需要使用 ...
- 基于UDP的客户端和服务器端的代码设计
实验平台 linux 实验内容 编写UDP服务器和客户端程序,客户端发送消息,服务器接收消息,并打印客户端的IP地址和端口号. 实验原理 UDP是无需连接的通信,其主要实现过程如下: 同样,我们可以按 ...
- 基于Git项目管理客户端SourceTree的免注册安装及远程连接方法
作为程序员,不可避免的要在github上查询代码,而在企业项目中,为了使得项目好管理需要使用项目管理客户端,所以接下来详细讲解一下基于git的sourceTree在windows系统下的安装及与Git ...
- Redis基于Java的客户端SDK收集
如果要找这类的SDK,第一反应应该直奔官网,找一下看下有什么推荐.先找最权威的回答,找不到再尝试民间方案. 就Redis来说,官方已经提供了一个列表包括市面上绝大多数语言的SDK,可以参考以下网址看J ...
- Kafka 幂等生产者和事务生产者特性(讨论基于 kafka-python | confluent-kafka 客户端)
Kafka 提供了一个消息交付可靠性保障以及精确处理一次语义的实现.通常来说消息队列都提供多种消息语义保证 最多一次 (at most once): 消息可能会丢失,但绝不会被重复发送. 至少一次 ( ...
- 基于TCP的客户端、服务器端socket编程
一.实验目的 理解tcp传输客户端服务器端通信流程 二.实验平台 MAC OS 三.实验内容 编写TCP服务器套接字程序,程序运行时服务器等待客户的连接,一旦连接成功,则显示客户的IP地址.端口号,并 ...
- 使用CXF开发WebService程序的总结(四):基于bean的客户端和服务端代码的编写
1. 在原服务端项目 ws_server中添加两个bean 1.1 添加两个类 User 和 Clazz package com.lonely.pojo; public class User { ...
- 网络编程—【自己动手】用C语言写一个基于服务器和客户端(TCP)!
如果想要自己写一个服务器和客户端,我们需要掌握一定的网络编程技术,个人认为,网络编程中最关键的就是这个东西--socket(套接字). socket(套接字):简单来讲,socket就是用于描述IP地 ...
- 基于socket的客户端和服务端聊天简单使用 附Demo
功能使用 服务端 分离一个不停接受客户端请求的线程 接受不客户端请求的线程中,再分离就收消息的线程 几大对象分别是 IPEndPoint IP终结点 服务端Socket,绑定终结点Bind,启动监听L ...
随机推荐
- linux包安装,解压,压缩,包管理,环境变量
linux 包安装,解压,压缩,包管理 centoscentos上有系统包管理器yum yum的配置一般有两种方式,一种是直接配置/etc目录下的yum.conf文件,另外一种是在/etc/yum.r ...
- redis linux下的开机启动
redis linux下的环境搭建 http://www.cnblogs.com/zsg88/p/8321644.html 安装完redis-4.0.1后设置linux开机自启动. 1.在re ...
- Linux while 和 read 的用法
Reference: [ linux man doc ] [ CSDN roler_ ] [ Reads from the file descriptor] read 命令说明 SYNTAX : re ...
- 牛客网刷题(纯java题型 31~60题)
牛客网刷题(纯java题型 31~60题) 重写Override应该满足"三同一大一小"三同:方法名相同,参数列表相同,返回值相同或者子类的返回值是父类的子类(这一点是经过验证的) ...
- HDU 1465 不容易系列之一 (错排公式+容斥)
题目链接 Problem Description 大家常常感慨,要做好一件事情真的不容易,确实,失败比成功容易多了! 做好"一件"事情尚且不易,若想永远成功而总从不失败,那更是难上 ...
- HDU 1231 最大连续子序列 (dp)
题目链接 Problem Description 给定K个整数的序列{ N1, N2, ..., NK },其任意连续子序列可表示为{ Ni, Ni+1, ..., Nj },其中 1 <= ...
- Bagging和Boosting 概念及区别(转)
Bagging和Boosting都是将已有的分类或回归算法通过一定方式组合起来,形成一个性能更加强大的分类器,更准确的说这是一种分类算法的组装方法.即将弱分类器组装成强分类器的方法. 首先介绍Boot ...
- 使用EL表达式需要注意的
1.表达式与Java无关,表达式都是以${开始,以}结束. 2.EL访问java变量不能直接访问,因为得不到数据,要访问数据,需要将其放到作用域中.而使用<%=java变量%>可以访问ja ...
- bootstrap-select属性
# 参考:https://blog.csdn.net/zxl_langya/article/details/79247307 # bootstrap-select属性: <select mult ...
- Linux下基本栈溢出攻击【转】
转自:http://blog.csdn.net/wangxiaolong_china/article/details/6844415 版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[ ...