zoukankan      html  css  js  c++  java
  • WebService客户端终极总结 + httpClient调用webservice

    WebService概念简单理解

    1.可以看成是RPC的一种实现。常见的RPC框架:Dubbox、gRPC、Thrift、Avro等

    2.wsdl:定义了服务端的接口的调用方式,包括请求和返回的类型等。

    3.soap:采用Http来传输信息,可以认为是SOAP协议包装了Http协议在TCP上传输。

    4.wsdl与soap的关系在于:

     wsdl绑定服务的时候可以设定使用的协议,协议可以是soap、http、smtp、ftp等任何一种传输协议。

    5.wsdl文件:其实封装了wsdl和soap。

    6.WebService优势:

       语言无关

       获取wsdl文件就知道怎么调用。

       技术成熟,可以直接通过工具生成客户端。

    WebService调用方式

    1.通过URL Connection调用

     优点:仅仅是能实现

     缺点:使用原生类,太复杂了。发送Http请求和SOAP协议都要自己封装。

    2.通过wximport生成代码

     优点:自动生成客户端调用代码,不用实现。

         因为生成的是代码,直接调用类即可。

     缺点:会生成很多类。

    3.axis2、cxf、xFire等框架。

     优点:比较成熟,也能自动生成客户端调用代码。

         因为生成的是代码,直接调用类即可。

     缺点:引入重量级框架,也会生成很多类。

         当然,如果系统的WebService通讯很多,那么可以考虑。

    4.HttpClient调用(本文推荐)

     优点:封装了Http请求,一般系统都有jar,不需要引入额外的jar包。

         不会生成很多类,代码简洁。

     缺点:SOAP协议内容需要自己封装,使用soapUI工具之后也比较简单。

         复杂对象需要解析XML,不过目前XML与对象映射的都很简单,问题不大。

    HttpClient调用WebService

    1.通过WSDL,编写SOAP协议

      (1)如果能看懂WSDL和SOAP,完全可以自己写出来。当然也可以通过soapUI工具 实现

               熟悉WSDL文档:http://www.360doc.com/content/16/1027/00/37651083_601648996.shtml

      (2)下载soapUI 4.5.2

     2.httpClient方法

    /**
         * 使用SOAP1.1发送消息
         * 
         * @param postUrl
         * @param soapXml
         * @param soapAction
         * @return
         * @throws Exception 
         */
        public static String doPostSoap1_1(String postUrl, String soapXml,
                    String soapAction, int socketTimeout,String serviceName) {
            String retStr = "";
            // 创建HttpClientBuilder
            HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
            // HttpClient
            CloseableHttpClient closeableHttpClient = httpClientBuilder.build();
            HttpPost httpPost = new HttpPost(postUrl);
                    //  设置请求和传输超时时间
            //如果没有传送超时,默认两分钟
            if (socketTimeout <= 0){
                socketTimeout = HttpKit.socketTimeout;
            }
            RequestConfig requestConfig = RequestConfig.custom()
                    .setSocketTimeout(socketTimeout)
                    .setConnectTimeout(connectTimeout).build();
            httpPost.setConfig(requestConfig);
            try {
                httpPost.setHeader("Content-Type", "text/xml;charset=UTF-8");
                httpPost.setHeader("SOAPAction", soapAction);
                StringEntity data = new StringEntity(soapXml,
                        Charset.forName("UTF-8"));
                httpPost.setEntity(data);
                CloseableHttpResponse response = closeableHttpClient
                        .execute(httpPost);
                HttpEntity httpEntity = response.getEntity();
                if (httpEntity != null) {
                    // 打印响应内容
                    retStr = EntityUtils.toString(httpEntity, "UTF-8");
                }
                // 释放资源
                closeableHttpClient.close();
            } catch (ConnectTimeoutException e) {
                logger.error("URL["+postUrl+"]"+serviceName+"连接超时:"+e.getMessage());
                throw e;
                
            } catch (SocketTimeoutException e) {
                logger.error("URL["+postUrl+"]"+serviceName+"响应超时:"+e.getMessage());
                throw e;
            } catch (Exception e) {
    logger.error(
    "URL["+postUrl+"]"+serviceName+"出现未知异常:"+e.getMessage(),e);
    throw e;

    }
    return retStr;
    }

    /**
         * 使用SOAP1.2发送消息
         * 
         * @param postUrl
         * @param soapXml
         * @param soapAction
         * @return
         * @throws Exception 
         */
        public static String doPostSoap1_2(String postUrl, String soapXml,
                String soapAction, int socketTimeout) throws Exception {
            String retStr = "";
            // 创建HttpClientBuilder
            HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
            // HttpClient
            CloseableHttpClient closeableHttpClient = httpClientBuilder.build();
            HttpPost httpPost = new HttpPost(postUrl);
                    // 设置请求和传输超时时间
            //如果没有传送超时,默认两分钟
            if (socketTimeout <= 0){
                socketTimeout = HttpKit.socketTimeout;
            }
            RequestConfig requestConfig = RequestConfig.custom()
                    .setSocketTimeout(socketTimeout)
                    .setConnectTimeout(connectTimeout).build();
            httpPost.setConfig(requestConfig);
            try {
                httpPost.setHeader("Content-Type",
                        "application/soap+xml;charset=UTF-8");
                httpPost.setHeader("SOAPAction", soapAction);
                StringEntity data = new StringEntity(soapXml,
                        Charset.forName("UTF-8"));
                httpPost.setEntity(data);
                CloseableHttpResponse response = closeableHttpClient
                        .execute(httpPost);
                HttpEntity httpEntity = response.getEntity();
                if (httpEntity != null) {
                    // 打印响应内容
                    retStr = EntityUtils.toString(httpEntity, "UTF-8");
                }
                // 释放资源
                closeableHttpClient.close();
            } catch (ConnectTimeoutException e) {
                logger.error("URL["+postUrl+"]"+serviceName+"连接超时:"+e.getMessage());
                throw e;
                
            } catch (SocketTimeoutException e) {
                logger.error("URL["+postUrl+"]"+serviceName+"响应超时:"+e.getMessage());
                throw e;
    
    
            } catch (Exception e) {
    logger.error("URL["+postUrl+"]"+serviceName+"出现未知异常:"+e.getMessage(),e);
    throw e;
    }
    return retStr; } 

    3.传送的soapXML参数

    <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:web="http://webservice.xxx.xxx.xxx">
      <soapenv:Header/>
      <soapenv:Body>
          <web:queryUser>

                             <account>?</account>
                             <areaCode>?</areaCode>
                             <carNo>?</carNo>

               </web:queryUser>
      </soapenv:Body>
    </soapenv:Envelope>

    注意:如果传送的参数是XML字符串,那么需要使用转义或者使用<![CDATA[ "+xmlStr+"]]>,建议使用<![CDATA[ "+xmlStr+"]]>的方式。

     

  • 相关阅读:
    Spring boot 梳理
    Spring boot 梳理
    Spring boot 梳理
    观察者模式
    设计模式原则
    Spring MVC上传文件
    Spring MVC视图解析器
    Spring MVC中Action使用总结
    Spring MVC控制器
    Java并发 两个线程交替执行和死锁
  • 原文地址:https://www.cnblogs.com/caoshouling/p/14475892.html
Copyright © 2011-2022 走看看