如何使用Spring的ClientResponse消费一个Map?

huangapple go评论62阅读模式
英文:

How to consume a Map with Spring ClientResponse?

问题

首先,我有一个类似这样的 REST URL:

@PostMapping("/check/existence")
@ResponseBody
public Map<String, MyObjectDto> checkExistence() {
    //一些代码
}

然后,我有一个使用 Spring WebClient 的消费者,就像这样:

ClientResponse response = webclient.post().uri....

我想要做类似这样的操作:

Map<String, MyObjectDto> responseDto = 
    response.bodyToMono(Map.class).block();

但是控制台返回了以下信息:

java.util.LinkedHashMap 无法强制转换为 org.mypackage.MyObjectDto

那么,我如何消费一个类似 Map<String, MyObjectDto> 类型的映射呢?

英文:

First, I have a REST URL exposed like that:

   @PostMapping(&quot;/check/existence&quot;)
   @ResponseBody
   public Map&lt;String, MyObjectDto&gt; checkExistence() {
   //some code 

then, I have a consumer with a Spring WebClient, like that :

   ClientResponse response = webclient.post().uri....

I want to do something like that :

   Map&lt;String, MyObjectDto&gt; responseDto = 
   response.bodyToMono(Map.class).block();

but console returns to me

   java.util.LinkedHashMap cannot be cast to  org.mypackage.MyObjectDto

so, how can I consume a map typed like Map&lt;String, MyObjectDto&gt;?

答案1

得分: 6

从类ParameterizedTypeReference&lt;T&gt;文档中:

此类的目的是为了能够捕获和传递泛型类型。为了在运行时捕获泛型类型并保留它,您需要创建一个子类(最好是匿名内联类),如下所示:

当您需要将某些东西序列化/反序列化为使用泛型的类型(例如Map<k,v>或List<T>)时,

您不能使用

response.bodyToMono(Map.class)

因为这种方式,Spring不知道您实际上要放入Map中的类型。您会放入int吗?String?对象?它毫无头绪。

因此,您需要提供包含类型信息的内容。

bodyToMono(new ParameterizedTypeReference&lt;Map&lt;StringMyObjectDto&gt;&gt;() {})

ParameterizedTypeReference是一个匿名类,将为您保存类型信息。因此,该类的作用类似于容器,将类型信息传递给泛型函数bodyToMono,这样Spring可以查看此对象的内容并确定您要使用的类型。

英文:

From the documentation of the class ParameterizedTypeReference&lt;T&gt;

> The purpose of this class is to enable capturing and passing a generic Type. In order to capture the generic type and retain it at runtime, you need to create a subclass (ideally as anonymous inline class) as follows:

When you need to serialize/deserialize something into a type that uses generics (for example Map<k, v> or List<T>)

You cannot use

response.bodyToMono(Map.class)

Since this way, spring has no idea what types you want to actually put into the Map. Are you going to put in an int? a String? an Object? It has no idea.

so instead you need to supply something that includes the type information.

bodyToMono(new ParameterizedTypeReference&lt;Map&lt;String, MyObjectDto&gt;&gt;() {})

ParameterizedTypeReference is an anonymous class that will hold your type information for you. So the class acts like a vessel to hold your type information as we pass it into the generic function bodyToMono and that way spring can look at the contents of this object and figure out what types you want to use.

huangapple
  • 本文由 发表于 2020年10月2日 19:45:12
  • 转载请务必保留本文链接:https://go.coder-hub.com/64170975.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定