Home > Software engineering >  Spring controller cannot parse JSON sent from HttpClient (Cannot construct instance of `java.util.Li
Spring controller cannot parse JSON sent from HttpClient (Cannot construct instance of `java.util.Li

Time:11-14

I am trying to send a JSON object to a Spring controller, the controller takes in a request body as a Map<String, Object>, the JSON itself is correct and sending the same JSON over postman works properly as well, it's just when I send it using the HttpClient.

Here is the JSON I am trying to send over:

{"fruit": "Apple", "color": "Red"}

My HTTP request:

ObjectMapper mapper = new ObjectMapper();
mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
String jsonString = mapper.writeValueAsString(body);

HttpRequest request = HttpRequest.newBuilder()
    .uri(new URI(url))
    .header("content-type", "application/json")
    .POST(BodyPublishers.ofString(jsonString))
    .build();
HttpResponse<String> response = client.send(request, BodyHandlers.ofString());

My controller:

@PostMapping(value = "/config/addDocument", consumes = {"application/json"})
public void addDocument(@RequestBody Map<String, Object> document)

I get this error:

HttpMessageNotReadableException: JSON parse error: Cannot construct instance of `java.util.LinkedHashMap` (although at least one Creator exists): no String-argument constructor/factory method to deserialize from String value ('{"fruit": "Apple", "color": "Red"}'); nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of `java.util.LinkedHashMap` (although at least one Creator exists): no String-argument constructor/factory method to deserialize from String value ('{"fruit": "Apple", "color": "Red"}')<EOL> at [Source: (org.springframework.util.StreamUtils$NonClosingInputStream); line: 1, column: 1]]

I tried to use postman to send the same request and it works fine, creating a variable string and sending that over works fine as well, what am I doing wrong regarding the request?

Edit

The client is from the java.net.http.HttpClient package.

I created the client using HttpClient.newHttpClient()

I am using the Spring Boot Starter Web 2.7.5.

Edit 2

Based on the answer I tried switching the input JSON string into a map and converting the map back to a JSON string and sending that and that worked.

      ObjectMapper mapper = new ObjectMapper();
      Map<String, Object> map = mapper.readValue(body, Map.class);
      String jsonString = mapper.writeValueAsString(map);

      HttpRequest request = HttpRequest.newBuilder()
          .uri(new URI(url))
          .header("content-type", "application/json")
          .POST(HttpRequest.BodyPublishers.ofString(jsonString))
          .build();
      HttpResponse<String> response = client.send(request, BodyHandlers.ofString());

CodePudding user response:

I tried below code with Spring Boot 2.7.5, Java 17. Driver Code for sending request.

Map<String, String> body = new LinkedHashMap<>(); //new HashMap() is also fine here
body.put("fruit", "Apple");
body.put("color", "Red");
//Map.of("fruit", "Apple", "color", "Red");
ObjectMapper mapper = new ObjectMapper();
mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
String jsonString = mapper.writeValueAsString(body);

HttpClient client = HttpClient.newHttpClient();

HttpRequest request = HttpRequest.newBuilder()
                     .uri(new URI("http://localhost:8080/test"))
                     .header("content-type", "application/json")
                     .POST(HttpRequest.BodyPublishers.ofString(jsonString))
                     .build();
HttpResponse<String> response = client.send(request, 
                                     HttpResponse.BodyHandlers.ofString());
System.out.println("Status Code : "   response.statusCode());
System.out.println("Headers : "    response.headers());

The rest controller is same as you mentioned in the question. If I instantiate the map using Map.of() still its is working fine. The last sysout statements outputs to console as below.

enter image description here

  • Related