0

我尝试构建混合应用程序,我有用于soap适配器的wsdl我在ibm站点HTTP适配器中逐步遵循- 与HTTP后端系统通信

然后我想像这样调用适配器从混合客户端应用程序调用适配器过程

这是我尝试的代码:

索引.html

<!DOCTYPE HTML>
<html>
        <head>
            <meta charset="UTF-8">
            <title>Emoney</title>
            <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=0">
            <!--
                <link rel="shortcut icon" href="images/favicon.png">
                <link rel="apple-touch-icon" href="images/apple-touch-icon.png"> 
            -->
            <link href="jqueryMobile/jquery.mobile-1.4.0.css" rel="stylesheet">
            <link rel="stylesheet" href="css/main.css">
            <link rel="stylesheet" href="jqueryMobile/jquery.mobile-1.4.0.css">
            <script>window.$ = window.jQuery = WLJQ;</script>
            <script src="jqueryMobile/jquery.mobile-1.4.0.js"></script>
        </head>
        <body style="display: none;">

            <div id="header">
            <h1>Inquiry</h1>
        </div>
        <div id="wrapper">
            <ul id="itemsList"></ul>
        </div>



    <script src="js/initOptions.js"></script>
            <script src="js/main.js"></script>
            <script src="js/messages.js"></script>
        </body>
</html>

main.js

//function wlCommonInit(){
//  /*
//   * Use of WL.Client.connect() API before any connectivity to a MobileFirst Server is required. 
//   * This API should be called only once, before any other WL.Client methods that communicate with the MobileFirst Server.
//   * Don't forget to specify and implement onSuccess and onFailure callback functions for WL.Client.connect(), e.g:
//   *    
//   *    WL.Client.connect({
//   *          onSuccess: onConnectSuccess,
//   *          onFailure: onConnectFailure
//   *    });
//   *     
//   */
//  
//  // Common initialization code goes here
//  
//  
//}
//
//
//  $('#inquiry').on('click', function(){
//      $.mobile.changePage('#inquiry');
//      doGetInquiry();
//  });
//  
////    function doGetInquiry(){
////        $.mobile.loading("show");
////        var invocationData = {
////                adapter : 'InquiryAdapters',
////                procedure : 'getInquiry',
////                parameters : []
////            };
////        
////        var options = {
////                onSuccess: doGetInquiryFinish,
////                onFailure: doGetInquiryFinish
////        };
////        WL.Client.invokeProcedure(invocationData, options);
////    }
//  
//  function doGetInquiry(){
//      $.mobile.loading("show");
//      var invocationData = {
//              adapter : 'InquiryAdapters',
//              procedure : 'getFeedsFiltered',
//              parameters : []
//          };
//      
//      var options = {
//              onSuccess: doGetInquiryFinish,
//              onFailure: doGetInquiryFinish
//      };
//      WL.Client.invokeProcedure(invocationData, options);
//  }
//  
//  function doGetInquiryFinish(result){
//      if(result.invocationResult.inquiry.length>0){
//          buildInquiryList(result.invocationResult.inquiry);
//      }else{
//          $.mobile.loading("hide");
//          alert("Please try again later!");
//      }
//  }
//  
//  function buildInquiryList(inquiry){
//      var ul = $('#inquirytList');
//      for (var i = 0; i < inquiry.length; i++) {
//          var li = $('<li/>').text(inquiry[i].title);
//          var pubDate = $('<div/>', {
//              'class': 'pubDate'
//          }).text(inquiry[i].pubDate);
//
//          li.append(pubDate);
//          
//          ul.append(li);
//      }
//      
//      
//      
//      
////        console.log("in buildInquiryList()");
////        $("#inquirytList").empty();
////        var item, i;
////        for(i=0;i<inquiry.length;i++){      
////            item = inquiry[i];              
////                var html = "";                          
//////              html += "<h3 class='ui-li-heading'>" + item.accountName + "</h3>";
//////              html += "<p class='ui-li-desc'>" + item.accountNumber + "</p>";
//////              if(item.accountBalance.indexOf("(")>-1){
//////                  html += "<div class='rightText negative'>$" + item.accountBalance + "</div>";                   
//////              }else{
//////                  html += "<div class='rightText'>$" + item.accountBalance + "</div>";
//////              }                                                                                                                           
//////              var listItem = $('<li class="acctItem" acct_name="' + item.accountName + '" data="' + item.accountNumber + '"><a href="#">' + html + '</a></li>');          
//////              $("#accountList").append(listItem);                         
////        }
//////      $("#accountHeaderLabel").html("Account List");
//////      $('#accountList:visible').listview('refresh');  
////        $.mobile.loading("hide");
////        
//  }


