当前位置: 首页 > 知识库问答 >
问题:

spring测试rest模板:无法提取响应:未找到适合响应类型的HttpMessageConverter

苏涵润
2023-03-14

我得到这个例外

组织。springframework。网状物客户RestClientException:无法提取响应:未找到响应类型[AnalyticsResponse]和内容类型[application/json;charset=UTF-8]的合适HttpMessageConverter

仅在我的junit测试用例中(Restendpoint可以正常工作),如果我的DTO包含一个以用户定义的类作为键的映射

@Data
public class AnalyticsResponse {

    private List<Committer> commitersList; //OK
    private Map<Committer , Long> comittersCommitsMap; // Problem
    private Map<Date, List<CommitItem>> commitItemsTimeLineMap; //OK

}

如果删除comittersCommitsMap字段,一切都会正常进行

我的测试用例代码段:

ResponseEntity<AnalyticsResponse> analyticsResponse = testRestTemplate.getForEntity(ANALYSIS_CONTROLLER_BASE_URL+"analytics?repo-full-name=" + searchResponse.getBody().get(0).getFull_name() ,
                AnalyticsResponse.class); 

---更新:提交者类

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Committer {

    private  String name;
    private String email;

}

共有1个答案

叶英哲
2023-03-14

默认情况下,ObjectMapper不能确定Map的序列化和反序列化,其中不是String,您必须提供自定义实现。

提交者日期实现键反序列化器和JsonSerializer(作为Map的键)

配置ObjectMapper-使用键反序列化器和键序列化器(JsonSerializer)注册模块

@SpringBootApplication
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }

    // KeyDeserializer for Committer (simple without 'null' check)
    @RequiredArgsConstructor
    public static class CommitterKeyDeserializer extends KeyDeserializer {

        private final ObjectMapper mapper;

        @Override
        public Object deserializeKey(final String key,
                                     final DeserializationContext ctxt)
                throws IOException, JsonProcessingException {

            return mapper.readValue(key, Committer.class);
        }
    }

    // KeyDeserializer for Date (simple without 'null' check)
    @RequiredArgsConstructor
    public static class DateKeyDeserializer extends KeyDeserializer {

        private final ObjectMapper mapper;

        @Override
        public Object deserializeKey(final String key,
                                     final DeserializationContext ctxt)
                throws IOException, JsonProcessingException {

            return mapper.readValue(key, Date.class);
        }
    }

    // JsonSerializer for Committer (simple without 'null' check)
    @RequiredArgsConstructor
    public static class CommitterJsonSerializer extends JsonSerializer<Committer> {

        private final ObjectMapper mapper;

        @Override
        public void serialize(Committer committer,
                              JsonGenerator jgen,
                              SerializerProvider provider)
                throws IOException, JsonProcessingException {

            jgen.writeFieldName(mapper.writeValueAsString(committer));
        }

    }

    // JsonSerializer for Date (simple without 'null' check)
    public static class DateJsonSerializer extends JsonSerializer<Date> {

        @Override
        public void serialize(Date date,
                              JsonGenerator jgen,
                              SerializerProvider provider)
                throws IOException, JsonProcessingException {

            jgen.writeFieldName(String.valueOf(date.getTime()));
        }

    }

    // ObjectMapper configuration
    @Bean
    public ObjectMapper objectMapper() {
        ObjectMapper mapper = new ObjectMapper();

        // register module with custom serializers and deserializers
        mapper.registerModule(new SimpleModule()
                .addKeyDeserializer(
                        Committer.class,
                        new CommitterKeyDeserializer(mapper))
                .addKeyDeserializer(
                        Date.class,
                        new DateKeyDeserializer(mapper))
                .addKeySerializer(
                        Committer.class,
                        new CommitterJsonSerializer(mapper))
                .addKeySerializer(
                        Date.class,
                        new DateJsonSerializer()));

        return mapper;
    }

    // RestTemplate configuration
    @Bean
    public RestTemplate restTemplate(List<HttpMessageConverter<?>> converters) {
        RestTemplate restTemplate = new RestTemplate();
        // add spring's predefined converters
        restTemplate.setMessageConverters(converters);

        return restTemplate;
    }

}

请注意,在这个简单的实现中,comiterscommitsmap中的键Committer表示为JSON响应中的字符串(RestTemplate在这个实现中也起作用):

{
    "commitersList": [
        {
            "name": "name",
            "email": "email"
        }
    ],
    "comittersCommitsMap": {
        "{\"name\":\"name\",\"email\":\"email\"}": 1
    },
    "commitItemsTimeLineMap": {
        "1570929503854": [
            {
                "data": "data"
            }
        ]
    }
}
 类似资料:
  • 我是新的Spring集成和工作在Spring集成超文本传输协议模块为我的项目要求。我从出站网关作为超文本传输协议客户端发送请求。我试图向服务器发起一个请求,服务器应该用我的设置值返回消息负载。我正在将对象转换为JSON,用于发送到服务器我正在从客户端(HttpClientDemo)向服务器端的入站网关发送请求。为此,我将我的对象转换成JSON,然后将JSON字符串转换为客户端的对象,在那里执行一些

  • 我正在尝试使用spring for Android从REST服务中检索一些数据。但是我遇到了问题。我也在使用Robospice——因此有一种类似这样的方法: 不幸的是,这不起作用。我将引发以下异常: 现在,基于我的谷歌搜索,我觉得我需要添加一个消息转换器。我只是不确定我需要哪个消息转换器,或者在哪里添加它?

  • 我试图让一个Spring CloudNetflixFaignes客户端通过HTTP获取一点JSON并将其转换为对象。我一直得到这个错误,而不是: 组织。springframework。网状物客户RestClientException:无法提取响应:未找到响应类型[class io.urig.checkout.Book]和内容类型[application/json;charset=UTF-8]的合适

  • 我有以下几点建议: 当我对它执行cucumber测试时,我得到以下异常: 我有一些其他的测试和其他具有相同注释的POJO,它们工作起来没有任何问题。我真的一点也不知道出了什么问题。 感谢任何建议!

  • 我正在写一个Springmvc应用程序(Spring新手),它必须调用Rest服务。我有其余的服务部署在我的VM(weblogic 10.3.6在Linux)和我写的应用程序是在我的本地笔记本电脑weblogic(10.3.6在Windows 8.1)。 当我尝试调用rest服务时,restservice应用程序的请求正常,但响应失败,并显示以下消息 我正在初始化控制器中的其余客户端 在实际的客户

  • 当通过Rest Api发布请求时,我抛出 内容类型:应用程序/json 当我尝试编写代码时,我使用以下代码 org.springframework.web.client.RestClientException:无法提取响应:没有找到合适的HttpMessageConverter响应类型[... FileUpload响应DTO]和内容类型[text/html]给出一个错误。如何转换?