code: private static void formpostmultipart(
              Bootstrap bootstrap, String host, int port, URI uriFile, HttpDataFactory factory,
              Iterable<Entry<String, String>> headers, List<InterfaceHttpData> bodylist) throws Exception {
          // XXX /formpostmultipart
          // Start the connection attempt.
          ChannelFuture future = bootstrap.connect(SocketUtils.socketAddress(host, port));
          // Wait until the connection attempt succeeds or fails.
          Channel channel = future.sync().channel();
  
          // Prepare the HTTP request.
          HttpRequest request = new DefaultHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.POST, uriFile.toASCIIString());
  
          // Use the PostBody encoder
          HttpPostRequestEncoder bodyRequestEncoder =
                  new HttpPostRequestEncoder(factory, request, true); // true => multipart
  
          // it is legal to add directly header or cookie into the request until finalize
          for (Entry<String, String> entry : headers) {
              request.headers().set(entry.getKey(), entry.getValue());
          }
  
          // add Form attribute from previous request in formpost()
          bodyRequestEncoder.setBodyHttpDatas(bodylist);
  
          // finalize request
          bodyRequestEncoder.finalizeRequest();
  
          // send request
          channel.write(request);
  
          // test if request was chunked and if so, finish the write
          if (bodyRequestEncoder.isChunked()) {
              channel.write(bodyRequestEncoder);
          }
          channel.flush();
  
          // Now no more use of file representation (and list of HttpData)
          bodyRequestEncoder.cleanFiles();
  
          // Wait for the server to close the connection.
          channel.closeFuture().sync();
      }
docs: Multipart example