Jenkins流水线脚本REST POST请求报415媒体类型错误,如何修复?
问题
我尝试在Jenkins流水线脚本中发送REST POST请求,代码如下:
def data = [ 'markdown': params.message, 'roomId': params.roomid ] echo "Webex data: ${data}" def response = httpRequest url: 'https://api.foo.com/v1/messages', httpMode: 'POST', requestBody: data.toMapString(), validResponseCodes: '200,400,401,404,415', customHeaders: [ [name: 'Content-Type', value: "application/octet-stream;charset=UTF-8"], [name: 'Authorization', value: "Bearer ${params.token}"] ] println("Status: ${response.status}") println("Response: ${response.content}") println("Headers: ${response.headers}")
执行后返回415状态码,响应信息显示:
请求未指定媒体类型或使用了不支持的媒体类型,'application/octet-stream;charset=UTF-8'不在支持范围内。
响应详情如下:
Status: 415 Response: {"message":"The request was made to a resource without specifying a media type or used a media type that is not supported. 'application/octet-stream;charset=UTF-8' is not included.","errors":[{"description":"The request was made to a resource without specifying a media type or used a media type that is not supported. 'application/octet-stream;charset=UTF-8' is not included."}],"trackingId":"ROUTERGW_dc76a5ab-43cf-4add-8bd2-8fa0302c8836"} Headers: [Content-Length:[441], Content-Type:[application/json], Date:[Mon, 19 Aug 2024 11:57:23 GMT], Server:[istio-envoy], Trackingid:[ROUTERGW_dc76a5ab-43cf-4add-8bd2-8fa0302c8836, ROUTERGW_dc76a5ab-43cf-4add-8bd2-8fa0302c8836], Vary:[Origin], X-Content-Type-Options:[nosniff, nosniff], X-Envoy-Upstream-Service-Time:[11]]
但我用Python编写了逻辑类似的脚本却能正常运行,代码如下:
room_id = 'Y2lzY29zcGFyazovL3VzL1JPT00vNTI2YzFlOTAtYmViYi0xMWU5LTkzYWUtNTU1ZTE5YTM2NGQ2' message = '''I'm a lumberjack and I'm ok''' resp = requests.post( 'https://api.foo.com/v1/messages', data={ 'roomId': room_id, 'markdown': message, }, headers={'Authorization': f'Bearer {os.environ["TOKEN"]}'}, )
请问如何修复我的Jenkins脚本?
问题原因
Python的requests.post使用data参数时,会自动将字典格式的数据编码为**application/x-www-form-urlencoded**格式的表单数据,并且自动设置对应的Content-Type请求头,这符合目标接口的要求。
你的Jenkins脚本存在两个核心问题:
- 错误设置了
Content-Type为application/octet-stream,该媒体类型不被目标接口支持; - 使用
data.toMapString()生成的请求体格式不符合application/x-www-form-urlencoded的规范,导致接口无法解析。
修复方案
方案1:使用httpRequest的formData参数(推荐)
httpRequest插件支持直接传入formData参数,会自动处理表单编码和Content-Type的设置,无需手动处理:
def data = [ 'markdown': params.message, 'roomId': params.roomid ] echo "Webex data: ${data}" def response = httpRequest url: 'https://api.foo.com/v1/messages', httpMode: 'POST', formData: data, validResponseCodes: '200,400,401,404,415', customHeaders: [ [name: 'Authorization', value: "Bearer ${params.token}"] ] println("Status: ${response.status}") println("Response: ${response.content}") println("Headers: ${response.headers}")
方案2:手动编码请求体并设置正确的Content-Type
如果无法使用formData参数,可以手动将数据编码为url格式,并设置符合要求的请求头:
import java.net.URLEncoder def data = [ 'markdown': params.message, 'roomId': params.roomid ] // 手动编码为application/x-www-form-urlencoded格式 def requestBody = data.collect { k, v -> "${URLEncoder.encode(k, 'UTF-8')}=${URLEncoder.encode(v, 'UTF-8')}" }.join('&') echo "Webex data: ${data}" def response = httpRequest url: 'https://api.foo.com/v1/messages', httpMode: 'POST', requestBody: requestBody, validResponseCodes: '200,400,401,404,415', customHeaders: [ [name: 'Content-Type', value: "application/x-www-form-urlencoded;charset=UTF-8"], [name: 'Authorization', value: "Bearer ${params.token}"] ] println("Status: ${response.status}") println("Response: ${response.content}") println("Headers: ${response.headers}")
内容的提问来源于stack exchange,提问作者John
相关产品推荐
相关产品推荐

