无法获取泛型 ResponseEntity<T>,其中 T 是一个泛型类“SomeClass<SomeGenericType>”。

31

请帮我获取一个ResponseEntity<T>,其中T本身是一个泛型类型。目前来看,Spring RestTemplate现在不支持此功能。我正在使用Spring MVC版本3.1.2。

这是我想要使用的代码: Code:

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

I'm getting this error:

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个回答

46
这是已知的问题。现在通过引入ParameterizedTypeReference进行了修复,它是一个参数化类型,在运行时你需要明确继承它来提供类型信息。这被称为超类型标记,并可以解决类型擦除问题,因为子类(在此情况下是匿名的)在运行时保留了其泛型超类型的类型参数
然而,由于API仅支持exchange(),所以您不能使用postForObject
ResponseEntity<CisResponse<CisResponseEntity>> res = template.exchange(
        rootUrl,
        HttpMethod.POST,
        null,
        new ParameterizedTypeReference<CisResponse<CisResponseEntity>>() {});
请注意,最后一行演示了“超类型令牌”的想法:super type tokens。您不提供字面量CisResponse.class,而是提供参数化类型ParameterizedTypeReference<T>的匿名实例化,在运行时可以预期从中提取子类型信息。您可以将超类型令牌视为实现Foo<Bar<Baz>>.class的“黑科技”。
顺便说一句,在Java中,您不需要在实例变量的访问前加上this前缀:如果您的对象定义了urltemplate成员,只需使用它们的简单名称访问它们,而不是像this.urlthis.template那样加前缀。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接