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

时间:2014-05-15 09:17:51

标签: java spring resttemplate

我有两个问题:

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

我正在尝试使用https://bitpay.com/api/rates中的教程来消费http://spring.io/guides/gs/consuming-rest/

13 个答案:

答案 0 :(得分:284)

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

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

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

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

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

答案 1 :(得分:192)

也许这样......

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

RequestMapping

的控制器代码
@RequestMapping(value="/Object/getList/", method=RequestMethod.GET)
public @ResponseBody List<Object> findAllObjects() {

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

ResponseEntityHttpEntity的扩展,可添加HttpStatus状态代码。用于RestTemplate以及@Controller方法。 在RestTemplate中,此类由getForEntity()exchange()返回。

答案 2 :(得分:68)

对我来说这很有用

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

对象是你想要的类

答案 3 :(得分:5)

经过多次测试,这是我找到的最佳方式:)

members.member.view

你需要的一切

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

答案 4 :(得分:2)

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

答案 5 :(得分:2)

这里提到了 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()

}

答案 6 :(得分:1)

如果您希望使用“对象列表”,执行此操作的一种方法是这样的:

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对象保留这些信息,我们不再需要担心类型擦除。”

答案 7 :(得分:1)

考虑一下此答案,特别是如果您想在List中使用泛型的话 Spring RestTemplate and generic types ParameterizedTypeReference collections like List<T>

答案 8 :(得分:1)

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

/**
 * @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 MappingJackson2HttpMessageConverter());
        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 MappingJackson2HttpMessageConverter());
        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;
    }
}

我希望这会对某人有所帮助!

答案 9 :(得分:0)

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

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

然后使用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();

答案 10 :(得分:0)

就我而言,我更喜欢提取一个String,然后使用JsonNode接口浏览上下文

    var response =  restTemplate.exchange("https://my-url", HttpMethod.GET, entity,  String.class);
    if (response.getStatusCode() == HttpStatus.OK) {
        var jsonString = response.getBody();
        ObjectMapper mapper = new ObjectMapper();
        JsonNode actualObj = mapper.readTree(jsonString);           
        
        System.out.println(actualObj);  
    }

或快速

ObjectNode actualObj= restTemplate.getForObject("https://my-url", ObjectNode.class);

然后使用路径表达式读取内部数据

boolean b = actualObj.at("/0/states/0/no_data").asBoolean();

答案 11 :(得分:0)

作为通用模块,Page<?>对象可以像moduleJodaModule等一样被Log4jJsonModule反序列化。参考我的这个答案。JsonMappingException when testing endpoints with Pageable field

答案 12 :(得分:-1)

我找到了这篇文章的作品https://jira.spring.io/browse/SPR-8263

根据这篇文章,您可以返回如下类型的列表:

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