/*
 *
    COPYRIGHT LICENSE: This information contains sample code provided in source code form. You may copy, modify, and distribute
    these sample programs in any form without payment to IBM® for the purposes of developing, using, marketing or distributing
    application programs conforming to the application programming interface for the operating platform for which the sample code is written.
    Notwithstanding anything to the contrary, IBM PROVIDES THE SAMPLE SOURCE CODE ON AN "AS IS" BASIS AND IBM DISCLAIMS ALL WARRANTIES,
    EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, ANY IMPLIED WARRANTIES OR CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY,
    FITNESS FOR A PARTICULAR PURPOSE, TITLE, AND ANY WARRANTY OR CONDITION OF NON-INFRINGEMENT. IBM SHALL NOT BE LIABLE FOR ANY DIRECT,
    INDIRECT, INCIDENTAL, SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR OPERATION OF THE SAMPLE SOURCE CODE.
    IBM HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS OR MODIFICATIONS TO THE SAMPLE SOURCE CODE.

 */

var busyIndicator = null;

function wlCommonInit(){
    busyIndicator = new WL.BusyIndicator();
    loadFeeds();
}

function loadFeeds(){
    busyIndicator.show();
    var invocationData = {
            adapter : 'SoapAdapter1',
            procedure : 'InquiryImpl_getAmount',
            parameters : []
        };

    WL.Client.invokeProcedure(invocationData,{
        onSuccess : loadFeedsSuccess,
        onFailure : loadFeedsFailure
    });
}

function loadFeedsSuccess(result){
    WL.Logger.debug("Feed retrieve success");
    busyIndicator.hide();
    if (result.invocationResult.Items.length>0) 
        displayFeeds(result.invocationResult.Items);
    else 
        loadFeedsFailure();
}

function loadFeedsFailure(result){
    WL.Logger.error("Feed retrieve failure");
    busyIndicator.hide();
    WL.SimpleDialog.show("Inquiry", "Service not available. Try again later.", 
            [{
                text : 'Reload',
                handler : WL.Client.reloadApp 
            },
            {
                text: 'Close',
                handler : function() {}
            }]
        );
}

function displayFeeds(items){
    var ul = $('#itemsList');
    for (var i = 0; i < items.length; i++) {
        var li = $('<li/>').text(items[i].owner);
        var amount = $('<div/>', {
            'class': 'amount'
        }).text(items[i].amount);

        li.append(amount);

        ul.append(li);
    }
}

soapAdapter-impl

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Generated code - Do not edit                                                                                  //
//                                                                                                               //
// This is a SOAP adapter that was auto-generated by Worklight for invocation of specific SOAP-based services.   //
// The adapter may invoke more than one service as long as they are all from the same enpdpoint (server host).   //
// Each adapter procedure matches a single operation for the same endpoint server and accepts:                   //
//   params  - Serialized JSON representation of the XML-based SOAP body to be sent to the service               //
//   headers - Custom HTTP headers to be specified when invoking the remote service. It is a JSON object with    //
//             the headers names and values. E.g. { 'name1' : 'value1', 'name2' : 'value2' }                     //
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////

