Flutter/Dart 中的 SOAP 请求
SOAP Request in Flutter/Dart
我需要使用 Flutter 向 .NET Web 服务 (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连接:
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>
所以,我有两个很大的疑问:
- 如何通过认证(user/password);
- 为什么,即使设置 "Content-Length" 总是硬编码它 return 411.
我是 Dart/Flutter
的新人
您设置的 header 太多,因为其中大部分将由客户端设置 - 特别是内容长度和编码。
您的基本身份验证 header 看起来没问题。
不要混合使用 await
和 then
- 使用其中之一。
您可以将代码简化为:
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 http
将所有 header 名称小写(RFC 允许),但这会使一些服务器感到困惑。
使用 Postman 尝试您的请求。如果您可以让它在那里工作,请编辑显示良好邮递员请求(或其他语言)的问题。
经过大量时间的测试,我通过使用这个 header:
获得了成功
"SOAPAction": "http://www.totvs.com/IwsConsultaSQL/RealizarConsultaSQL",
"Content-Type": "text/xml;charset=UTF-8",
"Authorization": "Basic bWVzdHJlOnRvdHZz",
"cache-control": "no-cache"
接缝 Content-Length 是自动发送的,所以,有效的代码是这样的:
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}");
});
感谢大家的帮助,我按照之前的提示通过Postman代码得到了解决方案,谢谢。
我需要使用 Flutter 向 .NET Web 服务 (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连接:
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>
所以,我有两个很大的疑问:
- 如何通过认证(user/password);
- 为什么,即使设置 "Content-Length" 总是硬编码它 return 411.
我是 Dart/Flutter
的新人您设置的 header 太多,因为其中大部分将由客户端设置 - 特别是内容长度和编码。
您的基本身份验证 header 看起来没问题。
不要混合使用 await
和 then
- 使用其中之一。
您可以将代码简化为:
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 http
将所有 header 名称小写(RFC 允许),但这会使一些服务器感到困惑。
使用 Postman 尝试您的请求。如果您可以让它在那里工作,请编辑显示良好邮递员请求(或其他语言)的问题。
经过大量时间的测试,我通过使用这个 header:
获得了成功 "SOAPAction": "http://www.totvs.com/IwsConsultaSQL/RealizarConsultaSQL",
"Content-Type": "text/xml;charset=UTF-8",
"Authorization": "Basic bWVzdHJlOnRvdHZz",
"cache-control": "no-cache"
接缝 Content-Length 是自动发送的,所以,有效的代码是这样的:
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}");
});
感谢大家的帮助,我按照之前的提示通过Postman代码得到了解决方案,谢谢。