【问题标题】:Webflux webclient and generic typesWebflux webclient 和泛型类型
【发布时间】:2019-04-22 00:30:29
【问题描述】:
我正在尝试构建一个使用 REST api 的通用类。 api 根据 url 返回对象列表。
我已经建立了一个通用类
public class RestConsumer<T> {
WebClient client;
public RestConsumer(){
//Initialize client
}
public List<T> getList(String relativeUrl){
try{
return client
.get()
.uri(relativeUrl)
.retrieve()
.bodyToMono(new ParameterizeTypeReference<List<T>> (){}
.block()
catch(Exception e){}
}
}
问题是 T 在编译时被 Object 替换,整个事情返回 LinkedHashMap 列表而不是 T 列表。
我尝试了很多解决方法,但没有运气。有什么建议吗?
【问题讨论】:
标签:
java
spring
jackson
spring-webflux
【解决方案1】:
创建一个类(比如 CollectionT)并在其中添加 T 的列表作为属性。然后您可以轻松地将其转换为 Mono,.map(x -> x.getList()) 将返回 T 列表的 Mono。它还通过避免 .block() 使您的代码看起来更加非阻塞
代码如下:->
public class CollectionT {
private List<T> data;
//getters
public List<T> getData(){
return data;
}
//setters
...
}
public class RestConsumer<T> {
WebClient client = WebClient.create();
public RestConsumer(){
//Initialize client
}
public List<T> getList(String relativeUrl){
return client
.get()
.uri(relativeUrl)
.retrieve()
.bodyToMono(CollectionT.class)
.map(x -> x.getData());
}
}
【解决方案2】:
我遇到了同样的问题,为了工作,我添加了 ParameterizedTypeReference 作为该函数的参数。
public <T> List<T> getList(String relativeUrl,
ParameterizedTypeReference<List<T>> typeReference){
try{
return client
.get()
.uri(relativeUrl)
.retrieve()
.bodyToMono(typeReference)
.block();
} catch(Exception e){
return null;
}
}
然后调用那个函数
ParameterizedTypeReference<List<MyClass>> typeReference = new ParameterizedTypeReference<List<MyClass>>(){};
List<MyClass> strings = getList(relativeUrl, typeReference);
【解决方案3】:
如果您使用的是 kotlin,关键是使用 reified 来保留调用字段上的泛型类型的类类型。
代码如下:
inline fun <reified T> getMonoResult(uriParam: String): T? = client
.get()
.uri(uriParam)
.retrieve()
.bodyToMono(T::class.java)
.block(Duration.ofSeconds(1))
inline fun <reified T> getFluxResult(uriParam: String): MutableList<T>? = client
.get()
.uri(uriParam)
.retrieve()
.bodyToFlux(T::class.java)
.collectList()
.block(Duration.ofSeconds(1))