• (七)发送、接收SOAP消息(以HttpClient方式)(2)


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

    package com.shyroke.webService_client;
    
    import java.io.IOException;
    import java.io.StringReader;
    
    import org.apache.http.HttpEntity;
    import org.apache.http.HttpResponse;
    import org.apache.http.client.ClientProtocolException;
    import org.apache.http.client.methods.HttpPost;
    import org.apache.http.client.methods.HttpUriRequest;
    import org.apache.http.entity.StringEntity;
    import org.apache.http.impl.client.DefaultHttpClient;
    import org.apache.http.util.EntityUtils;
    import org.dom4j.Document;
    import org.dom4j.Element;
    import org.dom4j.io.SAXReader;
    
    /**
     * Hello world!
     *
     */
    public class App {
        public static void main(String[] args) {
    
            try {
    
                /**
                 * 定义发送soap的消息
                 */
                StringBuffer str_xml = new StringBuffer();
                str_xml.append(
                        "<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ser="http://service/">");
                str_xml.append(" <soapenv:Header/>");
                str_xml.append("  <soapenv:Body>");
                str_xml.append("<ser:add>");
                str_xml.append(" <x>11</x>");
                str_xml.append("<y>20</y>");
                str_xml.append("</ser:add>");
                str_xml.append("</soapenv:Body>");
                str_xml.append("</soapenv:Envelope>");
    
                /**
                 * 定义post请求
                 */
                // 定义post请求地址
                HttpPost httpPost = new HttpPost("http://localhost:3030/first?wsdl");
                // 定义post请求的实体
                HttpEntity entity = new StringEntity(str_xml.toString());
                // 设置post请求的实体和头部
                httpPost.setEntity(entity);
                httpPost.setHeader("Content-Type", "text/xml; charset=UTF-8");
    
                /**
                 * 发送请求并获取返回数据
                 */
                @SuppressWarnings("deprecation")
                DefaultHttpClient client = new DefaultHttpClient();
                // 发送请求并获取返回数据
                HttpResponse response = client.execute(httpPost);
                // 获取返回数据中的实体
                HttpEntity respon_entity = response.getEntity();
                // 将返回数据的实体转为字符串
                String respon_str = EntityUtils.toString(respon_entity);
    
                // 解析字符串
                SAXReader reader = new SAXReader();
                Document document = reader.read(new StringReader(respon_str));
                Element rootElement = document.getRootElement();
    
                Element resultElement = rootElement.element("Body").element("addResponse").element("addResult");
                String addResult = resultElement.getText();
                System.out.println("addResult = " + addResult);
    
            } catch (Exception e) {
                e.printStackTrace();
            }
    
        }
    }

    结果:

  • 相关阅读:
    is(C# 参考)
    索引器(C# 编程指南)
    修改IIS文件上传大小限制
    Sql Server判断某列字段是否为空或判断某列字段长度
    Linq分页查询
    H5网页播放器播不了服务器上的mp4视频文件
    [你必须知道的.NET] 第八回:品味类型---值类型与引用类型(上)-内存有理
    如何通过ildasm/ilasm修改assembly的IL代码
    Python实战之set学习笔记及简单练习
    Python实战之int学习笔记及简单练习
  • 原文地址:https://www.cnblogs.com/shyroke/p/7657133.html
Copyright © 2020-2023  润新知