简体   繁体   中英

How to pass complex parameter to POST request using Apache HTTP client?

I attempt to send POST request with body like this

{
  "method": "getAreas",
  "methodProperties": {
      "prop1" : "value1",
      "prop2" : "value2",
   }
}

Here is my code

static final String HOST = "https://somehost.com";

  public String sendPost(String method,
      Map<String, String> methodProperties) throws ClientProtocolException, IOException {

    HttpPost post = new HttpPost(HOST);

    List<NameValuePair> urlParameters = new ArrayList<>();
    urlParameters.add(new BasicNameValuePair("method", method));

    List<NameValuePair> methodPropertiesList = methodProperties.entrySet().stream()
                .map(entry -> new BasicNameValuePair(entry.getKey(), entry.getValue()))
                .collect(Collectors.toList());

    // ??? urlParameters.add(new BasicNameValuePair("methodProperties", methodPropertiesList));

    post.setEntity(new UrlEncodedFormEntity(urlParameters));

    try (CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpResponse response = httpClient.execute(post)) {

      return EntityUtils.toString(response.getEntity());
    }
  }

But constructor of BasicNameValuePair applies (String, String) . So I need another class instead.

Is there any way to add methodPropertiesList to urlParameters ?

your request looking like a json structure so post data like below:

 class pojo1{
   String method;
   Map<String,String> methodProperties;
 }

String postUrl = "www.site.com";// put in your url
Gson gson = new Gson();
HttpClient httpClient = HttpClientBuilder.create().build();
HttpPost post = new HttpPost(postUrl);
StringEntity postingString = new StringEntity(gson.toJson(pojo1));//gson.tojson()    converts your pojo to json
post.setEntity(postingString);
post.setHeader("Content-type", "application/json");
HttpResponse  response = httpClient.execute(post);

ref: HTTP POST using JSON in Java

There is a well known approach to this problem. In most cases you will create your own object describing the thing that you want to send in the HttpPost. So you will have something like:

static final String HOST = "https://somehost.com";

  public String sendPost(String method,
      Map<String, String> methodProperties) throws ClientProtocolException, IOException {

    HttpPost post = new HttpPost(HOST);
    MyResource resource = new MyResource();
    resource.setMethod(method);
    MyNestedResource nestedResource = new MyNestedResource();
    nestedResource.setMethodProperties(methodProperties);
    resource.setNestedResourceMethodProperties(nestedResource);

    StringEntity strEntity = new StringEntity(gson.toJson(resource));
    post.setEntity(strEntity);

    try (CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpResponse response = httpClient.execute(post)) {

      return EntityUtils.toString(response.getEntity());
    }
  }

And that is usually how you approach more complext json objects with a nested structure. You have to create classes for the resources you want to send (in your example it may be one class and to use map in it, but usually you create a class for the nested object too if it has a specific structure). To get more familiar with the whole picture better cover this tutorial: https://www.baeldung.com/jackson-mapping-dynamic-object

Using Sushil Mittal answer here is my solution

static final String HOST = "https://somehost.com";

  public String sendPost(String method, Map<String, String> methodProperties) throws ClientProtocolException, IOException {

    HttpPost post = new HttpPost(HOST);  
    Gson gson = new Gson();

    Params params = new Params(method, methodProperties);
    StringEntity entity = new StringEntity(gson.toJson(params));   
    post.setEntity(entity);

    try (CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpResponse response = httpClient.execute(post)) {

      return EntityUtils.toString(response.getEntity());
    }
  }

  class Params {

    String method;   
    Map<String, String> methodProperties;

    public Params(String method, Map<String, String> methodProperties) {
      this.method = method;
      this.methodProperties = methodProperties;
    }

    //getters
  }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM