java RestTemplate getForEntity 映射到对象列表

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/30936863/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 17:51:23  来源:igfitidea点击:

RestTemplate getForEntity map to list of objects

javaresttemplate

提问by Harsha Ananthapadmanabha

I have a response from URL which looks like:

我有一个来自 URL 的响应,它看起来像:

{"seq":1,"id":"Test1","changes":[{"rev":"1-52f5cdf008ecfbadf621c2939af7bd80"}]}
{"seq":2,"id":"Test2","changes":[{"rev":"1-8ce403a89dc5e7cb4187a16941b3fb7d"}]}
{"seq":3,"id":"Test3","changes":[{"rev":"1-52as7ddfd8ecfbadf621c2939af7bd80"}]}
{"seq":4,"id":"Test4","changes":[{"rev":"1-6yy03a89dc5e7cb45677a16941b3fb7d"}]}

If the mapped object is String, then getting all the changes feed.

如果映射对象是字符串,则获取所有更改提要。

ResponseEntity<String> responseEntity = restTemplate.exchange(URL, HttpMethod.GET, requestEntity, String.class);

Whereas, if I happen to use a custom Value object, somethings like:

然而,如果我碰巧使用自定义 Value 对象,例如:

public class KnChanges {
private long seq;
private String id;
private List changes;

with getter and setter methods, then I'm getting only the first doc change details. Even if the KnChanges[] (array) is used, only the first change is obtained.

使用 getter 和 setter 方法,那么我只能获得第一个文档更改详细信息。即使使用了 KnChanges[](数组),也只能获得第一个变化。

Can you please help as to how the JSON list structure mentioned above can be mapped to an object?

你能帮忙看看上面提到的 JSON 列表结构如何映射到一个对象吗?

Thanks Harsha

谢谢哈沙

回答by sujim

ParameterizedTypeReference<List<KnChanges>> responseType = new ParameterizedTypeReference<List<KnChanges>>() {};
ResponseEntity<List<KnChanges>> resp = restTemplate.exchange(URL, HttpMethod.GET, requestEntity, responseType);
List<KnChanges> list = resp.getBody();

回答by Mario Eis

Some people asked for a better answer with some explaination. So here it is:

有些人要求提供更好的答案并进行一些解释。所以这里是:

As sujim mentioned: You need to

正如 sujim 提到的:你需要

ParameterizedTypeReference<List<KnChanges>> responseType = new ParameterizedTypeReference<List<KnChanges>>() {};
ResponseEntity<List<KnChanges>> resp = restTemplate.exchange(URL, HttpMethod.GET, requestEntity, responseType);
List<KnChanges> list = resp.getBody();

Explaination:

说明:

The last parameter of the exchange method call defines the class that gets instantiated when the response is received. The response data will then be mapped to the resulting object. So you need a List.classin fist place. Because you expect a JSON array. Now you need to define the type of the content of that List. Here Java's type erasurethrows some stones in your way. As Java removes generic type information at compile-time, you can't just define the expected Listto be a List<KnChanges>.class. "Luckily" there is a hack ;) And that hack is new ParameterizedTypeReference<List<KnChanges>>() {}. Provided that object the application is able to read the generic type information at runtime. And therefore is able to map the received data to your Java objects.

exchange 方法调用的最后一个参数定义了在收到响应时实例化的类。然后将响应数据映射到结果对象。所以你需要一个List.class拳头。因为您需要一个 JSON 数组。现在您需要定义 that 的内容类型List。在这里,Java 的类型擦除给您带来了一些障碍。由于 Java 在编译时删除了泛型类型信息,因此您不能仅将预期定义ListList<KnChanges>.class. “幸运的是”有一个 hack ;) 而那个 hack 是new ParameterizedTypeReference<List<KnChanges>>() {}. 如果该对象应用程序能够在运行时读取泛型类型信息。因此能够将接收到的数据映射到您的 Java 对象。

As a side-note: There a several implementations of that hack. It's commonly used for dependency injection or mapper systems, where type erasure can sometimes be an issue. Also Googles Guava offers an implementation. See the codefor more information. There you can also learn how it's done, if you like.

附带说明:该 hack 有多种实现方式。它通常用于依赖注入或映射器系统,其中类型擦除有时可能是一个问题。Googles Guava 也提供了一个实现。有关更多信息,请参阅代码。如果您愿意,您还可以在那里了解它是如何完成的。