두 가지 질문이 있습니다.
- Spring RestTemplate을 사용하여 JSON 객체 목록을 매핑하는 방법.
- 중첩 JSON 객체를 매핑하는 방법
http://spring.io/guides/gs/ consumer-rest /의 자습서에 따라 https://bitpay.com/api/rates 를 사용하려고합니다 .
두 가지 질문이 있습니다.
http://spring.io/guides/gs/ consumer-rest /의 자습서에 따라 https://bitpay.com/api/rates 를 사용하려고합니다 .
답변:
아마도 이런 식으로 ...
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()
and에 의해 반환됩니다 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 [] 대신 강력한 형식의 목록을 다시 얻는 것이 좋습니다.
restTemplate.exchange
마샬 랄라가 모든 json 값을 Rate 객체의 속성으로 일치하는 키 이름에 매핑 할 때 여기에서 일어나는 일을 추측하고 있습니다. 내 사고 과정이 정확하길 바랍니다.
나를 위해 이것은 효과가 있었다
Object[] forNow = template.getForObject("URL", Object[].class);
searchList= Arrays.asList(forNow);
Object는 원하는 클래스입니다.
Coupon[] coupons = restTemplate.getForObject( url, Coupon[].class)
[]
완전히 비어 있지 않은 경우) NPE가 발생할 수 있습니다 . 따라서 조심하고 null
( if (forNow != null)...
)를 확인하십시오 .
Object.class
메소드에 지정된 때 Jackson이 사용하는 유형이 궁금 합니다 getForObject()
.
여러 번 테스트 한 후에 이것이 내가 찾은 가장 좋은 방법입니다. :)
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());
}
여기서 가장 큰 문제는 RestTemplate을 호환되는 클래스와 일치시키는 데 필요한 Object 구조를 빌드하는 것이 었습니다. 운 좋게도 http://www.jsonschema2pojo.org/ (브라우저에서 JSON 응답을 가져 와서 입력으로 사용)을 발견했으며 이것을 충분히 추천 할 수 없습니다!
나는 실제로 내 프로젝트 중 하나에 기능적인 것을 개발했으며 여기에 코드가 있습니다.
/**
* @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;
}
}
나는 이것이 누군가를 도울 수 있기를 바랍니다!
객체 목록을 선호하는 경우 한 가지 방법은 다음과 같습니다.
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를 리턴 유형으로 사용하여 실제로 원하는 오브젝트 목록을 랩핑합니다. 둘째, getForObject () 대신 RestTemplate.exchange ()를 호출합니다. .
RestTemplate을 사용하는 가장 일반적인 방법입니다. HTTP 메소드, 선택적 요청 본문 및 응답 유형을 지정해야합니다. 이 경우 응답 유형에 대해 ParameterizedTypeReference의 익명 서브 클래스를 사용합니다.
이 마지막 부분은 JSON 응답을 적절한 유형의 객체 목록으로 변환 할 수있게 해줍니다. ParameterizedTypeReference의 익명 서브 클래스를 작성할 때 리플렉션을 사용하여 응답을 변환하려는 클래스 유형에 대한 정보를 캡처합니다.
Java의 Type 객체를 사용하여이 정보를 유지하므로 더 이상 유형 삭제에 대해 걱정할 필요가 없습니다. "
Spring RestTemplate 에서 제네릭을 사용 하고 List <T>와 같은 제네릭 형식 ParameterizedTypeReference 컬렉션을 사용하려는 경우 특히이 답변을 고려하십시오.List
다음과 같이 각 항목에 대해 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();
이 게시물 https://jira.spring.io/browse/SPR-8263 에서 해결 방법을 찾았습니다 .
이 게시물을 기반으로 다음과 같이 유형이 지정된 목록을 반환 할 수 있습니다.
ResponseEntity<? extends ArrayList<User>> responseEntity = restTemplate.getForEntity(restEndPointUrl, (Class<? extends ArrayList<User>>)ArrayList.class, userId);
getForEntity
. 또한 (Class<? extends ArrayList<User>>) ArrayList.class
"호환되지 않는 유형"컴파일 오류가 발생합니다.