Webflux WebClient和通用类型

时间:2018-11-19 15:45:48

标签: java spring jackson spring-webflux

我正在尝试构建一个将使用REST API的通用类。 api根据网址返回对象列表。

我建立了一个通用类

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列表。 我尝试了很多变通办法,但是没有运气。有什么建议吗?

3 个答案:

答案 0 :(得分:1)

我遇到了同样的问题,为了工作,我添加了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);

答案 1 :(得分:1)

如果您使用的是 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))

答案 2 :(得分:0)

创建一个类(例如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());

    }
}