提问者:小点点

Flutter/Dart中的SOAP请求


我需要使用Flutter向NETWebservice(WSDL)发出SOAP请求。

这个网络服务有一个基本的身份验证(用户、密码)和一些带有预定义信封的服务。

所以我尝试创建一个SOAP信封:

String requestBody = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:tot=\"http://www.totvs.com/\">   <soapenv:Header/>   <soapenv:Body>      <tot:RealizarConsultaSQL>         <!--Optional:-->         <tot:codSentenca>ETHOS.TESTE</tot:codSentenca>         <!--Optional:-->         <tot:codColigada>0</tot:codColigada>         <!--Optional:-->         <tot:codSistema>F</tot:codSistema>         <!--Optional:-->         <tot:parameters></tot:parameters>      </tot:RealizarConsultaSQL>   </soapenv:Body></soapenv:Envelope>";

此信封有效。第二步是建立超文本传输协议连接:

http.Response response = await http.post(
  request,
  headers: {
    "Accept-Encoding": "gzip,deflate",
    "Content-Length": utf8.encode(requestBody).length.toString(),
    "Content-Type": "text/xmlc",
    "SOAPAction": "http://www.totvs.com/IwsConsultaSQL/RealizarConsultaSQL",
    "Authorization": "Basic bWVzdHJlOnRvdHZz",
    "Host": "totvs.brazilsouth.cloudapp.azure.com:8051",
    "Connection": "Keep-Alive",
    "User-Agent": "Apache-HttpClient/4.1.1 (java 1.5)"
  },
  body: utf8.encode(requestBody),
  encoding: Encoding.getByName("UTF-8")).then((onValue)
{
  print("Response status: ${onValue.statusCode}");
  print("Response body: ${onValue.body}");
 });

此时我只收到411代码:

<hr><p>HTTP Error 411. The request must be chunked or have a content length.</p>

所以,我有两个很大的疑问:

  1. 如何通过身份验证(用户/密码);
  2. 为什么,即使设置“Content-Llong”硬编码它也总是返回411。

我是新来的Dart/Flutter


共2个答案

匿名用户

在花了很多时间进行测试后,我通过使用这个标题获得了成功:

     "SOAPAction": "http://www.totvs.com/IwsConsultaSQL/RealizarConsultaSQL",
    "Content-Type": "text/xml;charset=UTF-8",
    "Authorization": "Basic bWVzdHJlOnRvdHZz",
    "cache-control": "no-cache"

它接缝Content-Llong是自动发送的,所以,工作的代码是这样的:

  http.Response response = await http.post(
      request,
      headers: {
        "SOAPAction": "http://www.totvs.com/IwsConsultaSQL/RealizarConsultaSQL",
        "Content-Type": "text/xml;charset=UTF-8",
        "Authorization": "Basic bWVzdHJlOnRvdHZz",
        "cache-control": "no-cache"
      },
      body: utf8.encode(requestBody),
      encoding: Encoding.getByName("UTF-8")
  ).then((onValue)
  {
    print("Response status: ${onValue.statusCode}");
    print("Response body: ${onValue.body}");

  });

谢谢大家的帮助,我得到了解决方案的邮差代码,如前所述,谢谢。

匿名用户

您设置了太多的标头,因为其中大部分将由客户端设置-特别是内容长度和编码。

您的基本身份验证标头看起来不错。

不要混合await然后-使用一个或另一个。

您可以将代码简化为:

import 'dart:convert';
import 'package:http/http.dart' as http;

main() async {
  String soap = '''<?xml version="1.0"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
                  xmlns:tot="http://www.totvs.com/">
  <soapenv:Header/>
  <soapenv:Body>
    <tot:RealizarConsultaSQL>      
      <tot:codSentenca>ETHOS.TESTE</tot:codSentenca>    
      <tot:codColigada>0</tot:codColigada>       
      <tot:codSistema>F</tot:codSistema>       
      <tot:parameters></tot:parameters>
    </tot:RealizarConsultaSQL>
  </soapenv:Body>
</soapenv:Envelope>''';

  http.Response response = await http.post(
    'http://totvs.brazilsouth.cloudapp.azure.com:8051/wherever',
    headers: {
      'content-type': 'text/xmlc',
      'authorization': 'bWVzdHJlOnRvdHZz',
      'SOAPAction': 'http://www.totvs.com/IwsConsultaSQL/RealizarConsultaSQL',
    },
    body: utf8.encode(soap),
  );
  print(response.statusCode);
}

请注意,Dart超文本传输协议将所有标头名称小写(RFC允许),但这会混淆一些服务器。

使用Postman尝试您的请求。如果您可以让它在那里工作,请编辑显示良好Postman请求(或其他语言)的问题。