我有两个问题:

如何使用Spring RestTemplate映射JSON对象列表。 如何映射嵌套的JSON对象。

我试图消费https://bitpay.com/api/rates,从http://spring.io/guides/gs/consuming-rest/遵循教程。


当前回答

这里提到了3种检索对象列表的方法。所有这些都将完美地工作

@RequestMapping(value = "/emp2", produces = "application/json")
public List<Employee> getEmp2()
{
    HttpHeaders headers = new HttpHeaders();
    headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
    HttpEntity<String> entity = new HttpEntity<String>(headers);
    ResponseEntity<List<Employee>> response = restTemplate.exchange(
            "http://hello-server/rest/employees", HttpMethod.GET,entity, 
    new ParameterizedTypeReference<List<Employee>>() {});
    return response.getBody();
}

(或)

@RequestMapping(value = "/emp3", produces = "application/json")
public List<Employee> getEmp3()
{
    Employee[] empArray = restTemplate.getForObject("http://hello-server/rest/employees", Employee[].class);
    List<Employee> emp= Arrays.asList(empArray);
    return emp;
}

(或)

    @RequestMapping(value = "/emp4", produces = "application/json")
public Employee[] getEmp4()
{
    ResponseEntity<Employee[]> responseEntity = restTemplate.getForEntity("http://hello-server/rest/employees", Employee[].class);
    Employee[] empList = responseEntity.getBody();
    //MediaType contentType = responseEntity.getHeaders().getContentType();
    //HttpStatus statusCode = responseEntity.getStatusCode();
    return  empList;
}

Employee.class

public class Employee {

private Integer id;
private String name;
private String Designation;
private String company;

//getter setters and toString()

}

其他回答

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

对于那些使用Spring + Kotlin的人来说,下面是翻译:

val rates = restTemplate.exchange("https://bitpay.com/api/rates", HttpMethod.GET, null, object : ParameterizedTypeReference<List<Rate>>() {}).body!!

我在这里遇到的最大问题是构建将RestTemplate匹配到兼容类所需的Object结构。幸运的是,我找到了http://www.jsonschema2pojo.org/(在浏览器中获得JSON响应并将其作为输入),我非常推荐这个功能!

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

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

这就是你所需要的

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());
}

如果你更喜欢一个pojo列表,一种方法是这样做的:

class SomeObject {
    private int id;
    private String name;
}

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;
}

像这样使用它:

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

以上的解释可以在这里(https://www.baeldung.com/spring-rest-template-list)找到,并在下面进行解释。

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

这是使用RestTemplate的最通用方式。它要求我们指定HTTP方法、可选请求体和响应类型。在本例中,我们为响应类型使用ParameterizedTypeReference的匿名子类。

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

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