webservice系统学习笔记5-手动构建/发送/解析SOAP消息
手动拼接SOAP消息调用webservice
SOAP消息的组成:

1、创建需要发送的SOAP消息的XML(add方法为例子)
/**
* 创建访问add方法的SOAP消息的xml
*/
@Test
public void test1(){
try {
//1、创建消息工厂
MessageFactory factory = MessageFactory.newInstance();
//2、根据消息工厂创建SoapMessage
SOAPMessage message = factory.createMessage();
//3、创建SOAPPart
SOAPPart part = message.getSOAPPart();
//4、获取SOAPENvelope
SOAPEnvelope envelope = part.getEnvelope();
//5、可以通过SoapEnvelope有效的获取相应的Body和Header等信息
SOAPBody body = envelope.getBody();
//6、根据Qname创建相应的节点(QName就是一个带有命名空间的)
QName qname = new QName("http://ws01.yzl.com",
"add","ns");//<ns:add xmlns:ns=http://ws01.yzl.com>这里指定ns是前缀,必须指定,随便定义即可,不定义这消息将无效
//如果使用以下方式进行设置,会见<>转换为<和>
//body.addBodyElement(qname).setValue("<a>1</a><b>2</b>");
SOAPBodyElement ele = body.addBodyElement(qname);
ele.addChildElement("a").setValue("22");
ele.addChildElement("b").setValue("33");
//打印消息信息
message.writeTo(System.out);
} catch (Exception e) {
e.printStackTrace();
}
}
结果为下:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header/>
<SOAP-ENV:Body><ns:add xmlns:ns="http://ws01.yzl.com"><a>22</a><b>33</b></ns:add>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
2、提交创建的SOAP消息的xml到服务器端与其进行通信
2.1、使用SOAPMessage和Service.Mode.MESSAGE的方式发送消息
/**
* 发送add方法的SOAP的消息并接受解析返回的soap消息(使用Service.Mode.MESSAGE模式进行发送数据)
<service name="MyServiceImplService">
<port name="MyServiceImplPort" binding="tns:MyServiceImplPortBinding">
<soap:address location="http://localhost:8888/ws01" />
</port>
</service>
*
*/
@Test
public void test2(){
try {
String namespace = "http://ws01.yzl.com/";
String wsdlUrl = "http://localhost:8888/ws01?wsdl"; //1、创建服务(Service)
URL url = new URL(wsdlUrl);
QName qname = new QName(namespace,"MyServiceImplService");
Service service = Service.create(url, qname); //2、创建Dispatch
//public interface Dispatch<T>extends BindingProviderDispatch 接口提供对动态调用服务端点操作的支持。javax.xml.ws.Service 接口作为创建 Dispatch 实例的工厂。
Dispatch<SOAPMessage> dispatch = service.createDispatch(new QName(namespace,"MyServiceImplPort"), SOAPMessage.class, Service.Mode.MESSAGE); //3、创建SOAPMessage
MessageFactory factory = MessageFactory.newInstance();
SOAPMessage message = factory.createMessage();
SOAPPart part = message.getSOAPPart();
SOAPEnvelope envelope = part.getEnvelope();
SOAPBody body = envelope.getBody();
QName portQname = new QName("http://ws01.yzl.com/",
"add","ns");
SOAPBodyElement ele = body.addBodyElement(portQname);
ele.addChildElement("a").setValue("22");
ele.addChildElement("b").setValue("33"); //4、通过Dispatch传递消息,并返回响应消息
SOAPMessage returnMessage = dispatch.invoke(message);
returnMessage.writeTo(System.out);//打印返回消息
System.out.println(); //5、解析返回的SOAP消息的XML
Document doc = returnMessage.getSOAPBody().extractContentAsDocument();
//Document doc = returnMessage.getSOAPPart().getEnvelope().getBody().extractContentAsDocument();
String result = doc.getElementsByTagName("addResult").item(0).getTextContent();
System.out.println("result is :" + result); } catch (Exception e) {
e.printStackTrace();
}
}
结果:
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Header/>
<S:Body>
<ns2:addResponse xmlns:ns2="http://ws01.yzl.com/"><addResult>55</addResult></ns2:addResponse>
</S:Body>
</S:Envelope>
result is :55
2.2、使用Source和Service.Mode.PAYLOAD的方式来发送消息
接口IMyService.java中添加方法:
/**
*这里将WebResult和WebParam定义为user是为了使用jaxb进行类的编排和反编排时方便
*/
@WebResult(name="user")
public List<User> getChildListByUser(@WebParam(name="user")User user);
@Override
public List<User> getChildListByUser(User user) {
List<User> result = new ArrayList<User>();
result.add(new User("张三", "11111"));
result.add(new User("李四", "22222"));
return result;
}
这时wsdl中的定义如下:

