Spring RestTemplate을 사용하여 JSON 객체 목록 가져 오기


답변:


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()and에 의해 반환됩니다 exchange().


그것은 매력처럼 작동했습니다, 감사합니다. 어쩌면이 주제에 대해 읽을 수있는 다른 자습서 나 안내서로 안내 할 수 있습니까?
Karudi

2
일부 코드 스 니펫 및 예제에 대한 스택 오버 플로우를 보거나 가장 좋은 스프링 웹 사이트를 방문하는 것이 가장 좋습니다 ... TblGps [] a = responseEntity.getBody ();
카 모카 제

제네릭을 사용하여 가능합니까? 즉, 내 메소드에는 Class <T extends Foo> 매개 변수가 있으며 getForEntity 메소드에서 T 컬렉션을 가져오고 싶습니다.
Diskutant

예, 작동하지만 스프링 / 잭슨 버전 및 클래스 유형에 따라 즉시 사용되지 않을 수 있습니다. 제네릭을 직렬화 / 역 직렬화하는 것에 관한 모든 것-http 요청 자체는 전송되는 것을 신경 쓰지 않습니다.
kamokaze


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

완벽 함, Spring Boot 1.4.0에서 잘 작동합니다 .RELEASE Thanks
Anand

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

Object는 원하는 클래스입니다.


16
이것은 클래스가 아닌 Object를 사용하지 않더라도 작동합니다.Coupon[] coupons = restTemplate.getForObject( url, Coupon[].class)
lrkwz

1
HTTP 응답 본문이 비어 있으면 ( []완전히 비어 있지 않은 경우) NPE가 발생할 수 있습니다 . 따라서 조심하고 null( if (forNow != null)...)를 확인하십시오 .
Ruslan Stelmachenko 님이

1
내 엉덩이를 저장 :) Object.class메소드에 지정된 때 Jackson이 사용하는 유형이 궁금 합니다 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());
}

참고 : 여기에는 Guava
vphilipnyc

2

여기서 가장 큰 문제는 RestTemplate을 호환되는 클래스와 일치시키는 데 필요한 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를 리턴 유형으로 사용하여 실제로 원하는 오브젝트 목록을 랩핑합니다. 둘째, getForObject () 대신 RestTemplate.exchange ()를 호출합니다. .

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
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.