多部分标题似乎被忽略

时间:2019-10-07 12:52:16

标签: groovy header multipartform-data

我有以下代码,应该将POST请求发送到某些服务并基本上发布文件。

此请求为multipart/form-data。它包括:

  • JSON
  • Base64文件

代码如下:

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])
          }
  }
}

但是,每当我发送请求时,似乎都会丢失或未指定某些标头:

The generated request's body

但是“完美”的请求看起来像这样:

The perfect request

现在我们可以得出以下JSON标头的结论:

    缺少
  • Content-Type(用于JSON)(尽管您可以看到第一部分(即json)属于ContentType.APPLICATION_JSON
  • charset不会自动指定
  • Content-Transfer-Encoding不会自动指定

从base64开始:

  • Content-Transfer-Encoding不会自动指定

因此,我有2个问题:

  • 为什么我实际上设置了JSON的标头Content-Type
  • 如何指定根本不存在的标题?

预先感谢

1 个答案:

答案 0 :(得分:0)

  

为什么我实际上设置了JSON的标题Content-Type,却没有它?

因为您使用的是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--