Заголовки из нескольких частей, похоже, игнорируются - PullRequest
0 голосов
/ 07 октября 2019

У меня есть следующий код, который должен отправить 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])
          }
  }
}

Однако всякий раз, когда яотправить запрос, кажется, что некоторые заголовки пропущены или не указаны:

Тело сгенерированного запроса

Но «идеальный» запрос выглядит так:

Идеальный запрос

Теперь мы можем заключить, что следующие заголовки JSON:

  • Content-Type для JSON отсутствуют (хотя вы можете видеть,что первая часть, которая является json, имеет ContentType.APPLICATION_JSON)
  • charset, не указывается автоматически
  • Content-Transfer-Encoding не указывается автоматически

По состоянию на base64:

  • Content-Transfer-Encoding не указывается автоматически

Следовательно, у меня есть 2 вопроса:

  • Почему заголовок Content-Type JSON отсутствует, хотя я на самом деле его установил?
  • Как указать заголовки, которых вообще нет?

Заранее спасибо

1 Ответ

0 голосов
/ 08 октября 2019

Почему отсутствует заголовок 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")

results

--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--
...