调用代码:
/**
* 使用Source和Service.Mode.PAYLOAD的方式来发送消息
* 使用JAXB来对User对象进行编排和反编排
* 使用xpath解析xml
* @throws Exception
*/
@Test
public void test3() throws Exception{
String namespace = "http://ws01.yzl.com/";
String wsdlUrl = "http://localhost:8888/ws01?wsdl"; //1、创建服务(Service)
URL url = new URL(wsdlUrl);
QName qname = new QName(namespace,"MyServiceImplService");
Service service = Service.create(url, qname); //2、创建Dispatch(通过源数据的方式传递)
Dispatch<Source> dispatch = service.createDispatch(new QName(namespace,"MyServiceImplPort"),Source.class, Service.Mode.PAYLOAD); //3、根据用户对象创建相应的xml(user对象的属性可以通过wsdl文件构建出来)
User user = new User("管理员","123456");
JAXBContext jaxb = JAXBContext.newInstance(User.class);
Marshaller ms = jaxb.createMarshaller();
ms.setProperty(Marshaller.JAXB_FRAGMENT, true);//去掉xml声明
StringWriter writer = new StringWriter();
ms.marshal(user, writer);
//System.out.println(writer.toString());//<user><password>123456</password><username>管理员</username></user> //4、封装相应的part addUser
String payload = "<nn:getChildListByUser xmlns:nn=\""+namespace+"\">"+writer.toString()+"</nn:getChildListByUser>";
System.out.println(payload);
StreamSource rs = new StreamSource(new StringReader(payload)); //5、通过dispatch传递payload
Source response = (Source)dispatch.invoke(rs); //6、将Source转化为DOM进行操作,使用Transform对象转换
Transformer tran = TransformerFactory.newInstance().newTransformer();
DOMResult result = new DOMResult();
tran.transform(response, result); //7、处理相应信息(通过xpath处理)
XPath xpath = XPathFactory.newInstance().newXPath();
NodeList nl = (NodeList)xpath.evaluate("//user", result.getNode(),XPathConstants.NODESET);
for(int i=0; i<nl.getLength(); i++){
User ru = (User)jaxb.createUnmarshaller().unmarshal(nl.item(i));
System.out.println(ru.getUsername());
}
}
结果如下:
<nn:getChildListByUser xmlns:nn="http://ws01.yzl.com/"><user><password>123456</password><username>管理员</username></user></nn:getChildListByUser>
张三
李四
webservice系统学习笔记5-手动构建/发送/解析SOAP消息的更多相关文章
- webservice系统学习笔记7-使用handler实现过滤器/拦截器效果
handler可以作用于客户端,也可以作用了服务端 handler分为:1.LogicalHandler:只能获取到soap消息的body. 2.SOAPHandler:可以获取SOAPMessage ...
- webservice系统学习笔记4-使用工具查看SOAP消息
使用myeclipse的WTP java ee视图里的[web services Explorer]来测试查看webservice传输的SOAP消息 1. 2. 测试getUserByUsername ...
- webservice系统学习笔记10-使用jax-ws创建基于tomcat类型的容器的ws服务
1.在web-info目录下新建目录wsdl 2.在1步的目录下 新建文件user.wsdl <?xml version="1.0" encoding="UTF-8 ...
- webservice系统学习笔记9-使用契约优先的方式的一个服务端demo(隐式传Header信息)
服务器端: 1.编写wsdl文件 <?xml version="1.0" encoding="UTF-8" standalone="no&quo ...
- webservice系统学习笔记2-使用jdk的命令生成本地代码
使用jdk自带的命令wsimport生成远程服务的本地代码 C:\Documents and Settings\Administrator>wsimport -d E:\mhWorkspace\ ...
- webservice系统学习笔记1-使用注解创建ws服务
简单入门之helloword,具体详细的在后面的章节详细介绍. 使用JDK自带的jax-ws创建并发布一个简单的webservice 在本地创建服务,然后本机访问 1.创建服务提供接口 IMyServ ...
- webservice系统学习笔记8-简单的权限校验
服务端handler.java package com.ws01; import java.util.Set; import javax.xml.namespace.QName; import jav ...
- webservice系统学习笔记7-异常处理
接口类:IMyService.java @WebResult(name="testExceptionResult") public void testException() thr ...
- webservice系统学习笔记6-使用soap的header传递消息
1.显示的使用soap的header传递消息(不推荐使用,会破坏正常的代码结构,推荐使用handler处理) @WebResult(name="deleteResult") pub ...
随机推荐
- ASP.NET浏览器跨域
转载:http://www.cnblogs.com/alvinwei1024/p/4626054.html 什么是跨域? 访问同源的资源是被浏览器允许的,但是如果访问不同源的资源,浏览器默认是不允许的 ...
- python测试开发django-5.模板templates
前言 html是一个静态的语言,里面没法传一些动态参数,也就是一个写死的html页面.如果想实现在一个固定的html样式,传入不同的参数,这就可以用django的模板传参来解决. 模板参数 先在hel ...
- window与linux文件传输工具
window与linux文件传输工具 [一般用于SecureCRT ssh中使用] 法一:直接用yum安装lrzsz(推荐) yum install lrzsz -y 注意:rhel安装完系统后 直接 ...
- [翻译] EnterTheMatrix
Enter The Matrix https://github.com/mpospese/EnterTheMatrix The sample application to accompany my c ...
- Ladda 应用提交表单的时候显示loading载入中 包含不同位置,不同效果
Ladda 应用提交表单的时候显示loading载入中 包含不同位置,不同效果 不同大小.位置,效果,进度条等 演示 XML/HTML Code <article class="exa ...
- 北京市基本医疗保险A类定点医疗机构名单(2010-09-29)
1.中国医学科学院北京协和医院 2.首都医科大学附属北京同仁医院 3.首都医科大学宣武医院 4.首都医科大学附属北京友谊医院 5.北京大学第一医院 6.北京大学人民医院 7.北京大学第三医院 8.北京 ...
- Sublimetext3将空格转换为Tab
最近在学习Python,从网上粘贴的代码很多缩进都是空格,这样就会导致代码执行的时候报错,因为Python是依靠缩进来判断代码层次的.我的编辑器是Sublime Text 3看了一下,原来转换成Tab ...
- Latex初学者入门(三)-- 用BibTeX生成参考文献
昨boss要往期Elsevier 刊投文章,距上次排版貌似过了好久,生疏了不少,翻出以前的写的一些笔记再复习复习. 不过这次好多了,仅仅是改个格式,原始的文章已经用latex编写过了(个人感觉最头疼的 ...
- @JVM中对象的引用类型
JVM中有四种引用类型:强引用.软引用.弱引用.虚引用 强引用(Stong Reference):是指在程序代码中普遍存在的,类似:Object obj = new Object()这类的引用,只 ...
- 使用Topshelf 5步创建Windows 服务
使用Topshelf创建Windows 服务简要的介绍了创建Windows服务的另一种方法,老外的一篇文章Create a .NET Windows Service in 5 steps with T ...