首页 文章

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

提问于
浏览
167

我有两个问题:

  • 如何使用Spring RestTemplate映射JSON对象列表 .

  • 如何映射嵌套的JSON对象 .

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

10 回答

  • 1

    也许这样......

    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() 返回 .

  • 1

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

    @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

    对我来说这很有效

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

    Object是您想要的类

  • 2

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

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

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

  • 66

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

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

  • 190

    考虑看看这个答案,特别是如果你想在 List Spring RestTemplate and generic types ParameterizedTypeReference collections like List<T>中使用泛型

  • 0

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

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

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

  • 276

    您可以为每个条目创建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();
    
  • 1

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

    根据这篇文章,你可以返回一个这样的打字列表:

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

相关问题