【问题标题】:Webservice SOAP request - Wrong type of data sentWebservice SOAP 请求 - 发送的数据类型错误
【发布时间】:2016-12-06 11:36:27
【问题描述】:

上下文/我想要什么:

我在使用 SOAP 调用 Web 服务时遇到问题。这是我要调用的 WS 相关部分的图像:

(我自愿隐藏命名空间部分,这里不相关)

我想通过 'Demande_de_mot_de_passe' 函数发送数据并捕获此请求的结果。

在下面的代码中,这个请求是正确的(函数名是好的),我猜问题是我要发送的数据的格式。函数的调用是用这部分进行的:

$client->Demande_de_mot_de_passe($soapVar);

我试过的:

这是我尝试过的代码的相关部分(我自愿更改数据的值,但没有其他内容。括号没有拼写错误,它关闭了我没有放在这里的函数和类以保留相关部分):

    $client = new \SoapClient('URL_OF_THE_WS?WSDL', array(
      'trace'        => 1,
      'encoding'     => 'UTF-8',
      'soap_version' => SOAP_1_1,
      'classmap'     => array('Demande_de_mot_de_passe_Input' => 'Demande_de_mot_de_passe_Input')
    ));

    $donnesUtilisateur = new Demande_de_mot_de_passe_Input;
    $donnesUtilisateur->Code_societe = '000';
    $donnesUtilisateur->Ident_type   = 'A';
    $donnesUtilisateur->Ident_code   = 'xxxxxx';
    $donnesUtilisateur->Dat_demande  = '00000000';
    $donnesUtilisateur->Adr_mail     = 'xxxxxx';
    $donnesUtilisateur->Adr_cpos     = 'xxxxxx';
    $donnesUtilisateur->Nom          = 'xxxxxx';
    $donnesUtilisateur->Prenom       = 'xxxxxx';
    $donnesUtilisateur->Dat_naiss    = '00000000';
    $namespace = 'URL_OF_NAMESPACE';

    $soapVar = new \SoapVar($donnesUtilisateur, SOAP_ENC_OBJECT,'Demande_de_mot_de_passe_Input', $namespace);

    $result = $client->Demande_de_mot_de_passe($soapVar);

    print_r($result);

  }
}

class Demande_de_mot_de_passe_Input {
  public $Code_societe;
  public $Ident_type;
  public $Ident_code;
  public $Dat_demande;
  public $Adr_cpos;
  public $Adr_mail;
  public $Nom;
  public $Prenom;
  public $Dat_naiss;
}

我也尝试过用这样的数组传递一个对象的数组(没有成功):

$donnesUtilisateur =  [
      'Code_societe' => '000',
      'Ident_type'  => 'A',
      'Ident_code'  => 'xxxxxx',
      'Dat_demande' => '00000000',
      'Adr_cpos'    => 'xxxxxx',
      'Adr_mail'    => 'xxxxxx',
      'Nom'         => 'xxxxxx',
      'Prenom'      => 'xxxxxx',
      'Dat_naiss'   => '00000000',
    ];

和:

$donnesUtilisateur = (object) [
      'Code_societe' => '000',
      'Ident_type'  => 'A',
      'Ident_code'  => 'xxxxxx',
      'Dat_demande' => '00000000',
      'Adr_cpos'    => 'xxxxxx',
      'Adr_mail'    => 'xxxxxx',
      'Nom'         => 'xxxxxx',
      'Prenom'      => 'xxxxxx',
      'Dat_naiss'   => '00000000',
    ];

我得到的错误:

SoapFault: Did not receive a 'Demande_de_mot_de_passe_Input' object. in SoapClient->__call()

如果我理解清楚,发送的数据格式不正确,但是当我尝试其他方式发送时,它仍然报告相同的错误。

我读过的文档没有成功:

http://www.fvue.nl/wiki/Php:_Soap:_How_to_add_attribute_to_SoapVar

http://grokbase.com/t/php/php-soap/066jkmcz2h/passing-objects-to-soap-server-complextype-classmap

编辑

以下是 SoapUI 中 WS 'Demande_de_mot_de_passe' 函数调用的捕获:

(对不起,帖子太长了,我希望它足够清楚,如果需要不要忘记询问精度,提前感谢您的帮助:))

