У меня есть два вопроса:
- Как сопоставить список объектов JSON с помощью Spring RestTemplate.
- Как сопоставить вложенные объекты JSON.
Я пытаюсь использовать https://bitpay.com/api/rates, следуя руководству http://spring.io/guides/gs/consuming-rest/.
У меня есть два вопроса:
Я пытаюсь использовать https://bitpay.com/api/rates, следуя руководству http://spring.io/guides/gs/consuming-rest/.
Может быть, так...
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()
.
Сначала определите объект, чтобы удерживать объект, возвращающийся в массив. Например,
@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 [].
Для меня это сработало
Object[] forNow = template.getForObject("URL", Object[].class);
searchList= Arrays.asList(forNow);
Где объект - это класс, который вы хотите
После нескольких тестов это лучший способ, который я нашел:)
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());
}
Моя большая проблема заключалась в том, чтобы построить структуру Object, необходимую для соответствия RestTemplate совместимому классу. К счастью, я нашел http://www.jsonschema2pojo.org/ (получить ответ JSON в браузере и использовать его в качестве входных данных), и я не могу рекомендовать это достаточно!
Если вы предпочитаете список объектов, один из способов сделать это так:
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, он использует отражение для сбора информации о типе класса, в который мы хотим преобразовать наш ответ.
Он сохраняет эту информацию с помощью объекта Javas Type, и нам больше не нужно беспокоиться об удалении типов ".
Рассмотрим этот ответ, особенно если вы хотите использовать обобщенные значения в коллекциях List
Spring RestTemplate и универсальные типы ParameterizedTypeReference, такие как List<T>
я на самом деле разработал что-то функциональное для одного из моих проектов, и вот код:
/**
* @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;
}
}
Я надеюсь, что это кому-нибудь поможет!
Я нашел работу с этого сообщения https://jira.spring.io/browse/SPR-8263.
На основании этого сообщения вы можете вернуть типизированный список следующим образом:
ResponseEntity<? extends ArrayList<User>> responseEntity = restTemplate.getForEntity(restEndPointUrl, (Class<? extends ArrayList<User>>)ArrayList.class, userId);