Я пытаюсь отправить запрос POST, используя RobotFramework, где тело запроса - XML.
Вот пример файла робота:
*** Settings ***
Library REST
*** Variables ***
${SERVER_URL} https://www.w3schools.com/xml/tempconvert.asmx
*** Test Cases ***
CL 1
[Tags] TC-CL
# Send SOAP via POST <?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">" <soap:Body>" <FahrenheitToCelsius xmlns="https://www.w3schools.com/xml/">" <Fahrenheit>100</Fahrenheit>" </FahrenheitToCelsius>" </soap:Body>"</soap:Envelope>
# Send SOAP via POST <?xml version=\"1.0\" encoding=\"utf-8\"?><soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\"> <soap:Body> <FahrenheitToCelsius xmlns=\"https://www.w3schools.com/xml/\">\" <Fahrenheit>100</Fahrenheit> </FahrenheitToCelsius> </soap:Body></soap:Envelope>
# Send SOAP via POST <?xml version=\"1.0\" encoding=\"utf-8\"?>\n<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">\n <soap:Body>\n <FahrenheitToCelsius xmlns=\"https://www.w3schools.com/xml/\">\n <Fahrenheit>100</Fahrenheit>\n </FahrenheitToCelsius>\n </soap:Body>\n</soap:Envelope>
Send SOAP via POST <?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><FahrenheitToCelsius xmlns="https://www.w3schools.com/xml/"><Fahrenheit>100</Fahrenheit></FahrenheitToCelsius></soap:Body></soap:Envelope>
*** Keywords ***
Send SOAP via POST
[Arguments] ${body}
SET HEADERS {"SOAPAction": "https://www.w3schools.com/xml/FahrenheitToCelsius","Content-Type": "text/xml","Cache-Control": "no-cache"}
${resp}= POST ${SERVER_URL} data=${body}
Log ${resp} repr=true
Когда вы запускаете этот код, яполучить ошибку:
This is not a JSON string:
"data=<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/
soap/envelope/"><soap:Body><FahrenheitToCelsius xmlns="https://www.w3schools.com/xml/"><Fahrenheit>100</Fahrenheit></FahrenheitToCelsius></soap:Body></soap:Envelope>"
К вашему сведению: закомментированные версии «Отправка SOAP через POST» - это разные способы, которыми я пытался обойти проблему.
Вот пример кода Python с использованием запросовчтобы убедиться, что моя конечная точка работает (как только я обойду это надоедливое «Это не проблема строки JSON»:
import requests
url = "https://www.w3schools.com/xml/tempconvert.asmx"
payload = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">\r\n <soap:Body>\r\n <FahrenheitToCelsius xmlns=\"https://www.w3schools.com/xml/\">\r\n <Fahrenheit>100</Fahrenheit>\r\n </FahrenheitToCelsius>\r\n </soap:Body>\r\n</soap:Envelope>"
payload = "<?xml version=\"1.0\" encoding=\"utf-8\"?><soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\"> <soap:Body> <FahrenheitToCelsius xmlns=\"https://www.w3schools.com/xml/\">\" <Fahrenheit>100</Fahrenheit> </FahrenheitToCelsius> </soap:Body></soap:Envelope>"
payload = '<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><FahrenheitToCelsius xmlns="https://www.w3schools.com/xml/"><Fahrenheit>100</Fahrenheit></FahrenheitToCelsius></soap:Body></soap:Envelope>'
headers = {
'SOAPAction': "\"https://www.w3schools.com/xml/FahrenheitToCelsius\"",
'Content-Type': "text/xml",
'Cache-Control': "no-cache",
}
response = requests.request("POST", url, data=payload, headers=headers)
print(response.text)
Проблема, похоже, заключается в коде RESTInstance здесь
Первоначальная проблема, которая вызывает ошибку (см. Строку комментариев ниже):
@keyword
def post(self, endpoint, body=None, timeout=None, allow_redirects=None,
validate=True, headers=None):
"""Make a ``POST`` request call to a specified ``endpoint``.
Example:
POST "Mr Potato" to endpoint and ensure status code is 201
| `POST` | /users | { "id": 11, "name": "Mr Potato" } |
| `Integer` | response status | 201 |
"""
endpoint = self._input_string(endpoint)
request = deepcopy(self.request)
request['method'] = "POST"
request['body'] = self.input(body) # <== ERROR THROWS HERE
if allow_redirects is not None:
request['allowRedirects'] = self._input_boolean(allow_redirects)
if timeout is not None:
request['timeout'] = self._input_timeout(timeout)
validate = self._input_boolean(validate)
if headers:
request['headers'].update(self._input_object(headers))
return self._request(endpoint, request, validate)['response']
Основная проблема заключается в том, что код _request заставляет использовать тело в параметре json файла request.requests.call (он же клиент основан на импорте), см. фрагмент кода из того же файла ниже:
def _request(self, endpoint, request, validate=True):
if endpoint.endswith('/'):
endpoint = endpoint[:-1]
if not endpoint.startswith(('http://', 'https://')):
base_url = self.request['scheme'] + "://" + self.request['netloc']
if not endpoint.startswith('/'):
endpoint = "/" + endpoint
endpoint = urljoin(base_url, self.request['path']) + endpoint
request['url'] = endpoint
url_parts = urlparse(request['url'])
request['scheme'] = url_parts.scheme
request['netloc'] = url_parts.netloc
request['path'] = url_parts.path
try:
response = client(request['method'], request['url'],
params=request['query'],
json=request['body'], #<== ROOT CAUSE HERE
headers=request['headers'],
proxies=request['proxies'],
cert=request['cert'],
timeout=tuple(request['timeout']),
allow_redirects=request['allowRedirects'],
verify=request['sslVerify'])
При отправке XML с использованием библиотеки запросов вам нужно использовать body = not json =