You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 11:15:04