【问题标题】:Spring parsing JSON RequestBody: "Could not resolve type id" or "Root name does not match expected"Spring 解析 JSON RequestBody:\"Could not resolve type id\" or \"Root name does not match expected\"
【发布时间】:2022-12-05 21:21:56
【问题描述】:

我正在用 Spring 构建一个 REST API;好吧,目前我没有这样做。

长话短说

我得到了这个(错误 1)

JSON 解析错误:无法将类型 ID“test1”解析为 crm.zappes.core.template.domain.model.TemplateRequest 的子类型:已知类型 ID = [TemplateRequest]

或者这个(错误 2)

JSON 解析错误:根名称 ('test1') 与类型 crm.zappes.core.template.domain.model.TemplateRequest 的预期 ('TemplateRequest') 不匹配

模型

我使用 @JsonTypeInfo 将类名包裹起来;这会导致错误 1。

{"TemplateRequest":{"test1":"Anakin","test2":"Skywalker"}}

如果我在没有此注释的情况下使用默认值,则生成的 JSON 没有包装根元素,这会导致错误 2:

{"test1":"Anakin","test2":"Skywalker"}
@Data @Builder @NoArgsConstructor @AllArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
// With this I get error 1, without it error 2
@JsonTypeInfo(include = JsonTypeInfo.As.WRAPPER_OBJECT, use = JsonTypeInfo.Id.NAME)
public class TemplateRequest {
    private String test1;
    private String test2;
}

控制器

在此控制器端点中,我希望将 JSON 转换为 TemplateRequest 模型对象。

@RestController
@RequestMapping("/zappes/")
public class TemplateController {
    @PostMapping(value = "/template/test", consumes = {MediaType.APPLICATION_JSON_VALUE})
    public ResponseEntity<String> testPost(@RequestBody TemplateRequest request) {
        return ResponseEntity.ok("Hello World");
    }
}

如果我将它更改为 @RequestBody String request,它工作正常,我看到 2 个 JSON 变体(见上文),因此端点映射本身有效。 Spring 无法将 JSON 解析为模型对象。这有点奇怪,因为 JSON 也是由 Spring REST 框架生成的。请参阅下一节。

测试

在这里,我将 POST 调用发送到控制器。

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
class TemplateControllerIntegrationTests {
    @Test
    void testPost() {
        HttpHeaders headers = new HttpHeaders();
        headers.setBasicAuth("server_user", "server_password");

        var request = TemplateRequest.builder().test1("Anakin").test2("Skywalker").build();

        var requestEntity = new HttpEntity<>(request, headers);

        var restTemplate = new RestTemplate();
        var result = restTemplate.exchange("http://localhost:8083/zappes/template/test", HttpMethod.POST, requestEntity, String.class);

        Assertions.assertEquals("Hallo Welt", result.getBody());
    }
}

【问题讨论】:

    标签: java spring rest spring-rest


    【解决方案1】:

    显然没有默认的 JSON 转换器,我需要创建一个小配置类:

    @Bean
    public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() {
        var jsonConverter = new MappingJackson2HttpMessageConverter();
        var objectMapper = new ObjectMapper();
        jsonConverter.setObjectMapper(objectMapper);
        return jsonConverter;
    }
    

    【讨论】:

      猜你喜欢
      • 2022-08-18
      • 2015-08-03
      • 1970-01-01
      • 2022-12-24
      • 1970-01-01
      • 1970-01-01
      • 2022-12-01
      • 2016-08-23
      相关资源
      最近更新 更多