1、消息结构:首先我们要知道SOAPMessage的结构
2、SOAP消息创建:实现一个SOAPMessage要通过以下几个步骤
//1、创建消息工厂
MessageFactory mFactory = MessageFactory.newInstance();
//2、根据消息工厂创建SOAP消息
SOAPMessage message = mFactory.createMessage();
//3、创建soappart
SOAPPart part = message.getSOAPPart();
//4、获得SOAP信封SOAPEnvelope
SOAPEnvelope envelope = part.getEnvelope();
//5、可以通过SoapEnvelope有效的获取相应的body和header
SOAPBody body = envelope.getBody();
//6、根据QName创建相应的节点(QName就是一个带有命名空间的节点)
//<ns:add xmlns="http://service.soap.org/">
QName qname = new QName("http://service.soap.org/", "add", "ns");
//可通过以下方式给消息体赋值
SOAPBodyElement ele = body.addBodyElement(qname);
ele.addChildElement("a").setValue("3");
ele.addChildElement("b").setValue("5");
//打印消息信息
message.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.org/">
<a>3</a>
<b>5</b>
</ns:add>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
3、基于消息的传递方式:简单消息的传递要实现以下几个步骤
// 1、创建service服务
URL url = new URL("http://localhost:8989/ws?wsdl");
QName qname = new QName("http://service.soap.org/", "MyserviceImpl");
Service service = Service.create(url, qname);
// 2、创建Dispatch(基于消息的传递)
Dispatch<SOAPMessage> dispatch = service.createDispatch(new QName(
"http://service.soap.org/", "MyserviceImplPort"),
SOAPMessage.class, Service.Mode.MESSAGE);
// 3、创建soap消息
MessageFactory factory = MessageFactory.newInstance();
SOAPMessage message = factory.createMessage();
SOAPEnvelope envelope = message.getSOAPPart().getEnvelope();
SOAPBody body = envelope.getBody();
QName sname = new QName("http://service.soap.org/", "add", "ns");
SOAPBodyElement ele = body.addBodyElement(sname);
ele.addChildElement("a").setValue("22");
ele.addChildElement("b").setValue("13");
// 消息穿件完成,控制台输出消息内容
message.writeTo(System.out);
// 4、发送SOAPMessage消息,并获得相应信息
SOAPMessage response = dispatch.invoke(message);
System.out.println("\n invoking......");
response.writeTo(System.out);
// 5、解析出相应信息的结果
Document doc = response.getSOAPPart().getEnvelope().getBody()
.extractContentAsDocument();
String result = doc.getElementsByTagName("addResult").item(0)
.getTextContent();
System.out.println("\n addResult=" + result);
相应的SOAPMessage消息结构如下:
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Header/>
<S:Body>
<ns2:addResponse xmlns:ns2="http://service.soap.org/">
<addResult>
35
</addResult>
</ns2:addResponse>
</S:Body>
</S:Envelope>
4、通过源数据的方式传递:这里远程服务方法接口返回值定义成java对象便于xml和java转换,@WebResult
@WebResult(name="User")便于对结果xml和java的转换
@XmlRootElement
public class User {
private int id;
private String username;
private String nickname;
private String password;
public User() {
}
public User(int id,String username,String nickname,String password)
{
this.id = id;
this.username = username;
this.nickname = nickname;
this.password = password;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getNickname() {
return nickname;
}
public void setNickname(String nickname) {
this.nickname = nickname;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
远程服务接口
@WebService
public interface IMyservice {
@WebResult(name="addResult")
public int add(@WebParam(name="a")int a,@WebParam(name="b")int b);
/**以下返回的结构名称都设置成user,是为了对传递的soap消息很好的进行xml和java之间的转换**/
@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();
}
基于源数据的SOAP传递
// 1、创建service服务
URL url = new URL("http://localhost:8989/ws?wsdl");
QName qname = new QName("http://service.soap.org/", "MyserviceImpl");
Service service = Service.create(url, qname);
// 2、创建dispatch(通过源数据的方式传递)
Dispatch<Source> dispatch = service.createDispatch(new QName(
"http://service.soap.org/", "MyserviceImplPort"),
Source.class, Service.Mode.PAYLOAD);
// 3、根据用户对象创建相应的xml
User user = new User(3, "sean", "肖恩", "123456");
JAXBContext cxt = JAXBContext.newInstance(User.class);
Marshaller marshaller = cxt.createMarshaller();
// 转换xml时去掉头标签
marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true);
StringWriter writer = new StringWriter();
marshaller.marshal(user, writer);
System.out.println(writer.toString());
// 4、封装相应的part addUser
String payload = "<ns:addUser xmlns:ns=\"http://service.soap.org/\">"
+ writer.toString() + "</ns:addUser>";
StringReader reader = new StringReader(payload);
StreamSource source = new StreamSource(reader);
// 5、通过dispatch传递payload
Source response = dispatch.invoke(source);
// 6、将response转换成dom进行操作使用Transform转换
Transformer trans = TransformerFactory.newInstance()
.newTransformer();
DOMResult result = new DOMResult();
trans.transform(response, result);
// 7、XPath处理dom
XPath xPath = XPathFactory.newInstance().newXPath();
NodeList nl = (NodeList) xPath.evaluate("//user", result.getNode(),
XPathConstants.NODESET);
User user2 = (User) cxt.createUnmarshaller().unmarshal(nl.item(0));
System.out.println(user2.getUsername());