function InquiryImpl_getAmount(params, headers){
    var soapEnvNS = '';
    // The value of 'soapEnvNS' was set based on the version of the SOAP to be used (i.e. 1.1 or 1.2).
    soapEnvNS = 'http://www.w3.org/2003/05/soap-envelope';

    // The following mappings object was autogenerated from the XML schema of the input message to the service.
    // It is being used to support a params JSON when invoking this procedure that don't specify the namespace
    // prefix nor specifying whether a property is attribute or not.
    // 
    // The 'roots' object has the list of message parts within the invocation SOAP message. Each entry has a
    // mapping between the root element name and its namespace prefix and type.
    // Each root object may define 'nsPrefix' and 'type'. Both are optional - If there is no need for a NS prefix
    // then the 'nsPrefix' should not be specified. If the element is a simple type then the 'type' should not be
    // specified.
    //
    // The 'types' object has a list of types each defining the children of the type and the definition of each
    // child. If the child is a complext type, the 'type' property has a reference to the child type definition.
    // Each child object may define:
    // 'nsPrefix' (optional) - Holds the namespace prefix to be attached to the element. If there is no need for 
    //   a NS prefix then the 'nsPrefix' should not be specified. 
    // 'type' (optional) - If the element is a simple type then the 'type' should not be specified. If it is an 
    //   attribute then 'type' should have the value of '@'. Otherwise the value of 'type' is a reference to the 
    //   type definition within the 'types' object.
    var mappings = {
        roots: {
            'getAmount': { nsPrefix: 'ns', type: 'ns:getAmount' }               
        },

        types: {
            'ax27:InquiryRequest': {
                children: [
                    {'channelId': { nsPrefix: 'ax29' }},    
                    {'rrn': { nsPrefix: 'ax29' }},  
                    {'stan': { nsPrefix: 'ax29' }}, 
                    {'phoneNo': { nsPrefix: 'ax27' }}   
                ]
            },

            'ns:getAmount': {
                children: [
                    {'request': { nsPrefix: 'ns', type: 'ax27:InquiryRequest' }}    
                ]
            }
        }
    };
    var namespaces = 'xmlns:ax29="http://services.mik.co.id/xsd" xmlns:ns1="http://org.apache.axis2/xsd" xmlns:ax212="http://beans.common.sentrapay.mik.co.id/xsd" xmlns:ns="http://inquiry.services.mik.co.id" xmlns:ax27="http://inquiry.services.mik.co.id/xsd" xmlns:ax28="http://services.mik.co.id/xsd" xmlns:ax210="http://inquiry.services.mik.co.id/xsd" xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:ax211="http://beans.common.sentrapay.mik.co.id/xsd" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" ';
    var request = buildBody(params, namespaces, mappings, soapEnvNS);
    var soapAction = 'urn:getAmount';
    return invokeWebService(request, headers, soapAction);
}



function buildBody(params, namespaces, mappings, soapEnvNS){
    var body =
        '<soap:Envelope xmlns:soap="' + soapEnvNS + '">\n' +
        '<soap:Body>\n';

    var fixedParams = {};
    for (var paramName in params) {
        if (mappings['roots'][paramName]) { //There is mapping for this param
            var root = mappings['roots'][paramName];
            var name = paramName;
            if (root['nsPrefix'])
                name = root['nsPrefix'] + ':' + paramName;
            fixedParams[name] = handleMappings(params[paramName], root['type'], mappings['types']); 
        }
        else {
            fixedParams[paramName] = params[paramName];
        }
    }

    body = jsonToXml(fixedParams, body, namespaces);

    body += 
        '</soap:Body>\n' +
        '</soap:Envelope>\n';
    return body;
}

function handleMappings(jsonObj, type, mappings) {
    var fixedObj = {};
    var typeMap = mappings[type]['children']; //Get the object that defines the mappings for the specific type

    // loop through the types and see if there is an input param defined
    for(var i = 0; i < typeMap.length; i++) {
        var childType = typeMap[i];

        for(var key in childType) {
            if(jsonObj[key] !== null) { // input param exists
                var childName = key;
                if (childType[key]['nsPrefix'])
                    childName = childType[key]['nsPrefix'] + ':' + key;

                if (!childType[key]['type']) //Simple type element
                    fixedObj[childName] = jsonObj[key];
                else if (typeof jsonObj[key] === 'object' && jsonObj[key].length != undefined) { //Array of complex type elements
                    fixedObj[childName] = [];
                    for (var i=0; i<jsonObj[key].length; i++)
                        fixedObj[childName][i] = handleMappings(jsonObj[key][i], childType[key]['type'], mappings);
                }
                else if (typeof jsonObj[key] === 'object') //Complex type element
                    fixedObj[childName] = handleMappings(jsonObj[key], childType[key]['type'], mappings);
                else if (childType[key]['type'] == '@') //Attribute
                    fixedObj['@' + childName] = jsonObj[key];
            }
        }
    }

    return fixedObj;
}

function getAttributes(jsonObj) {
    var attrStr = '';
    for(var attr in jsonObj) {
        if (attr.charAt(0) == '@') {
            var val = jsonObj[attr];
            attrStr += ' ' + attr.substring(1);
            attrStr += '="' + xmlEscape(val) + '"';
        }
    }
    return attrStr;
}

