无法获取泛型响应实体<T>其中 T 是泛型类“SomeClass<SomeGenericType>”

2022-09-01 11:52:35

请帮我得到一个哪里本身就是一个泛型类型。正如我现在所看到的,现在春天的RestTemplate不支持这一点。我使用的是 Spring MVC 版本 3.1.2ResponseEntity<T>T

这是我的代码,我想用:代码:

ResponseEntity<CisResponse<CisResponseEntity>> res =
         this.restTemplate.postForEntity(
             this.rootURL, myRequestObj, CisResponse.class);

我收到此错误:

Type mismatch: cannot convert from ResponseEntity<CisResponse> to
ResponseEntity<CisResponse<CisResponseEntity>>

这是明显的错误,但我今天如何解决它?

比我确实想得到我的通用响应类型:

CisResponse<CisResponseEntity> myResponse= res.getBody();
CisResponseEntity entity = myResponse.getEntityFromResponse();

现在,我使用此解决方案,而不是:postForObject()postForEntity()

CisResponse<CisResponseEntity> response = 
          this.restTemplate.postForObject(
               this.rootURL,myRequestObj, CisResponse.class);

答案 1

这是一个已知问题。现在,通过引入 来修复它,这是一个参数化类型,您可以显式继承该类型以在运行时提供类型信息。这称为超类型标记,它适用于类型擦除,因为子类(在本例中为非匿名)在运行时保留泛型超类型的类型参数ParameterizedTypeReference

但是,您不能使用 ,因为 API 仅支持 exchange()postForObject

ResponseEntity<CisResponse<CisResponseEntity>> res = template.exchange(
        rootUrl,
        HttpMethod.POST,
        null,
        new ParameterizedTypeReference<CisResponse<CisResponseEntity>>() {});

请注意,最后一行演示了超类型标记的思想:您不提供文本 ,而是参数化类型的匿名实例化,在运行时可以期望它提取子类型信息。您可以将超类型令牌视为实现CisResponse.classParameterizedTypeReference<T>Foo<Bar<Baz>>.class

顺便说一句,在Java中,您不需要在访问实例变量之前添加前缀:如果您的对象定义了一个和成员,只需使用它们的简单名称访问它们,而不是像您那样通过前缀和thisurltemplatethis.urlthis.template


答案 2