有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java Spring RestTemplate映射JSON对映射的响应引发不匹配的PutException

我试图将Github的commit details API中的JSON解析为HashMap。我在测试中使用的示例Json是here

测试代码是

@SpringJUnitConfig(classes = {GithubApiService.class, RestTemplateConfiguration.class})
@EnableAutoConfiguration
public class GithubApiServiceTest {

    @Test
    public void testGithubResponseJsonToMapConversion(
            @Autowired RestTemplate restTemplate,
            @Autowired GithubApiService service,
            @Value("classpath:github/commit-payload.json") Resource commitPayloadFile) throws IOException {

        final String COMMITS_URL = "https://api.github.com/repos/Codertocat/Hello-World/commits/sha";

        //Stub response from Github Server
        String responseJson = new ObjectMapper().writeValueAsString(
                new String(Files.readAllBytes(Paths.get(commitPayloadFile.getFile().getAbsolutePath()))));
        MockRestServiceServer mockGithubServer = MockRestServiceServer.createServer(restTemplate);
        mockGithubServer.expect(requestTo(COMMITS_URL))
                .andRespond(withSuccess().contentType(APPLICATION_JSON).body(responseJson));

        //Call API Service
        Map<String, Object> result = service.getCommitDetails(COMMITS_URL);
        //Expect return type is hashmap
        assertThat(result.get("sha")).isEqualTo("6dcb09b5b57875f334f61aebed695e2e4193db5e");
    }
}

服务代码是

@Service
@AllArgsConstructor(onConstructor = @__(@Autowired))
public class GithubApiService {

    @Autowired
    private final RestTemplate restTemplate;

    public Map<String, Object> getCommitDetails(String commitsUrl) {
        ParameterizedTypeReference<Map<String, Object>> responseType = new ParameterizedTypeReference<Map<String, Object>>() {
        };
        RequestEntity<Void> request = RequestEntity.get(URI.create(commitsUrl)).accept(APPLICATION_JSON).build();
        return restTemplate.exchange(request, responseType).getBody();
    }
}

这无法将JSON响应转换为Map,出现以下错误(full log here

Caused by: 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 ('{
  "url": "https://api.github.com/repos/octocat/Hello-World/commits/6dcb09b5b57875f334f61aebed695e2e4193db5e",
  "sha": "6dcb09b5b57875f334f61aebed695e2e4193db5e",
  "node_id": "MDY6Q29tbWl0NmRjYjA5YjViNTc4NzVmMzM0ZjYxYWViZWQ2OTVlMmU0MTkzZGI1ZQ==",
  "html_url": "https://github.com/octocat/Hello-World/commit/6dcb09b5b57875f334f61aebed695e2e4193db5e",
  "comments_url": "https://api.github.com/repos/octocat/Hello-World/commits/6dcb09b5b57875f334f61aebed695e2e4193db5e/comments",

由于我正在使用spring-boot-starter-web,它会自动连接转换器,包括MappingJackson2HttpMessageConverter,但调试器显示,尽管将内容类型设置为application/json,响应仍由ByteArrayHttpMessageConverter处理


共 (1) 个答案

  1. # 1 楼答案

    糟糕的是,我应该用@RestClientTest注释插入@EnableAutoConfiguration来解决这个问题

    @EnableAutoConfiguration是一个更通用的注释,它没有实现@RestClientTest所实现的所有自动配置