function jsonToXml(jsonObj, xmlStr, namespaces) {
    var toAppend = '';
    for(var attr in jsonObj) {
        if (attr.charAt(0) != '@') {
            var val = jsonObj[attr];
            if (typeof val  === 'object'  &&  val.length != undefined) {
                for(var i=0; i<val.length; i++) {
                    toAppend += "<" + attr + getAttributes(val[i]);
                    if (namespaces != null)
                        toAppend += ' ' + namespaces;
                    toAppend += ">\n";
                    toAppend = jsonToXml(val[i], toAppend);
                    toAppend += "</" + attr + ">\n";
                }
            }
            else {
                toAppend += "<" + attr;
                if (typeof val  === 'object') {
                    toAppend += getAttributes(val);
                    if (namespaces != null)
                        toAppend += ' ' + namespaces;
                    toAppend += ">\n";
                    toAppend = jsonToXml(val, toAppend);
                }
                else {
                    toAppend += ">" + xmlEscape(val);
                }
                toAppend += "</" + attr + ">\n";
            }
        }
    }
    return xmlStr += toAppend;
}


function invokeWebService(body, headers, soapAction){
    var input = {
        method : 'post',
        returnedContentType : 'xml',
        path : '/Web_Service/services/InquiryImpl.InquiryImplHttpSoap12Endpoint/',
        body: {
            content : body.toString(),
            contentType : 'text/xml; charset=utf-8'
        }
    };

    //Adding custom HTTP headers if they were provided as parameter to the procedure call
    //Always add header for SOAP action 
    headers = headers || {};
    if (soapAction != 'null')
        headers.SOAPAction = soapAction;
    input['headers'] = headers;

    return WL.Server.invokeHttp(input);
}

function xmlEscape(obj) {
    if(typeof obj !== 'string') {
        return obj;
    }
    return obj.replace(/&/g, '&amp;')
           .replace(/"/g, '&quot;')
           .replace(/'/g, '&apos;')
           .replace(/</g, '&lt;')
           .replace(/>/g, '&gt;');
}

肥皂适配器.xml

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<wl:adapter xmlns:wl="http://www.ibm.com/mfp/integration" xmlns:http="http://www.ibm.com/mfp/integration/http" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="SoapAdapter1">
    <displayName>SoapAdapter1</displayName>
    <description></description>
    <connectivity>
        <connectionPolicy xsi:type="http:HTTPConnectionPolicyType">
            <protocol>http</protocol>
            <domain>localhost</domain>
            <port>8080</port>
            <connectionTimeoutInMilliseconds>30000</connectionTimeoutInMilliseconds>
            <socketTimeoutInMilliseconds>30000</socketTimeoutInMilliseconds>
            <maxConcurrentConnectionsPerNode>2</maxConcurrentConnectionsPerNode>
        </connectionPolicy>
    </connectivity>

    <procedure name="InquiryImpl_getAmount"/>
</wl:adapter>

如果我调用适配器的结果:

{
   "Envelope": {
      "Body": {
         "Fault": {
            "detail": "",
            "faultcode": "soapenv:VersionMismatch",
            "faultstring": "Transport level information does not match with SOAP Message namespace URI"
         }
      },
      "Header": {
         "Action": "http:\/\/www.w3.org\/2005\/08\/addressing\/soap\/fault",
         "wsa": "http:\/\/www.w3.org\/2005\/08\/addressing"
      },
      "soapenv": "http:\/\/schemas.xmlsoap.org\/soap\/envelope\/"
   },
   "errors": [
   ],
   "info": [
   ],
   "isSuccessful": true,
   "responseHeaders": {
      "Connection": "close",
      "Content-Type": "text\/xml;charset=utf-8",
      "Date": "Wed, 01 Apr 2015 04:12:43 GMT",
      "Server": "Apache-Coyote\/1.1",
      "Transfer-Encoding": "chunked"
   },
   "responseTime": 47,
   "statusCode": 500,
   "statusReason": "Internal Server Error",
   "totalTime": 49,
   "warnings": [
   ]
}

“statusReason”:“内部服务器错误”

4

1 回答 1

0

看起来适配器需要 SOAP 1.2,但您的服务是 SOAP 1.1。

适配器:soapEnvNS = ' http://www.w3.org/2003/05/soap-envelope ';

返回值:“soapenv”:“http://schemas.xmlsoap.org/soap/envelope/”

您可以尝试更改适配器中的命名空间以匹配您的服务。需要查看 WSDL 才能知道生成的适配器为什么具有错误的名称空间。

于 2015-04-23T13:38:27.100 回答