(七)发送、接收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();
        }

    }
}

结果:

原文地址:https://www.cnblogs.com/shyroke/p/7657133.html