Spring控制器无法解析从HttpClient发送的JSON(无法构造'java.util.LinkedHashMap'的示例)

iszxjhcz  于 2022-11-19  发布在  Spring
关注(0)|答案(1)|浏览(198)

我正在尝试将JSON对象发送到Spring控制器,控制器将请求主体作为Map<String, Object>接收,JSON本身是正确的,通过 Postman 发送相同的JSON也工作正常,只是当我使用HttpClient发送它时。
下面是我尝试发送的JSON:

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

我的HTTP请求:

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());

我的控制器:

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

我得到这个错误:

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]]

我试着用 Postman 发送同样的请求,它工作得很好,创建一个变量字符串并发送过来也工作得很好,关于请求,我做错了什么?

编辑

客户端来自java.net.http.HttpClient软件包。
我使用HttpClient.newHttpClient()创建了客户端
我使用的是Sping Boot Starter Web 2.7.5。

编辑2

根据这个答案,我尝试将输入的JSON字符串转换为Map,然后将Map转换回JSON字符串并发送,这样就成功了。

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());
brc7rcf0

brc7rcf01#

我尝试了以下代码与Spring Boot 2.7.5,Java 17。驱动程序代码发送请求。

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());

剩下的控制器和你在问题中提到的一样。如果我用Map.of()示例化Map,它仍然工作得很好。最后的sysout语句输出到控制台如下。

相关问题