webservice05#soap消息
1, SOAPMessage结构图

2, SOAP消息的创建
1>前面的一个简单WebService 服务
package com.yangw.soap.service;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
//说明该接口是服务接口,可以指定我们自己的命名空间
@WebServicepublic interface IMyService {
/**
* 使用注解指明返回值名,参数名
*/
@WebResult(name="addResult")
public int add(@WebParam(name="a")int a,@WebParam(name="b")int b);
}
package com.yangw.soap.service;
import javax.jws.WebService;
//说明该类是服务接口的实现类
@WebService(endpointInterface="com.yangw.soap.service.IMyService")
public class MyServiceImpl implements IMyService {
@Override
public int add(int a, int b) {
System.out.println("a+b="+(a+b));
return a+b;
}
}
package com.yangw.soap.service;
import javax.xml.ws.Endpoint;
public class MyService {
/**
* @param args
*/
public static void main(String[] args) {
//发布服务
Endpoint.publish("http://localhost:8899/ns", new MyServiceImpl());
}
}




2>SOAPMessage的创建
package com.yangw.soap.test;
import java.io.IOException;
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.soap.SOAPPart;
import org.junit.Test;
public class TestSoap {
/**
* 自己创建soap协议
*/
@Test
public void test() {
try {
//1,创建消息工厂
MessageFactory factory=MessageFactory.newInstance();
//2,根据消息工厂创建soap消息
SOAPMessage msg=factory.createMessage();
//3,创建SOAPPart
SOAPPart part=msg.getSOAPPart();
//4,获取soapEnvelope
SOAPEnvelope envelope=part.getEnvelope();
//5,通过SOAPEnvelope可以有效的获取相应的Header和Body等
SOAPBody body=envelope.getBody();
//6,根据QName创建相应的节点(QName就是一个带有命名空间的节点)
QName qName=new QName("http://service.soap.yangw.com/",
"add", "ns"); //相当于<ns:add xmlns="http://service.soap.yangw.com/" />
//7,将QName加入到body中
// body.addBodyElement(qName).setValue("123123");
/**
* <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
* <SOAP-ENV:Header/>
* <SOAP-ENV:Body>
* <ns:add xmlns:ns="http://service.soap.yangw.com/">123123</ns:add>
* </SOAP-ENV:Body>
* </SOAP-ENV:Envelope>
*/
//如果使用下面注释住的这个方式,会将<>转换为<>
//body.addBodyElement(qName).setValue("<a>11</a><b>22</b>");
//加子元素
SOAPBodyElement bodyEle=body.addBodyElement(qName);
bodyEle.addChildElement("a").setValue("11");
bodyEle.addChildElement("b").setValue("22");
//打印消息
msg.writeTo(System.out);
/**
* <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
* <SOAP-ENV:Header/>
* <SOAP-ENV:Body>
* <ns:add xmlns:ns="http://service.soap.yangw.com/">
* <a>11</a>
* <b>22</b>
* </ns:add>
* </SOAP-ENV:Body>
* </SOAP-ENV:Envelope>
*/
} catch (SOAPException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
3, SOAPMessage的传递
private String ns="http://service.soap.yangw.com/";
private String wsdlUrl="http://localhost:8899/ns?wsdl";
/**
* Soap消息的传递
*/
@Test
public void test02() {
try {
//1,创建服务
URL url=new URL(wsdlUrl);
QName qName=new QName(ns,"MyServiceImplService");
Service service=Service.create(url, qName);
//2,创建Dispatch
Dispatch<SOAPMessage> dispatch=service.createDispatch(new QName(ns,"MyServiceImplPort"),//(创建Port的时候指定名称空间)
SOAPMessage.class, Service.Mode.MESSAGE);
//3, 创建SOAPMessage
SOAPMessage msg=MessageFactory.newInstance().createMessage();
SOAPEnvelope envelope=msg.getSOAPPart().getEnvelope();
SOAPBody body=envelope.getBody();
//4, 创建QName来指定消息中传递的数据
QName eName=new QName(ns,"add", "nn"); //前缀必须指定,名字可以任意 <nn:add xmlns="XXX" />
SOAPBodyElement bodyEle=body.addBodyElement(eName);
bodyEle.addChildElement("a").setValue("22");
bodyEle.addChildElement("b").setValue("33");
msg.writeTo(System.out); //输出消息到控制台
/**
* <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
* <SOAP-ENV:Header/>
* <SOAP-ENV:Body>
* <nn:add xmlns:nn="http://service.soap.yangw.com/">
* <a>22</a>
* <b>33</b>
* </nn:add>
* </SOAP-ENV:Body>
* </SOAP-ENV:Envelope>
*/
System.out.println("\n invoke ...");
//5, 通过Dispatch传递消息
SOAPMessage resMsg= dispatch.invoke(msg);
resMsg.writeTo(System.out);
/**
* <S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
* <S:Header/>
* <S:Body>
* <ns2:addResponse xmlns:ns2="http://service.soap.yangw.com/">
* <addResult>55</addResult>
* </ns2:addResponse>
* </S:Body>
* </S:Envelope>
*/
//6, 将响应的消息转换为DOM对象
Document doc=resMsg.getSOAPPart().getEnvelope().getBody().extractContentAsDocument();
String str=doc.getElementsByTagName("addResult").item(0).getTextContent();
System.out.println("\n"+str);
} catch (SOAPException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
4, 基于PayLoad的方式传递SOAP消息,其实是附件的形式 下面实例是传递了一个自定义User对象 它可以传递字符串
package com.yangw.soap.service;
import java.util.Date;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public class User {
private String userName;
private String password;
private int age;
private Date birthday;
public User() {
super();
}
public User(String userName, String password, int age, Date birthday) {
super();
this.userName = userName;
this.password = password;
this.age = age;
this.birthday = birthday;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
}
package com.yangw.soap.service;
import java.util.List;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
//说明该接口是服务接口
@WebService
public interface IMyService {
/**
* 使用注解指明返回值名,参数名
*/
@WebResult(name="addResult")
public int add(@WebParam(name="a")int a,@WebParam(name="b")int b);
//返回对象是什么类型就写什么值,不区分单个对象还是List
@WebResult(name="user")
public User addUser(@WebParam(name="user")User user);
@WebResult(name="user")
public User login(@WebParam(name="username")String username,@WebParam(name="password")String password);
@WebResult(name="user")
public List<User> list();
}
package com.yangw.soap.service;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.jws.WebService;
//说明该类是服务接口的实现类
@WebService(endpointInterface="com.yangw.soap.service.IMyService")
public class MyServiceImpl implements IMyService {
private static List<User> users=new ArrayList<User>();
static{
users.add(new User("yangw","123456",12,new Date()));
users.add(new User("awei","123456",25,new Date()));
}
@Override
public int add(int a, int b) {
System.out.println("a+b="+(a+b));
return a+b;
}
@Override
public User addUser(User user) {
users.add(user);
return user;
}
@Override
public User login(String username, String password) {
for(User user:users){
if(user.getUserName().equals(username)&&user.getPassword().equals(password)){
return user;
}
}
return null;
}
@Override
public List<User> list() {
return users;
}
}
真正的处理消息的组成,发送和接收
/**
* Soap消息的传递,PAYLOAD方式可以传字符串的.
*/
@Test
public void test03() {
try {
//1,创建服务
URL url=new URL(wsdlUrl);
QName qName=new QName(ns,"MyServiceImplService");
Service service=Service.create(url, qName);
//2,创建Dispatch ,通过Source的方式传递
Dispatch<Source> dispatch=service.createDispatch(new QName(ns,"MyServiceImplPort"),
Source.class, Service.Mode.PAYLOAD);
//3, 根据用户对象创建相应的xml(编排)
User user=new User("ahuang","123321",23,new Date());
JAXBContext ctx=JAXBContext.newInstance(User.class);
Marshaller mar=ctx.createMarshaller();
//去掉文档头和尾
mar.setProperty(Marshaller.JAXB_FRAGMENT, true);
StringWriter writer=new StringWriter();
mar.marshal(user, writer);
//4,封装相应的Part addUser
String payLoad="<nn:addUser xmlns:nn='"+ns+"'>"+writer.toString()+"</nn:addUser>";
System.out.println(payLoad);
//5,通过Dispatch传递 payLoad
Source response=dispatch.invoke(new StreamSource(new StringReader(payLoad)));
//6, 将Source转换为DOM操作,使用Transform对象
Transformer tran=TransformerFactory.newInstance().newTransformer();
DOMResult result=new DOMResult();
tran.transform(response, result);
//7,处理响应信息
XPath xpath=XPathFactory.newInstance().newXPath();
NodeList nl=(NodeList) xpath.evaluate("//user", result.getNode(),XPathConstants.NODESET);
//反编排
User u=(User) ctx.createUnmarshaller().unmarshal(nl.item(0));
System.out.println(u.getUserName());
} catch (IOException e) {
e.printStackTrace();
} catch (JAXBException e) {
e.printStackTrace();
} catch (TransformerConfigurationException e) {
e.printStackTrace();
} catch (TransformerFactoryConfigurationError e) {
e.printStackTrace();
} catch (TransformerException e) {
e.printStackTrace();
} catch (XPathExpressionException e) {
e.printStackTrace();
}
}
5, list方法测试
package com.yangw.soap.service;
import java.util.List;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
//说明该接口是服务接口
@WebService
public interface IMyService {
/**
* 使用注解指明返回值名,参数名
*/
@WebResult(name="addResult")
public int add(@WebParam(name="a")int a,@WebParam(name="b")int b);
//返回对象是什么类型就写什么值,不区分单个对象还是List
@WebResult(name="user")
public User addUser(@WebParam(name="user")User user);
@WebResult(name="user")
public User login(@WebParam(name="username")String username,@WebParam(name="password")String password);
@WebResult(name="user")
public List<User> list1();
@WebResult(name="user")
//设置header为true,让它以头信息的形式传递
//这是显示的方式传递头部信息的方式
public List<User> list2(@WebParam(name="authInfo",header=true)String authInfo);
}
不带参数的list()方法
/**
* Soap消息的传递 --测试 list()方法,不带参数的形式
*/
@Test
public void test04() {
try {
//1,创建服务
URL url=new URL(wsdlUrl);
QName qName=new QName(ns,"MyServiceImplService");
Service service=Service.create(url, qName);
//2,创建Dispatch (创建Port的时候指定名称空间)
Dispatch<SOAPMessage> dispatch=service.createDispatch(new QName(ns,"MyServiceImplPort"),
SOAPMessage.class, Service.Mode.MESSAGE);
//3, 创建SOAPMessage
SOAPMessage msg=MessageFactory.newInstance().createMessage();
SOAPEnvelope envelope=msg.getSOAPPart().getEnvelope();
SOAPBody body=envelope.getBody();
//4, 创建QName来指定消息中传递的数据
QName eName=new QName(ns,"list1", "nn"); //前缀必须指定,名字可以任意 <nn:add xmlns="XXX" />
body.addBodyElement(eName);
msg.writeTo(System.out); //输出消息到控制台
/**
*<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
* <SOAP-ENV:Header/>
* <SOAP-ENV:Body>
* <nn:list xmlns:nn="http://service.soap.yangw.com/"/>
* </SOAP-ENV:Body>
*</SOAP-ENV:Envelope>
*/
System.out.println("\n invoke ...");
//5, 通过Dispatch传递消息
SOAPMessage resMsg= dispatch.invoke(msg);
resMsg.writeTo(System.out);
System.out.println();
/**
*<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
* <S:Header/>
* <S:Body>
* <ns2:listResponse xmlns:ns2="http://service.soap.yangw.com/">
* <user>
* <age>12</age>
* <birthday>2014-03-03T14:21:02.468+08:00</birthday>
* <password>123456</password>
* <userName>yangw</userName>
* </user>
* <user>
* <age>25</age>
* <birthday>2014-03-03T14:21:02.468+08:00</birthday>
* <password>123456</password>
* <userName>awei</userName>
* </user>
* </ns2:listResponse>
* </S:Body>
*</S:Envelope>
*/
//6, 将响应的消息转换为DOM对象
Document doc=resMsg.getSOAPPart().getEnvelope().getBody().extractContentAsDocument();
NodeList nl=doc.getElementsByTagName("user");
JAXBContext ctx=JAXBContext.newInstance(User.class);
for(int i=0;i<nl.getLength();i++){
Node node=nl.item(i); //import org.w3c.dom.Node;
User user=(User) ctx.createUnmarshaller().unmarshal(node);
System.out.println(user.getUserName()+":"+user.getPassword());
}
} catch (SOAPException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (JAXBException e) {
e.printStackTrace();
}
}
带参数的list()方法测试
/**
* Soap消息的传递 --测试 list(String)方法,带参数的形式,一般都是把参数放到头信息中作验证
*/
@Test
public void test05() {
try {
//1,创建服务
URL url=new URL(wsdlUrl);
QName qName=new QName(ns,"MyServiceImplService");
Service service=Service.create(url, qName);
//2,创建Dispatch (创建Port的时候指定名称空间)
Dispatch<SOAPMessage> dispatch=service.createDispatch(new QName(ns,"MyServiceImplPort"),
SOAPMessage.class, Service.Mode.MESSAGE);
//3, 创建SOAPMessage
SOAPMessage msg=MessageFactory.newInstance().createMessage();
SOAPEnvelope envelope=msg.getSOAPPart().getEnvelope();
//3.2 头信息的处理
SOAPHeader header=envelope.getHeader();
if(header==null)
header=envelope.addHeader();
QName hName=new QName(ns,"authInfo", "nn");
header.addHeaderElement(hName).setValue("aabbcc");
SOAPBody body=envelope.getBody();
//4, 创建QName来指定消息中传递的数据
QName eName=new QName(ns,"list2", "nn"); //前缀必须指定,名字可以任意 <nn:add xmlns="XXX" />
body.addBodyElement(eName);
msg.writeTo(System.out); //输出消息到控制台
/**
* <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
* <SOAP-ENV:Header>
* <nn:authInfo xmlns:nn="http://service.soap.yangw.com/">aabbcc</nn:authInfo>
* </SOAP-ENV:Header>
* <SOAP-ENV:Body>
* <nn:list2 xmlns:nn="http://service.soap.yangw.com/"/>
* </SOAP-ENV:Body>
* </SOAP-ENV:Envelope>
*/
System.out.println("\n invoke ...");
//5, 通过Dispatch传递消息
SOAPMessage resMsg= dispatch.invoke(msg);
resMsg.writeTo(System.out);
System.out.println();
/**
*<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
* <S:Header/>
* <S:Body>
* <ns2:listResponse xmlns:ns2="http://service.soap.yangw.com/">
* <user>
* <age>12</age>
* <birthday>2014-03-03T14:21:02.468+08:00</birthday>
* <password>123456</password>
* <userName>yangw</userName>
* </user>
* <user>
* <age>25</age>
* <birthday>2014-03-03T14:21:02.468+08:00</birthday>
* <password>123456</password>
* <userName>awei</userName>
* </user>
* </ns2:listResponse>
* </S:Body>
*</S:Envelope>
*/
//6, 将响应的消息转换为DOM对象
Document doc=resMsg.getSOAPPart().getEnvelope().getBody().extractContentAsDocument();
NodeList nl=doc.getElementsByTagName("user");
JAXBContext ctx=JAXBContext.newInstance(User.class);
for(int i=0;i<nl.getLength();i++){
Node node=nl.item(i); //import org.w3c.dom.Node;
User user=(User) ctx.createUnmarshaller().unmarshal(node);
System.out.println(user.getUserName()+":"+user.getPassword());
}
} catch (SOAPException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (JAXBException e) {
e.printStackTrace();
}
}
上面头消息的处理是显示消息的处理,用wsimport导出之后,可以看到会“自动生成一个List对象”
接口上的名称空间应该与实现类上的名称空间一致.
webservice05#soap消息的更多相关文章
- 如何用Apache TCPMon来截获SOAP消息
在WebService服务器和客户机之间会传递SOAP消息,有时我们需要得到这些消息以便调试,而Apache的TCPMon可以帮助我们做到这一点. TCPMon的下载地址在http://ws.apa ...
- soap消息机制 讲解
SOAP(Simple Object Access Protocol,简单对象访问协议)作为一种信息交互协议在分布式应用中非常广泛,如WebService.在使用.Net开发WebService时候, ...
- Web Service学习之八:Soap消息详解
一.区别概念 WSDL是网络服务描述语言,是XML文档:它包含一系列描述某个web service的定义或者说是规则.尤其是定义了传输Sope消息的结构 Soap:简单对象访问协议,是交换数据的一种协 ...
- SOAP消息的传递
上一篇说了SOAP消息的创建,那么创建好了的SOAP消息要怎么发送给服务端呢? public class SoapTest { private String wsdlUri = "http: ...
- SOAP消息创建
看了SOAP消息分析之后,大家对soap消息应该有了一个初步的认识,那么怎样自己编写一个soap消息呢? 先来创建一个简单的soap消息: @Test public void test1(){ try ...
- JAX-WS创建和处理SOAP消息
JAX-WS规范是一组XML web services的JAVA API,在 JAX-WS中,一个远程调用可以转换为一个基于XML的协议例如SOAP,在使用JAX-WS过程中,开发者不需要编写任何生成 ...
- 写入soap消息以及与soap消息通信
1.些了解一下soap消息的结构以及通信方式如下图:
- Web Service进阶(二)如何用Apache TCPMon来截获SOAP消息
注:以下是关于TCPMon的一些使用常识,如果不需要或是已经熟悉就不用往下看了. 在WebService服务器和客户机之间会传递SOAP消息,有时我们需要得到这些消息以便调试,而Apache的TCPM ...
- 如何在WCF中用TcpTrace工具查看发送和接收的SOAP消息
WCF对消息加密(只对消息加密,不考虑Authorize)其实很简单,只要在server和client端的binding加入security mode为Message(还有Transport, Tra ...
随机推荐
- 简单倒计时js代码
//倒计时 var timer=null; var interval = 1000; function ShowCountDown(year,month,day,hour,minute,second, ...
- js通过添加随机数的方法,解决多张图片加载时由于缓存导致图片无法正确显示的问题
问题出现描述:当对列表中某个图片进行重新编辑时,提交后会发现图片列表仍会出现修改之前的图片,新图片并未覆盖. 问题出现原因:缓存问题. 解决办法:通过js方法,在每张图片路劲后面添加一个随机数,这样每 ...
- 图片浏览 h5
@{ Layout = null; } <html> <head> <script type="text/javascript" src=" ...
- Ubuntu安装卸载anaconda
安装要点: 1.在Anaconda官网https://www.continuum.io/downloads内下载需要的版本: 2.打开终端--进入下载安装包所在的文件夹(cd 文件名)--输入命令:b ...
- python基础教程(三)
序列概览 Python 包含6 种内建的序列,这里重点讨论最常用的两种类型:列表和元组. 列表与元组的主要区别在于,列表可以修改,元组则不能.也就是说如果要根据要求来添加元素,那么列表可以会更好用:而 ...
- 官方问答--微信小程序常见FAQ (17.8.21-17.8.27)
给提问的开发者的建议:提问之前先查询 文档.通过社区右上角搜索搜索已经存在的问题. 写一个简明扼要的标题,并且正文描述清楚你的问题. 提交 BUG:需要带上基础库版本号,设备信息(iOS, Andro ...
- tomcat设置文件编码
tomcat修改bin文件夹下面的catalina.bat文件可以解决乱码在文件中加上JAVA_OPTS="-server -Xms128M -Xmx4096M -XX:PermSize=5 ...
- jmeter系列------参数关联
接口请求中的一个变量需要用上一个接口道服务器返回响应的动态值(上个请求). 遇到这样的情况,我们就需要用到关联 例如用户A发表了一个一条微信朋友圈,用户B想对这条朋友圈进行评论,就需要先获取到这个朋友 ...
- SVN 通过IIS设置反向代理访问
原因 一个字,穷,没办法,只有一台机器 要当测试服务器还要做源码管理. 解决办法 通过IIS配置反向代理访问SVN,给SVN访问的HTTPS绑定上域名,就可以正常访问了. 1.修改SVN配置 把SVN ...
- C#最佳工具集合:IDE、分析、自动化工具等
C#是企业中广泛使用的编程语言,特别是那些依赖微软的程序语言.如果您使用C#构建应用程序,则最有可能使用Visual Studio,并且已经寻找了一些扩展来对您的开发进行管理.但是,这个工具列表可能会 ...