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


Answers:


220

也许这样

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

ResponseEntity是对扩展名的HttpEntity添加HttpStatus状态代码。使用RestTemplate以及@Controller方法。在RestTemplate此类中,由getForEntity()和返回exchange()


就像魅力一样,谢谢。也许您可以指导我阅读一些其他有关该主题的教程或指南?
卡鲁迪

2
最好在此处查看stackoverflow上的一些代码段和示例,或访问正式的Spring网站。TblGps []
kamokaze 2014年

是否可以使用泛型?即我的方法有一个Class <Textended Foo>参数,我想从getForEntity方法获取T的集合。
Diskutant

是的,它应该可以工作,但是可能不是开箱即用的,具体取决于您的spring / jackson版本和您的班级类型。有关泛型序列化/反序列化的全部内容-http Request本身并不关心要传输的内容。
kamokaze 2015年


335

首先定义一个对象来保存实体回到数组中。

@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 []。


6
在Spring 4.2.3上运行平稳,并且-如Matt所说-具有避免Object []的巨大优势
Marged

@Matt-您使用哪个编组器将json编组为Rate对象?我猜这就是这里发生的事情,在restTemplate.exchange封送警官将所有json值映射到匹配的键名时,作为Rate对象中的属性。希望我的想法正确。
Nirmal

完美,做工精细春季启动1.4.0.RELEASE感谢
阿南德

1
我相信@Nirmal Spring默认使用Jackson。
Sohaib

1
@SarvarNishonboev从springframework.core当前的ParameterizedTypeReference似乎仍然很好:docs.spring.io/spring-framework/docs/current/javadoc-api/org/…–
fspinnenhirn

75

对我来说这很有效

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

对象是您想要的类


16
即使您使用类而不是类似Object的方法,该方法也有效Coupon[] coupons = restTemplate.getForObject( url, Coupon[].class)
lrkwz 2015年

1
如果HTTP响应主体为空(不是[]但完全为空),则可能导致NPE 。因此请小心并检查nullif (forNow != null)...)。
Ruslan Stelmachenko

1
保存了我的屁股:)想知道Jackson Object.class在方法(method)中指定了什么类型getForObject()
Eric Wang

5

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

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

注意:这需要番石榴
vphilipnyc

2

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


2

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

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

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


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



1

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

4
这将不起作用,因为由于擦除操作,没有将类型参数信息传递给getForEntity。还(Class<? extends ArrayList<User>>) ArrayList.class给出了“不兼容类型”的编译错误。
Esko Luontola 2015年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.