RestTemplate调用GET接口解析指定结构JSON为Domain列表反序列化报错如何解决
报错原因
- 泛型类型传递错误:Java泛型存在编译期擦除特性,
Map<String, List<Domain>>.class本身是非法语法,实际传递给Jackson的类型仅为原始Map类型,框架无法识别内层List<Domain>的泛型信息,导致反序列化逻辑混乱,尝试将外层JSON对象映射为数组类型,抛出类型不匹配异常。 - DTO字段不匹配:接口返回的数组元素包含
name字段,但你的Domain类中对应业务字段命名为domain,没有建立映射关系,即使反序列化流程正常,该字段也会赋值为null。 - 无效请求体设置:GET请求不需要携带请求体,你在
HttpEntity中传入的"parameters"属于无效参数,部分服务端会因为GET请求携带body返回异常格式响应,也可能触发反序列化失败。
解决方案
第一步:修正Domain类字段映射
给domain字段添加@JsonProperty注解绑定返回的name字段,同时补充无参构造和setter方法(Jackson反序列化依赖):
class Domain { String id; @JsonProperty("name") String domain; // 无参构造 public Domain() {} // getter、setter方法省略 }
第二步:修正RestTemplate调用逻辑
方案1:用ParameterizedTypeReference传递完整泛型信息(直接解析为Map)
@WithUserDetails("testuser") @Test public void test_get_domains_api() { HttpHeaders headers = new HttpHeaders(); headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON)); headers.add("User-Agent", "Spring's RestTemplate" ); headers.add("Authorization", "Bearer "+TOKEN ); // GET请求不需要传body,直接传入headers即可 ResponseEntity<Map<String, List<Domain>>> response = restTemplate.exchange( "https://sample/v1/sites", HttpMethod.GET, new HttpEntity<>(headers), // 用ParameterizedTypeReference保留完整泛型信息 new ParameterizedTypeReference<Map<String, List<Domain>>>() {} ); List<Domain> domainList = response.getBody().get("data"); System.out.println(domainList); assertNotNull(domainList); }
方案2:定义通用外层响应DTO(更易维护)
先定义可复用的通用响应结构:
class ApiResponse<T> { private T data; // 无参构造、getter、setter方法省略 }
调整调用代码:
@WithUserDetails("testuser") @Test public void test_get_domains_api() { HttpHeaders headers = new HttpHeaders(); headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON)); headers.add("User-Agent", "Spring's RestTemplate" ); headers.add("Authorization", "Bearer "+TOKEN ); ResponseEntity<ApiResponse<List<Domain>>> response = restTemplate.exchange( "https://sample/v1/sites", HttpMethod.GET, new HttpEntity<>(headers), new ParameterizedTypeReference<ApiResponse<List<Domain>>>() {} ); List<Domain> domainList = response.getBody().getData(); System.out.println(domainList); assertNotNull(domainList); }
内容的提问来源于stack exchange,提问作者diaop
相关产品推荐
相关产品推荐

