web-dev-qa-db-de.com

Rufen Sie mit Spring RestTemplate eine Liste mit JSON-Objekten ab

Ich habe zwei Fragen:

  • So ordnen Sie eine Liste von JSON-Objekten mithilfe von Spring RestTemplate zu.
  • So ordnen Sie verschachtelte JSON-Objekte zu.

Ich versuche, https://bitpay.com/api/rates zu konsumieren, indem ich dem Tutorial von http://spring.io/guides/gs/consuming-rest/ folge.

165
Karudi

Vielleicht so ...

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

Controller-Code für die RequestMapping

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

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

ResponseEntity ist eine Erweiterung von HttpEntity, die einen HttpStatus-Statuscode hinzufügt. Wird in RestTemplate sowie @Controller-Methoden verwendet . In RestTemplate wird diese Klasse von getForEntity() und exchange() zurückgegeben.

185
kamokaze

Definieren Sie zuerst ein Objekt, das die Entität enthält, die in das Array zurückkommt.

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

Dann können Sie den Dienst nutzen und erhalten eine stark typisierte Liste über: 

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

Die anderen Lösungen oben werden ebenfalls funktionieren, aber ich möchte lieber eine stark typisierte Liste anstelle eines Objekts [] zurückbekommen.

273
Matt

Für mich hat das funktioniert 

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

Wobei Objekt die gewünschte Klasse ist

66
yonia

Nach mehreren Tests ist dies der beste Weg, den ich gefunden habe :)

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

Alles was du dort brauchst

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
Romain-p

Mein größtes Problem hier war das Erstellen der Objektstruktur, die erforderlich ist, um RestTemplate einer kompatiblen Klasse zuzuordnen. Zum Glück habe ich http://www.jsonschema2pojo.org/ gefunden (die JSON-Antwort in einem Browser abrufen und als Eingabe verwenden) und ich kann das nicht genug empfehlen!

2
upnorth
1
Moesio

ich habe tatsächlich etwas Funktionales für eines meiner Projekte entwickelt und hier ist der 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 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;
    }
}

Ich hoffe, dass dies jemandem helfen wird!

1
Hamza Jeljeli

Wenn Sie eine Liste mit Objekten bevorzugen, können Sie dies folgendermaßen tun:

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

Und benutze es wie folgt:

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

Erläuterungen zu den oben genannten Informationen finden Sie hier ( https://www.baeldung.com/spring-rest-template-list ) und sind unten umschrieben.

"Es gibt ein paar Dinge im obigen Code. Erstens verwenden wir ResponseEntity als Rückgabetyp, um damit die Liste der Objekte, die wir wirklich wollen, einzuhüllen. Zweitens rufen wir RestTemplate.exchange () anstelle von getForObject () auf. .

Dies ist die allgemeinste Art, RestTemplate zu verwenden. Dazu müssen wir die HTTP-Methode, den optionalen Anforderungstext und einen Antworttyp angeben. In diesem Fall verwenden wir eine anonyme Unterklasse von ParameterizedTypeReference für den Antworttyp.

Dieser letzte Teil ermöglicht es uns, die JSON-Antwort in eine Liste von Objekten zu konvertieren, die den entsprechenden Typ haben. Beim Erstellen einer anonymen Unterklasse von ParameterizedTypeReference werden mithilfe von Reflektion Informationen über den Klassentyp erfasst, in den unsere Antwort konvertiert werden soll.

Diese Informationen werden durch das Type-Objekt von Java beibehalten, und wir müssen uns nicht mehr um das Löschen von Typen kümmern. "

0
Toofy

Sie können POJO für jeden Eintrag erstellen,

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

dann können Sie mit ParameterizedTypeReference von List of BitPay verwenden als:

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();
0
Nitin Pawar