使用Python的requests库发送SOAP请求,错误码415

使用Python的requests库发送SOAP请求,错误码415

1. 背景

这个项目之前是采用的Python的requests库以POST的方式向服务器传送json字符串的形式,这次由于合作方的变化,要采用web services的形式,按照SOAP协议,传送XML格式的数据到服务端。

本着少改动的原则,决定继续使用Python的requests库,将原来的json字符串拼成XML格式,再发送给服务端。

在改动的过程中,遇到了一些问题,并逐个进行了解决。下面是详细的过程。

2. tomcat启动问题

  1. 首先有个服务端,合作方已经部署在了tomcat上,并把压缩包发了过来;第一步肯定是先运行tomcat;
  2. 运行tomcat后,localhost:8080显示tomcat已经启动,但是服务的域名localhost:8080/TPService/TPServicePort?wsdl却显示404,如图所示:在这里插入图片描述
  3. 然后发现运行起来的tomcat是9.0版本,而合作方发来的tomcat是7.0版本;
  4. 使用的是windows电脑,将环境变量中的CATALINA_HOME的值改为7.0版本的tomcat文件夹路径,即可启动7.0版本的tomcat,并能够成功访问localhost:8080/TPService/TPServicePort?wsdl在这里插入图片描述

3. 报415错误

  1. 首先并不急于将完整的数据发送给服务端,而是仅仅想把与服务端的连接成功建立。此时的代码大概如下:

    import requests
    url = 'http://localhost:8080/TPService/TPServicePort?wsdl'
    payload = {'a':'test'}
    response = requests.post(url, json=payload, timeout=5)
    
  2. 此时会报415错误;到服务端查看,发现如下报错信息:

    Unsupported Content-Type: application/json Supported ones are: [text/xml]
    com.sun.xml.ws.server.UnsupportedMediaException: Unsupported Content-Type: application/json Supported ones are: [text/xml]
    
  3. 按照提示,增加headers,将content-type的值设置为text/xml,此时代码如下:

    import requests
    from requests.structures import CaseInsensitiveDict
    
    url = 'http://localhost:8080/TPService/TPServicePort?wsdl'
    headers = CaseInsensitiveDict()
    headers['Content-Type'] = 'text/xml'
    payload = {'a': 'b'}
    response = requests.post(url, headers=headers, json=payload, timeout=5)
    print(response.status_code)
    
  4. 此时报500错误,说明通信连接已经建立了;

4. 按照SOAP格式拼装xml

  1. 一开始拼接的xml如下:

    <?xml version ="1.0" encoding="UTF-8"?>
    <S:Envelope xmlns:S='http://schemas.xmlsoap.org/soap/envelope/'>
    	<S:Body>
    		<n:uploadTestData xmlns:n="http://localhost:8080/TPService/TPServicePort?wsdl">
    			<a>test</a>
    		</n:uploadTestData>
    	</S:Body>
    </S:Envelope>
    
  2. 此时代码大概如下:

    import requests
    from requests.structures import CaseInsensitiveDict
    
    url = 'http://localhost:8080/TPService/TPServicePort?wsdl'
    headers = CaseInsensitiveDict()
    headers['Content-Type'] = 'text/xml'
    payload = ‘’‘
    <?xml version ="1.0" encoding="UTF-8"?>
    <S:Envelope xmlns:S='http://schemas.xmlsoap.org/soap/envelope/'>
    	<S:Body>
    		<n:uploadTestData xmlns:n="http://localhost:8080/TPService/TPServicePort?wsdl">
    			<a>test</a>
    		</n:uploadTestData>
    	</S:Body>
    </S:Envelope>
    ’‘’
    response = requests.post(url, headers=headers, data=payload, timeout=5)
    print(response.status_code)
    
  3. 然后这时会报错500如下:

    Couldn't create SOAP message due to exception: XML reader error: javax.xml.stream.XMLStreamException: ParseError at [row,col]:[2,14]
    Message: The processing instruction target matching "[xX][mM][lL]" is not allowed.
    com.sun.xml.ws.protocol.soap.MessageCreationException: Couldn't create SOAP message due to exception: XML reader error: javax.xml.stream.XMLStreamException: ParseError at [row,col]:[2,14]
    
  4. 按照提示,找到[2, 14]的位置,发现是xml version这里,去掉两个单词之间的空格,再次请求,报错500,但是服务端没有信息显示。

  5. 发现是请求地址写错了,请求地址应与localhost:8080/TPService/TPServicePort?wsdl中的namespace保持一致。将代码修改为:

    import requests
    from requests.structures import CaseInsensitiveDict
    
    url = 'http://localhost:8080/TPService/TPServicePort?wsdl'
    headers = CaseInsensitiveDict()
    headers['Content-Type'] = 'text/xml'
    payload = ‘’‘
    <?xml version ="1.0" encoding="UTF-8"?>
    <S:Envelope xmlns:S='http://schemas.xmlsoap.org/soap/envelope/'>
    	<S:Body>
    		<n:uploadTestData xmlns:n="http://www.xxxx.com">
    			<a>test</a>
    		</n:uploadTestData>
    	</S:Body>
    </S:Envelope>
    ’‘’
    response = requests.post(url, headers=headers, data=payload, timeout=5)
    print(response.status_code)
    
  6. 再次发起请求,返回结果如下:

    <?xml version="1.0" ?>
    <S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
    	<S:Body>
    		<ns2:uploadTestDataResponse xmlns:ns2="http://www.glorysoft.com">
    			<return>														{&quot;responseDate&quot;:&quot;20210420114103554&quot;,&quot;resultCode&quot;:&quot;OK&quot;,&quot;resultMessage&quot;:&quot;success&quot;}
    			</return>
         </ns2:uploadTestDataResponse>
       </S:Body>
     </S:Envelope>
    

    说明成功进行了通信。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
使用 Python 中的 `requests` 构造 SOAP 请求,你需要创建一个包含 SOAP 消息的字符串,并将其作为请求的正文发送。下面是一个示例: ```python import requests # 构造 SOAP 请求消息 soap_message = ''' <soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:example="http://www.example.com/"> <soap:Header/> <soap:Body> <example:SomeRequest> <example:Parameter1>Value1</example:Parameter1> <example:Parameter2>Value2</example:Parameter2> </example:SomeRequest> </soap:Body> </soap:Envelope> ''' # 设置请求头和请求正文 headers = { 'Content-Type': 'application/soap+xml', 'charset': 'UTF-8', 'SOAPAction': 'http://www.example.com/SomeAction' } # 发送 SOAP 请求 response = requests.post('http://www.example.com/soap-endpoint', headers=headers, data=soap_message) # 处理响应 if response.status_code == 200: # 解析响应内容 response_data = response.content # 处理响应数据 # ... else: print('SOAP 请求失败:', response.status_code, response.reason) ``` 在上面的示例中,`soap_message` 变量包含了构造的 SOAP 请求消息。你需要根据你的具体 SOAP 消息格式进行修改。 然后,我们设置了请求头 `Content-Type` 为 `application/soap+xml`,并指定了 `SOAPAction` 的值。根据具体的 SOAP 服务,你可能需要调整这些值。 最后,我们使用 `requests.post` 方法发送SOAP 请求,并处理了响应。 请注意,这只是一个简单的示例,实际情况可能会更复杂。你可能需要根据具体的 SOAP 服务和消息格式进行适当的调整。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Kuo-Teng

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值