zoukankan      html  css  js  c++  java
  • (六)发送、接收SOAP消息(1)

    一.为什么要用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消息包括:

      • Envelope
      • Header
      • Body
        • Message Data
        • Fault (optional)

      相同的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();
            }
    
        }
    }

    结果:

  • 相关阅读:
    [hosts]在hosts中屏蔽一级域名和二级域名的写法
    [oracle]查询一个表中数据的插入时间
    [Windows Doc]微软官方文档
    [PL]如果天空是黑暗的,那就摸黑生存
    [LVM]创建LVM卷
    [powershell]获取FCID&Port
    [oracle]解决ora-01034 oracle not available
    [GoogleBlog]new-approach-to-china
    [时钟]配置日期时间并同步到硬件
    [rhel]安装oracle11g
  • 原文地址:https://www.cnblogs.com/shyroke/p/7656613.html
Copyright © 2011-2022 走看看