【问题讨论】:

  • AFAIK,您的问题在于 SoapVar 的实现和 complexType 的复杂性。如我所见,您的请求消息需要一个名为Demande_de_mot_de_passe 的参数,其中需要一个名为Demande_de_mot_de_passe_input 的参数。您的示例没有显示方法名称(只是您的代码),我认为这是错误的。尝试使用 SoapUI 打开 WSDL 并查看它将显示为请求消息的内容。最后,您的 SoapVar 实现有一些错误。
  • 感谢您的帮助,方法名称很好(如果我尝试错误,则会触发另一个错误),另一个开发人员使用 Python 脚本调用了此 Web 服务,它工作正常.但他只是通过关联数组传递数据,我不知道为什么这不适用于我的 PHP 改编脚本。谢谢你的时间伙伴:)
  • 您是否使用 SoapUI 打开了 WSDL?显示请求消息或整个 WSDL。
  • 在 SoapUI 中,我已经能够使用我在 PHP 代码中解释的那些参数发送“Demande_de_mot_de_passe”请求。 ($donnesUtilisateur 中的那些) 但是,我不知道我的 PHP 代码有什么问题。感谢您的宝贵时间
  • 这就是我需要帮助你的东西,看看 SoapUI 作为 XML 请求创建了什么。

标签: php web-services soap


【解决方案1】:

在您的 WSDL 类型中,有一个名为 Demande_de_mot_de_passe 的序列使用名为 Demande_de_mot_de_passeRequest 而不是 Demande_de_mot_de_passe_Input 的元素。

您从 SoapUI 打印的内容描述了消息请求,但如果是 document 样式,则 Demande_de_mot_de_passe 是一种类型。另一方面,如果是 RPC 则是方法名称。

如果是 RPC,则可以如下所示进行。您应该尽可能地使用本机对象(SOAP 会更好地使用它们)。一个 stdObject 就足够了:

$request = new stdClass();

$demande_de_mot_de_passeRequest->Code_societe = '000';
$demande_de_mot_de_passeRequest->Ident_type = 'A';
$demande_de_mot_de_passeRequest->Ident_code = 'xxxxxx';
$demande_de_mot_de_passeRequest->Dat_demande = '00000000';
$demande_de_mot_de_passeRequest->Adr_mail = 'xxxxxx';
$demande_de_mot_de_passeRequest->Adr_cpos = 'xxxxxx';
$demande_de_mot_de_passeRequest->Nom = 'xxxxxx';
$demande_de_mot_de_passeRequest->Prenom = 'xxxxxx';
$demande_de_mot_de_passeRequest->Dat_naiss = '00000000';

$request->Demande_de_mot_de_passeRequest = $demande_de_mot_de_passeRequest;

$response = $client->Demande_de_mot_de_passe($request);

如果您的 SOAP 绑定是文档,您只需添加一个名为 Demande_de_mot_de_passe 的新上层

/** The variable $demande_de_mot_de_passeRequest is created as above **/

$demande_de_mot_de_passe = new stdClass();
$demande_de_mot_de_passe->Demande_de_mot_de_passeRequest = $demande_de_mot_de_passeRequest;
$request->Demande_de_mot_de_passe = $demande_de_mot_de_passe;

$response = $client->Demande_de_mot_de_passe($request);

您的 WSDL 不需要列表/集合(这不是您的情况),因此您不需要使用 SoapVar 创建/解析变量。您可以阅读其他示例(一个是我的,但它是葡萄牙语的),另一个是关于 BOGUS 节点的:

http://forum.imasters.com.br/topic/535213-enviar-xml-via-soap/?p=2137411 http://www.fischco.org/blog/2011/3/26/php-soapserver-objects-arrays-and-encoding.html

【讨论】:

  • 我对以“0”开头的整数字段也有疑问,截断数字。示例:005 变为 5。你知道我该如何解决这个问题吗?
  • 对于左边的整数零没有意义。将格式更改为字符串。序列号、电话、邮政编码和其他任何可以从零开始的格式都必须这样做。
  • 您好,我无法将格式更改为字符串,因为 Web 服务不依赖于我。你知道我可以在我的 php 代码中解决这个问题的方法吗?
  • 如果数字将始终具有相同的长度或基于某些规则,请使用 str_pad 前置零。如果它是可变的,那就没有办法了。
  • 感谢您的回答,但是,它不起作用。我使用str_pad(5,3,0,STR_PAD_LEFT) 获取005 但WS 仍将其解释为5 :/
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-19
  • 1970-01-01
  • 2018-05-25
  • 1970-01-01
  • 1970-01-01
  • 2012-08-20
相关资源
最近更新 更多