您的位置:首页 > 其它

(六)发送、接收SOAP消息(1)

2017-10-12 16:14 344 查看

 

一.为什么要用soap

  • 原本我们使用web服务都是根据wsdl生成客户端(生成一堆java文件)然后再调用,本章节讲解如何用soap消息来替代这种方式。

二、SOAP消息格式

  • SOAP(简单对象访问协议)是基于XML的消息格式。下面是一个简单的SOAP消息:
<?xml version="1.0"?>
<soap:Envelope
xmlns:soap="http://www.w3.org/2001/12/soap-envelope"
soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding">

<soap:Header>
</soap:Header>

<soap:Body>

... message data ...

<soap:Fault>
</soap:Fault>

</soap:Body>

</soap:Envelope>
  • 正如你可以看到一个SOAP消息包括:

    [ul] Envelope
  • Header
  • Body Message Data
  • Fault (optional)
[/ul]

相同的SOAP消息结构用于客户端和Web Service服务器之间的请求和响应。

Body内的Fault元素是可选的。只有Web服务中发生内部错误里才返回。否则,返回正常信息数据。

SOAP不指定一个消息从客户端如何获取到Web Service,但最常见的情况是通过HTTP。

 

三、案例

  3.1  发布服务

  • 服务接口
package service;

import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;

@WebService
public interface IFirstService {

@WebResult(name = "addResult")
public int add(@WebParam(name = "x") int x, @WebParam(name = "y") int y);
}
  • 服务接口实现类
package service;

import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;

@WebService(endpointInterface = "service.IFirstService")
public class IFirstServiceImpl implements IFirstService {

@Override
public int add(int x, int y) {

return x + y;
}

}
  • 发布服务
package publish;

import javax.xml.ws.Endpoint;

import service.IFirstServiceImpl;

public class TestPublish {
public static void main(String[] args) {
Endpoint.publish("http://localhost:3030/first", new IFirstServiceImpl());

System.out.println("发布成功.....");
}
}
  •  查看wsdl文件
<definitions targetNamespace="http://service/" name="IFirstServiceImplService">
<types>
<xsd:schema>
<xsd:import namespace="http://service/" schemaLocation="http://localhost:3030/first?xsd=1" />
</xsd:schema>
</types>
<message name="add">
<part name="parameters" element="tns:add" />
</message>
<message name="addResponse">
<part name="parameters" element="tns:addResponse" />
</message>
<portType name="IFirstService">
<operation name="add">
<input wsam:Action="http://service/IFirstService/addRequest"
message="tns:add" />
<output wsam:Action="http://service/IFirstService/addResponse"
message="tns:addResponse" />
</operation>
</portType>
<binding name="IFirstServiceImplPortBinding" type="tns:IFirstService">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http"
style="document" />
<operation name="add">
<soap:operation soapAction="" />
<input>
<soap:body use="literal" />
</input>
<output>
<soap:body use="literal" />
</output>
</operation>
</binding>
<service name="IFirstServiceImplService">
<port name="IFirstServiceImplPort" binding="tns:IFirstServiceImplPortBinding">
<soap:address location="http://localhost:3030/first" />
</port>
</service>
</definitions>
  • http://localhost:3030/first?xsd=1文件
<xs:schema version="1.0" targetNamespace="http://service/">
<xs:element name="add" type="tns:add" />
<xs:element name="addResponse" type="tns:addResponse" />
<xs:complexType name="add">
<xs:sequence>
<xs:element name="x" type="xs:int" />
<xs:element name="y" type="xs:int" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="addResponse">
<xs:sequence>
<xs:element name="addResult" type="xs:int" />
</xs:sequence>
</xs:complexType>
</xs:schema>

 

 

 

二、客户端发送soap消息、接收soap消息

  • 这里不再用工具生成客户端
package test;

import java.net.URL;
import java.rmi.RemoteException;

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.SOAPHeader;
import javax.xml.soap.SOAPMessage;
import javax.xml.soap.SOAPPart;
import javax.xml.ws.Dispatch;
import javax.xml.ws.Service;

import org.w3c.dom.Node;

public class TestMain {
public static void main(String[] args) throws RemoteException {

/**
* 发送soap消息
*
*/

try {
// 创建一个message工厂
MessageFactory factory = MessageFactory.newInstance();
//获取soapMessage对象
SOAPMessage send_message = factory.createMessage();
SOAPPart soapPart=send_message.getSOAPPart();

/**
* 获取head和body对象
*/
SOAPEnvelope soapEnvelope=soapPart.getEnvelope();

SOAPBody soapBody=soapEnvelope.getBody();
SOAPHeader soapHeader=soapEnvelope.getHeader();

/**
* 把数据封装到body元素里
*/

//添加add标签
QName addName=new QName("http://service/", "add","ns");
SOAPBodyElement soapBodyElement=soapBody.addBodyElement(addName);

//添加add标签中的子标签
soapBodyElement.addChildElement(new QName("x")).setValue("1");;
soapBodyElement.addChildElement(new QName("y")).setValue("10");;

//打印发送到服务端的soap消息
send_message.writeTo(System.out);

/*
* 将消息发送到服务端
*/
URL wsdlDocumentLocation=new URL("http://localhost:3030/first?wsdl");
QName serviceName=new QName("http://service/", "IFirstServiceImplService");
Service service=Service.create(wsdlDocumentLocation, serviceName);

/**
* createDispatch方法第一个参数的Qname的构造方法的参数为port标签的name值
* Mode
* Service.Mode.MESSAGE:发送是XML的Doucment对象
* Service.Mode.PAYLOAD:发送的是XML的字符串
*/
QName portName=new QName("http://service/","IFirstServiceImplPort");
Dispatch<SOAPMessage> dispatch=service.createDispatch(portName,SOAPMessage.class,Service.Mode.MESSAGE);

//发送soap消息,并接收服务端返回的soap消息
SOAPMessage respon_message=dispatch.invoke(send_message);

System.out.println("服务端返回soap消息");
respon_message.writeTo(System.out);

/**
* 解析从服务端返回的soap消息
*/
SOAPPart part=respon_message.getSOAPPart();
SOAPEnvelope envelope=part.getEnvelope();
SOAPBody body=envelope.getBody();
Node node=body.getElementsByTagName("addResult").item(0);

System.out.println();
System.out.println("result=="+node.getTextContent());

} catch (Exception e) {
e.printStackTrace();
}

}
}

结果:

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: