将含multipart文件上传的curl转为原生Groovy请求报415如何解决
问题根因
- 415状态码由错误的请求Content-Type导致:你当前代码设置的是
application/json,但curl中-F参数对应的是multipart/form-data类型的多部件表单提交 - 缺失多部件表单的文件上传逻辑,两个JSON文件未按表单格式写入请求体
原生Groovy实现代码(无第三方依赖)
String strBaseURL = 'https://jstg.XXXXXXX.com/' String strUserName = 'myuser' //TODO set password before testing String strUserPwd = 'fakepassword' String strInfoFile = 'C:\\temp\\JSON\\executionInfo_Pretty.json' String strExecResultsFile = 'C:\\temp\\JSON\\execResults_pretty.json' String strAPIPath = 'rest/raven/1.0/import/execution/multipart' String strAuthType = 'Basic' // 生成multipart边界标识 String boundary = "----WebKitFormBoundary${new Random().nextInt(999999999)}" String lineBreak = '\r\n' String authString = "${strUserName}:${strUserPwd}".getBytes().encodeBase64().toString() URL url = new URL("${strBaseURL}${strAPIPath}") HttpURLConnection conXray = (HttpURLConnection) url.openConnection() conXray.with { requestMethod = 'POST' connectTimeout = 10000 readTimeout = 30000 doOutput = true doInput = true // 修正Content-Type为multipart表单类型 setRequestProperty('Authorization', "${strAuthType} ${authString}") setRequestProperty('Content-Type', "multipart/form-data; boundary=${boundary}") } // 写入请求体 conXray.outputStream.with { out -> // 写入第一个文件:info字段 out.write("--${boundary}${lineBreak}".bytes) out.write("Content-Disposition: form-data; name=\"info\"; filename=\"${new File(strInfoFile).name}\"${lineBreak}".bytes) out.write("Content-Type: application/json${lineBreak}${lineBreak}".bytes) out.write(new File(strInfoFile).bytes) out.write(lineBreak.bytes) // 写入第二个文件:result字段 out.write("--${boundary}${lineBreak}".bytes) out.write("Content-Disposition: form-data; name=\"result\"; filename=\"${new File(strExecResultsFile).name}\"${lineBreak}".bytes) out.write("Content-Type: application/json${lineBreak}${lineBreak}".bytes) out.write(new File(strExecResultsFile).bytes) out.write(lineBreak.bytes) // 写入multipart结束标记 out.write("--${boundary}--${lineBreak}".bytes) out.flush() } // 读取响应结果 def responseCode = conXray.responseCode def responseText if (responseCode >= 200 && responseCode < 300) { responseText = conXray.inputStream.getText('UTF-8') } else { responseText = conXray.errorStream?.getText('UTF-8') ?: '无错误信息' } conXray.disconnect() // 输出结果 println "响应状态码:${responseCode}" println "响应内容:${responseText}"
关键说明
- 边界字符串
boundary用来分隔表单中的不同字段,值可以自定义,只要和请求体内容不冲突即可 - 两个表单字段名
info和result和curl命令中的-F参数的键完全对应,不能写错 - Groovy自带的
with、withStream语法糖会自动关闭流,无需手动处理资源释放
内容的提问来源于stack exchange,提问作者PGK
相关产品推荐
相关产品推荐

