как перенести вызов API SOAP wsdl с помощью PHP на Rails с помощью Savon Gem - PullRequest
0 голосов
/ 25 сентября 2018

Мне нужно перенести код из приложения PHP, вызывающего WSDL API, на Rails

вот мой код PHP:

class naf
{
    protected $_soap;
    protected $_token = array('Token' => '');
    protected $_header;

    public function __construct()
    {
        $this->_soap = new SoapClient('http://apiwebsite/api.asmx?WSDL', array('trace' => true));
        $this->_header = new SoapHeader('http://apinamespace/api/', 'Authenticationtoken', $this->_token, true);
    }

    public static function forge() {
        return new static;
    }

    public function get_boards()
    {
        $result = $this->_makeCall('getBoardList', array());
        return $result->getBoardListResult->BoardList;
    }

    public function board_list() {
        $data = array();
        $result = $this->get_boards();
        foreach ($result as $row) {
            $data[$row->Boardid] = $row->LongName;
        }
        return $data;
    }

    public function login($id, $passwrd, $board)
    {
        $args = array('userid' => $id, 'password' => $passwrd, 'board' => $board);
        return $this->_makeCall('login', $args);
    }

    public function logoff($id, $sid)
    {
        $args = array('creaid' => $id, 'sessionid' => $sid);
        return $this->_makeCall('logoff', $args);
    }

    public function isLogin($id, $sid)
    {
        $args = array('creaid' => $id, 'sessionid' => $sid);
        return $this->_makeCall('isAuthenticated', $args);
    }

    protected function _makeCall($action, $args)
    {
        try {
            $result = $this->_soap->__soapCall($action, $args, null, $this->_header, $outHeaders);
            return $result;
        } catch (Exception $e) {
            error_log(print_r($e, true));
        }
    }
}

Я много чего пробовал с "Savon", нокажется, что мой заголовок никогда не установлен.Я даже успешно перенес его на C #, но SoapHeader всегда кажется неправильным в рельсах.Я всегда получаю

ОШИБКА: (soap: clientfault) System.Web.Services.Protocols.SoapException: Пустой tokenid

Кажется, он не видит мой заголовок

PS Параметр Token является добровольным ommit в приведенном ниже коде

Вот мой код железной дороги:

require 'savon'

class Naf

  NAF_API_TOKEN = { Token: ''}

  def initialize()
    @wsdl = 'http://apiwebsite/api.asmx?WSDL'
    @header = { :Authenticationtoken => NAF_API_TOKEN }
  end

  def get_boards()
    puts "=========== Naf.get_boards ================== "

    result = makeCall(:get_board_list, {})

    return result.getBoardListResult.BoardList
  end

  def board_list()
    data = Array.new()
    results = get_boards()

    results.each do | row |
      data[row.Boardid] = row.LongName
    end

    return data

  end

  def login(id, passwrd, board)
    args = {:userid => id, :password => passwrd, :board => board}
    makeCall('logoff', args)
  end

  def logoff(id, sid)
    args = {:creaid => id, :sessionid => sid}
    makeCall('logoff', args)
  end

  def isLogin(id, sid)
    args = {:creaid => id, :sessionid => sid}
    makeCall('isAuthenticated', args)
  end

  private
  def makeCall(action, args)
    puts "=========== Naf.makeCall ================== "
    begin

      client = Savon.client(
          wsdl: @wsdl,
          soap_header: @header
          )
      return client.call(action, args)

    rescue Exception => e
      puts "ERROR: #{e.message}"
    end
  end

end

Я только что получил ожидаемый XML-запрос:

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://apinamespace/api/">
   <SOAP-ENV:Header>
      <ns1:Authenticationtoken SOAP-ENV:mustUnderstand="1">
         <ns1:Token>TOKENHERE</ns1:Token>
      </ns1:Authenticationtoken>
   </SOAP-ENV:Header>
   <SOAP-ENV:Body>
      <ns1:getBoardList />
   </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

1 Ответ

0 голосов
/ 26 сентября 2018

Я не уверен, что сделал это наилучшим образом, но у меня все получилось:

Мне пришлось добавить определение пространства имен и настроить заголовок, чтобы добавить свой собственный "префикс тега", например:

NAF_API_TOKEN = {' tns : Token' => 'TOKEN'}

вот мой обновленный код:

require 'savon'

class Naf

  #HACK I had to add the "TNS" keyword to make it work
  NAF_API_TOKEN = { 'tns:Token' => 'TOKEN'}

  def initialize()
    @wsdl = 'http://webapi/apiws/api.asmx?WSDL'
    @header = { 'tns:Authenticationtoken' => NAF_API_TOKEN }
  end

  def get_boards()
    puts "=========== Naf.get_boards ================== "
    result = makeCall(:get_board_list, {})

    resulthash = result.to_hash
    boardlist = resulthash[:get_board_list_response][:get_board_list_result][:board_list]

    return boardlist
  end

  def board_list()
    puts "=========== Naf.board_list ================== "

    results = get_boards()
    data = results.map { |row | {:boardid => row[:boardid], :long_name => row[:long_name]}}

    puts data.inspect
    return data

  end

  def login(id, passwrd, board)
    args = {:userid => id, :password => passwrd, :board => board}
    makeCall('logoff', args)
  end

  def logoff(id, sid)
    args = {:creaid => id, :sessionid => sid}
    makeCall('logoff', args)
  end

  def isLogin(id, sid)
    args = {:creaid => id, :sessionid => sid}
    makeCall('isAuthenticated', args)
  end

  private
  def makeCall(action, args)
    puts "=========== Naf.makeCall ================== "
    begin

      client = Savon.client(
          wsdl: @wsdl,
          namespace: 'http://namespace/api/', #We need that to add the "TNS" keyword
          soap_header: @header
          #log: true, pretty_print_xml: true # Uncomment to display wsdl request
          )


      return client.call(action, args)

    rescue Exception => e
      puts "ERROR: #{e.message}"
    end
  end

end
...