Java 使用 Spring RestTemplate 获取 JSON 对象列表

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/23674046/
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-08-14 00:36:35  来源:igfitidea点击:

Get list of JSON objects with Spring RestTemplate

javaspringresttemplate

提问by Karudi

I have two questions:

我有两个问题:

  • How to map a list of JSON objects using Spring RestTemplate.
  • How to map nested JSON objects.
  • 如何使用 Spring RestTemplate 映射 JSON 对象列表。
  • 如何映射嵌套的 JSON 对象。

I am trying to consume https://bitpay.com/api/rates, by following the tutorial from http://spring.io/guides/gs/consuming-rest/.

我正在尝试按照http://spring.io/guides/gs/sumption-rest/ 中的教程使用https://bitpay.com/api/rates

采纳答案by kamokaze

Maybe this way...

也许这样...

ResponseEntity<Object[]> responseEntity = restTemplate.getForEntity(urlGETList, Object[].class);
Object[] objects = responseEntity.getBody();
MediaType contentType = responseEntity.getHeaders().getContentType();
HttpStatus statusCode = responseEntity.getStatusCode();

Controller code for the RequestMapping

控制器代码 RequestMapping

@RequestMapping(value="/Object/getList/", method=RequestMethod.GET)
public @ResponseBody List<Object> findAllObjects() {

    List<Object> objects = new ArrayList<Object>();
    return objects;
}

ResponseEntityis an extension of HttpEntitythat adds a HttpStatusstatus code. Used in RestTemplateas well @Controllermethods. In RestTemplatethis class is returned by getForEntity()and exchange().

ResponseEntityHttpEntity添加HttpStatus状态代码的扩展。使用RestTemplate以及@Controller方法。在RestTemplate这个类中由getForEntity()和返回exchange()

回答by yonia

For me this worked

对我来说这有效

Object[] forNow = template.getForObject("URL", Object[].class);
    searchList= Arrays.asList(forNow);

Where Object is the class you want

Object 是你想要的类

回答by Shravan Ramamurthy

I found work around from this post https://jira.spring.io/browse/SPR-8263.

我从这篇文章https://jira.spring.io/browse/SPR-8263 中找到了解决方法。

Based on this post you can return a typed list like this:

基于这篇文章,你可以返回一个这样的类型列表:

ResponseEntity<? extends ArrayList<User>> responseEntity = restTemplate.getForEntity(restEndPointUrl, (Class<? extends ArrayList<User>>)ArrayList.class, userId);

回答by Matt

First define an object to hold the entity coming back in the array.. e.g.

首先定义一个对象来保存返回数组中的实体.. 例如

@JsonIgnoreProperties(ignoreUnknown = true)
public class Rate {
    private String name;
    private String code;
    private Double rate;
    // add getters and setters
}

Then you can consume the service and get a strongly typed list via:

然后您可以使用该服务并通过以下方式获取强类型列表:

ResponseEntity<List<Rate>> rateResponse =
        restTemplate.exchange("https://bitpay.com/api/rates",
                    HttpMethod.GET, null, new ParameterizedTypeReference<List<Rate>>() {
            });
List<Rate> rates = rateResponse.getBody();

The other solutions above will also work, but I like getting a strongly typed list back instead of an Object[].

上面的其他解决方案也可以使用,但我喜欢返回强类型列表而不是 Object[]。

回答by Romain-p

After multiple tests, this is the best way I found :)

经过多次测试,这是我发现的最好方法:)

Set<User> test = httpService.get(url).toResponseSet(User[].class);

All you need there

你需要的一切

public <T> Set<T> toResponseSet(Class<T[]> setType) {
    HttpEntity<?> body = new HttpEntity<>(objectBody, headers);
    ResponseEntity<T[]> response = template.exchange(url, method, body, setType);
    return Sets.newHashSet(response.getBody());
}

回答by upnorth

My big issue here was to build the Object structure required to match RestTemplate to a compatible Class. Luckily I found http://www.jsonschema2pojo.org/(get the JSON response in a browser and use it as input) and I can't recommend this enough!

我在这里的大问题是构建将 RestTemplate 与兼容的类匹配所需的对象结构。幸运的是,我找到了http://www.jsonschema2pojo.org/(在浏览器中获取 JSON 响应并将其用作输入),我不能推荐这个!

回答by Toofy

If you would prefer a List of Objects, one way to do it is like this:

如果您更喜欢对象列表,一种方法是这样的:

public <T> List<T> getApi(final String path, final HttpMethod method) {     
    final RestTemplate restTemplate = new RestTemplate();
    final ResponseEntity<List<T>> response = restTemplate.exchange(
      path,
      method,
      null,
      new ParameterizedTypeReference<List<T>>(){});
    List<T> list = response.getBody();
    return list;
}

And use it like so:

并像这样使用它:

 List<SomeObject> list = someService.getApi("http://localhost:8080/some/api",HttpMethod.GET);

