HTTP POST sends JSON format data (solves the Expect:100-continue problem)

A project under development recently needs to involve the use of Http requests to send relatively large data. After researching for a long time, encountering problems and solving them, I will share them with you here.

1. Due to the large amount of data, POST is used to transmit data (POST theoretically does not limit the data size, but different servers will have corresponding default settings to limit the data size)

2. Due to project needs, use data in JSON format

Code example:

JAVA version, use Apache's commons-httpClient package to send http requests, the code is for reference only, the method of sending requests can be modified according to your needs

copy code
import org.apache.commons.httpclient.*;
//使用apache commons httpclient
private static final String APPLICATION_JSON = "application/json;charset=uft-8"; 
private static final String CONTENT_TYPE_TEXT_JSON = "text/json";
 
/**
* Send json using http Post
* @param url
* @param json Choose your favorite Json package to format the data
* @throws Exception
 */ 
public  static  void httpPostWithJSON(String url, String json) throws Exception {
  // Encode JSON in UTF-8 to transmit Chinese 
  String encoderJson = URLEncoder.encode(json, "UTF-8" );
   
  HttpClient httpclient = new HttpClient();
  PostMethod method = new PostMethod(url);
  RequestEntity requestEntity = new StringRequestEntity(encoderJson);
  method.setRequestEntity(requestEntity);
  method.addRequestHeader("Content-Type",APPLICATION_JSON);
  int result = httpclient.executeMethod(method);
 
  System.out.println( "Response status code: " + result);
  System.out.println( "Response body: " );
  System.out.println(method.getResponseBodyAsString());
  method.releaseConnection();
}
copy code

 

 

For PHP version, use curl. Note here: curl uses POST to send a request. When the data is larger than 1024 bytes, it will automatically add Expect:100-continue to the request header, causing the request to hang and no response from the destination server.

Solution: Before sending the request, manually set Expect: empty in the request header to cancel Expect: 100-continue The following is a code example:

copy code
<?php
/**
 * PHP sends Json object data
 *
 * @param $url request url
 * @param $jsonStr sent json string
 * @return array
 */
function http_post_json($url, $jsonStr)
{
  $ch = curl_init();
  curl_setopt($ch, CURLOPT_POST, 1);
  curl_setopt($ch, CURLOPT_URL, $url);
  curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonStr);
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  curl_setopt($ch, CURLOPT_HTTPHEADER, array(
      'Content-Type: application/json; charset=utf-8',
      'Content-Length: ' . strlen($jsonStr),
    'Expect:'
    )
  );
  $response = curl_exec($ch);
  $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
  return array($httpCode, $response);
}

$arr = array(
        'service' => 's_scenic_info',
        'count' => 10 ,
        'batchNo' => 'JQ201609011230590001',
        'flag' => '11111',
        'data' => array(
            array(
                'displayName' => '15980851200',
                'authenTicket' => '8b11d343d766d4af88d6b8746ec4e786',
                'authenUserId' => '1120d8d6ea4a4850b65d0faa40d6dffb',
                'timestamp' => '20151009195525'
            ),
            array(
                'displayName' => '15980851200',
                'authenTicket' => '8b11d343d766d4af88d6b8746ec4e786',
                'authenUserId' =>'1120d8d6ea4a4850b65d0faa40d6dffb',
                'timestamp' => '20151009195525'
            )
        )
    );

$url = "http://wangming.hk1.ngrok.cc/tmdata/Dispatcher.do";
$jsonStr = json_encode($arr);
echo($jsonStr);
list($returnCode, $returnContent) = http_post_json($url, $jsonStr);
echo($returnContent)
?>
copy code

 

Expect:100-continue 

When using libcurl's POST method, if the size of the POST data is greater than 1024 bytes, libcurl will not send the POST request directly, but will execute the request in two steps:

1. Send a request, the request header contains an Expect: 100-continue field, which is used to ask the server whether it is willing to accept data

2. After receiving the 100-continue response from the server, it will actually initiate a POST request and send the data to the server.

 

For the "100-continue" field, the RFC document (http://www.w3.org/Protocols/rfc2616/rfc2616-sec8.html#sec8.2.3) explains this: it allows the client to send request data Before to determine whether the server is willing to receive the data, if the server is willing to receive, the client will actually send the data, the reason for this is that if the client directly sends the request data, but the server rejects the request, this behavior will bring to a large resource overhead. So in order to avoid this situation, libcurl uses this method when sending POST requests larger than 1024 bytes, but relatively, it will increase the request delay, and not all servers will correctly process and respond "100" -continue", such as lighttpd, will return 417 "Expectation Failed", causing an error in the request logic.

If you are sure that the server will not reject POST requests with more than 1024 bytes, you can leave this method out and avoid the two side effects mentioned above

refer to:

http://www.laruence.com/2011/01/20/1840.html

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324735134&siteId=291194637