title: Java 9 HttpClient send a multipart/form-data request
body: <p>Below is a form:</p>
  
  <pre><code>&lt;form action="/example/html5/demo_form.asp" method="post" 
  enctype=”multipart/form-data”&gt;
     &lt;input type="file" name="img" /&gt;
     &lt;input type="text" name=username" value="foo"/&gt;
     &lt;input type="submit" /&gt;
  &lt;/form&gt;
  </code></pre>
  
  <p>when will submit this form, the request will look like this:</p>
  
  <pre><code>POST /example/html5/demo_form.asp HTTP/1.1
  Host: 10.143.47.59:9093
  Connection: keep-alive
  Content-Length: 326
  Accept: application/json, text/javascript, */*; q=0.01
  Origin: http://10.143.47.59:9093
  X-Requested-With: XMLHttpRequest
  User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36
  Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryEDKBhMZFowP9Leno
  Accept-Encoding: gzip, deflate
  Accept-Language: en-US,en;q=0.8,zh-CN;q=0.6,zh;q=0.4
  
  Request Payload
  ------WebKitFormBoundaryEDKBhMZFowP9Leno
  Content-Disposition: form-data; name="username"
  
  foo
  ------WebKitFormBoundaryEDKBhMZFowP9Leno
  Content-Disposition: form-data; name="img"; filename="out.txt"
  Content-Type: text/plain
  
  
  ------WebKitFormBoundaryEDKBhMZFowP9Leno--
  </code></pre>
  
  <p>please pay attention to the "Request Payload", you can see the two params in the form, the username and the img(form-data; name="img"; filename="out.txt"), and the finename is the real file name(or path) in your filesystem, you will receive the file by name(not filename) in your backend(such as spring controller).<br>
  if we use Apache Httpclient to simulate the request, we will write such code:</p>
  
  <pre><code>MultipartEntity mutiEntity = newMultipartEntity();
  File file = new File("/path/to/your/file");
  mutiEntity.addPart("username",new StringBody("foo", Charset.forName("utf-8")));
  mutiEntity.addPart("img", newFileBody(file)); //img is name, file is path
  </code></pre>
  
  <p>But in java 9, We could write such code:</p>
  
  <pre><code>HttpClient client = HttpClient.newHttpClient();
  HttpRequest request = HttpRequest.
          newBuilder(new URI("http:///example/html5/demo_form.asp"))
         .method("post",HttpRequest.BodyProcessor.fromString("foo"))
         .method("post", HttpRequest.BodyProcessor.fromFile(Paths.get("/path/to/your/file")))
         .build();
  HttpResponse response = client.send(request, HttpResponse.BodyHandler.asString());
  System.out.println(response.body());
  </code></pre>
  
  <p>Now you see, how could I set the "name" of the param?</p>