我有以下代码,它应该向某个服务发送POST请求并基本上发布一个文件。
此请求multipart/form-data
。它包括:
- 杰伦
- 基数64文件
代码如下:
sendMultipartPost();
def sendMultipartPost()
{
def URLToGo = 'http://127.0.0.1:8080/sd/services/rest/find/';
def httpRequest = new HTTPBuilder(URLToGo);
def authToken = 'AR-JWT ' + 'TOKEN';
def headers = ['Authorization' : authToken, 'Content-Type' : 'multipart/form-data; boundary=W3NByNRZZYy4ALu6xeZzvWXU3NVmYUxoRB'];
httpRequest.setHeaders(headers);
def body = ["values":["Incident Number":'testSC',"Work Log Type":"General Information","Description":"File has been added TESTFile","z2AF Work Log01":'Test File title']];
httpRequest.request(Method.POST)
{
req ->
MultipartEntity multiPartContent = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE, 'W3NByNRZZYy4ALu6xeZzvWXU3NVmYUxoRB', Charset.forName("UTF-8"));
Gson gson = new Gson();
String jsonObj = gson.toJson(body);
multiPartContent.addPart('entry', new StringBody(jsonObj, ContentType.APPLICATION_JSON));
multiPartContent.addPart('attach-z2AF Work Log01', new ByteArrayBody(Base64.encodeBase64("let's createBase64 let's createBase64 let's createBase64 let's createBase64 let's createBase64".getBytes()), ContentType.APPLICATION_OCTET_STREAM, 'test file title'));
req.setEntity(multiPartContent);
response.success = { resp ->
if (resp.statusLine.statusCode == 200) {
// response handling
}
}
response.failure = { resp, json ->
result = groovy.json.JsonOutput.toJson(['state':resp.status])
}
}
}
但是,每当我发送请求时,似乎都会丢失或未指定某些标头:
生成的请求正文
但是"完美"请求如下所示:
完美的要求
现在我们可以得出结论,以下 JSON 标头:
- 缺少 JSON 的
Content-Type
(尽管您可以看到第一部分是 json,是ContentType.APPLICATION_JSON
( - 不自动指定
charset
- 未自动指定
Content-Transfer-Encoding
截至 base64:
- 未自动指定
Content-Transfer-Encoding
因此,我有两个问题:
- 为什么在我实际设置时没有 JSON 的标头
Content-Type
? - 如何指定根本不存在的标头?
提前致谢
为什么在我实际设置时没有 JSON 的标头内容类型?
因为您使用的是HttpMultipartMode.BROWSER_COMPATIBLE
模式。 删除它,您将获得content-type
标头。
如何指定根本不存在的标头?
此库中的唯一方法 - 使用FormBodyPart
包装任何正文并添加所需的标头。
这是一个可以在 groovyconsole 中运行的代码示例
@Grab(group='org.apache.httpcomponents', module='httpmime', version='4.5.10')
import org.apache.http.entity.mime.MultipartEntityBuilder
import org.apache.http.entity.ContentType
import org.apache.http.entity.mime.content.StringBody
//import org.apache.http.entity.mime.content.ByteArrayBody
import org.apache.http.entity.mime.FormBodyPartBuilder
//form part has ability to specify additional part headers
def form(Map m){
def p = FormBodyPartBuilder.create(m.remove('name'), m.remove('body'))
m.each{ k,v-> p.addField(k,v.toString()) } //all other keys assume to be headers
return p.build()
}
def json = '{"aaa":111,"bbb":222,"ccc":333}'
def multipart = MultipartEntityBuilder.create()
.addTextBody( "foo", 'bar' ) //transfer text with default encoding
.addTextBody( "theJson", json, ContentType.APPLICATION_JSON ) //text with content type
.addPart(form(
//add part with headers
name:'TheJsonWithHdrs',
body:new StringBody(json.getBytes("UTF-8").encodeBase64().toString(),ContentType.APPLICATION_JSON),
'Content-transfer-encoding':'base64',
))
.build()
//print result
def b = new ByteArrayOutputStream()
multipart.writeTo(b)
println b.toString("ASCII")
结果
--s89LGRZ8HCJ4Gimdis8AH2pXpUQyEpvalzB
Content-Disposition: form-data; name="foo"
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 8bit
bar
--s89LGRZ8HCJ4Gimdis8AH2pXpUQyEpvalzB
Content-Disposition: form-data; name="theJson"
Content-Type: application/json; charset=UTF-8
Content-Transfer-Encoding: 8bit
{"aaa":111,"bbb":222,"ccc":333}
--s89LGRZ8HCJ4Gimdis8AH2pXpUQyEpvalzB
Content-transfer-encoding: base64
Content-Disposition: form-data; name="TheJsonWithHdrs"
Content-Type: application/json; charset=UTF-8
eyJhYWEiOjExMSwiYmJiIjoyMjIsImNjYyI6MzMzfQ==
--s89LGRZ8HCJ4Gimdis8AH2pXpUQyEpvalzB--