Explanation for the above can be found here (https://www.baeldung.com/spring-rest-template-list) and is paraphrased below.

可以在此处找到对上述内容的解释 ( https://www.baeldung.com/spring-rest-template-list),并在下面进行了释义。

"There are a couple of things happening in the code above. First, we use ResponseEntity as our return type, using it to wrap the list of objects we really want. Second, we are calling RestTemplate.exchange() instead of getForObject().

“在上面的代码中发生了一些事情。首先,我们使用 ResponseEntity 作为我们的返回类型,使用它来包装我们真正想要的对象列表。其次,我们调用 RestTemplate.exchange() 而不是 getForObject() .

This is the most generic way to use RestTemplate. It requires us to specify the HTTP method, optional request body, and a response type. In this case, we use an anonymous subclass of ParameterizedTypeReference for the response type.

这是使用 RestTemplate 的最通用方法。它要求我们指定 HTTP 方法、可选的请求正文和响应类型。在这种情况下,我们使用 ParameterizedTypeReference 的匿名子类作为响应类型。

This last part is what allows us to convert the JSON response into a list of objects that are the appropriate type. When we create an anonymous subclass of ParameterizedTypeReference, it uses reflection to capture information about the class type we want to convert our response to.

最后一部分允许我们将 JSON 响应转换为适当类型的对象列表。当我们创建 ParameterizedTypeReference 的匿名子类时,它使用反射来捕获有关我们要将响应转换为的类类型的信息。

It holds on to this information using Java's Type object, and we no longer have to worry about type erasure."

它使用 Java 的 Type 对象保留这些信息,我们不再需要担心类型擦除。”

回答by Moesio

Consider see this answer, specially if you want use generics in ListSpring RestTemplate and generic types ParameterizedTypeReference collections like List<T>

考虑看这个答案,特别是如果你想在Spring RestTemplate 和泛型类型 ParameterizedTypeReference 集合中使用泛型,List如 List<T>

回答by Hamza Jeljeli

i actually deveopped something functional for one of my projects before and here is the code :

我之前实际上为我的一个项目开发了一些功能,这是代码:

/**
 * @param url             is the URI address of the WebService
 * @param parameterObject the object where all parameters are passed.
 * @param returnType      the return type you are expecting. Exemple : someClass.class
 */

public static <T> T getObject(String url, Object parameterObject, Class<T> returnType) {
    try {
        ResponseEntity<T> res;
        ObjectMapper mapper = new ObjectMapper();
        RestTemplate restTemplate = new RestTemplate();
        restTemplate.getMessageConverters().add(new MappingHymanson2HttpMessageConverter());
        restTemplate.getMessageConverters().add(0, new StringHttpMessageConverter(Charset.forName("UTF-8")));
        ((SimpleClientHttpRequestFactory) restTemplate.getRequestFactory()).setConnectTimeout(2000);
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        HttpEntity<T> entity = new HttpEntity<T>((T) parameterObject, headers);
        String json = mapper.writeValueAsString(restTemplate.exchange(url, org.springframework.http.HttpMethod.POST, entity, returnType).getBody());
        return new Gson().fromJson(json, returnType);
    } catch (Exception e) {
        e.printStackTrace();
        return null;
    }
}

/**
 * @param url             is the URI address of the WebService
 * @param parameterObject the object where all parameters are passed.
 * @param returnType      the type of the returned object. Must be an array. Exemple : someClass[].class
 */
public static <T> List<T> getListOfObjects(String url, Object parameterObject, Class<T[]> returnType) {
    try {
        ObjectMapper mapper = new ObjectMapper();
        RestTemplate restTemplate = new RestTemplate();
        restTemplate.getMessageConverters().add(new MappingHymanson2HttpMessageConverter());
        restTemplate.getMessageConverters().add(0, new StringHttpMessageConverter(Charset.forName("UTF-8")));
        ((SimpleClientHttpRequestFactory) restTemplate.getRequestFactory()).setConnectTimeout(2000);
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        HttpEntity<T> entity = new HttpEntity<T>((T) parameterObject, headers);
        ResponseEntity<Object[]> results = restTemplate.exchange(url, org.springframework.http.HttpMethod.POST, entity, Object[].class);
        String json = mapper.writeValueAsString(results.getBody());
        T[] arr = new Gson().fromJson(json, returnType);
        return Arrays.asList(arr);
    } catch (Exception e) {
        e.printStackTrace();
        return null;
    }
}

I hope that this will help somebody !

我希望这会帮助某人!

回答by Nitin Pawar

You can create POJO for each entry like,

您可以为每个条目创建 POJO,例如,

class BitPay{
private String code;
private String name;
private double rate;
}

then using ParameterizedTypeReference of List of BitPay you can use as:

然后使用 BitPay 列表的 ParameterizedTypeReference 您可以用作:

RestTemplate restTemplate = new RestTemplate();
ResponseEntity<List<Employee>> response = restTemplate.exchange(
  "https://bitpay.com/api/rates",
  HttpMethod.GET,
  null,
  new ParameterizedTypeReference<List<BitPay>>(){});
List<Employee> employees = response.getBody();