programing

Spring RestTemplate를 사용하여 JSON 개체 목록 가져오기

projobs 2022. 8. 9. 22:34
반응형

Spring RestTemplate를 사용하여 JSON 개체 목록 가져오기

두 가지 질문이 있습니다.

  • Spring RestTemplate를 사용하여 JSON 개체 목록을 매핑하는 방법
  • 중첩된 JSON 개체를 매핑하는 방법.

http://spring.io/guides/gs/consuming-rest/의 튜토리얼에 따라 https://bitpay.com/api/rates,을 이용하려고 합니다.

먼저 어레이로 돌아오는 엔티티를 유지할 개체를 정의합니다.예.

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

위의 다른 솔루션도 사용할 수 있지만 오브젝트[]가 아닌 강력한 유형의 목록을 돌려받는 것이 좋습니다.

어쩌면 이쪽일 수도 있고...

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().

나에게 이것은 효과가 있었다.

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

여기서 오브젝트는 원하는 클래스입니다.

다음과 같이 각 엔트리에 대해 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();

POJO 목록을 원하는 경우 다음과 같은 방법이 있습니다.

class SomeObject {
    private int id;
    private String name;
}

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를 호출합니다.getForObject() 대신 exchange()를 사용합니다.

이것이 RestTemplate를 사용하는 가장 일반적인 방법입니다.HTTP 방식, 옵션 요청 본문 및 응답 유형을 지정해야 합니다.이 경우 응답 유형으로 Parameterized Type Reference의 익명 서브클래스를 사용합니다.

마지막 부분에서는 JSON 응답을 적절한 유형의 개체 목록으로 변환할 수 있습니다.ParameterizedTypeReference의 익명 서브클래스를 만들면 리플렉션을 사용하여 응답을 변환할 클래스 유형에 대한 정보를 캡처합니다.

Java의 Type 개체를 사용하여 이 정보를 유지하므로 더 이상 유형 삭제에 대해 걱정할 필요가 없습니다."

여러 번 테스트한 결과, 이것이 가장 좋은 방법입니다.

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와 호환되는 클래스를 일치시키기 위해 필요한 객체 구조를 구축하는 것이었습니다.다행히 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;
    }
}

나는 이것이 누군가에게 도움이 되기를 바란다!

제 경우 String을 추출한 후 JsonNode 인터페이스를 사용하여 컨텍스트를 참조하는 것을 선호합니다.

    var response =  restTemplate.exchange("https://my-url", HttpMethod.GET, entity,  String.class);
    if (response.getStatusCode() == HttpStatus.OK) {
        var jsonString = response.getBody();
        ObjectMapper mapper = new ObjectMapper();
        JsonNode actualObj = mapper.readTree(jsonString);           
        
        System.out.println(actualObj);  
    }

또는 빠르게

ObjectNode actualObj= restTemplate.getForObject("https://my-url", ObjectNode.class);

경로 식을 사용하여 내부 데이터를 읽습니다.

boolean b = actualObj.at("/0/states/0/no_data").asBoolean();

오브젝트 리스트를 취득하기 위한 3가지 방법이 여기에 기재되어 있습니다.이 모든 것이 완벽하게 작동한다.

@RequestMapping(value = "/emp2", produces = "application/json")
public List<Employee> getEmp2()
{
    HttpHeaders headers = new HttpHeaders();
    headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
    HttpEntity<String> entity = new HttpEntity<String>(headers);
    ResponseEntity<List<Employee>> response = restTemplate.exchange(
            "http://hello-server/rest/employees", HttpMethod.GET,entity, 
    new ParameterizedTypeReference<List<Employee>>() {});
    return response.getBody();
}

(또는)

@RequestMapping(value = "/emp3", produces = "application/json")
public List<Employee> getEmp3()
{
    Employee[] empArray = restTemplate.getForObject("http://hello-server/rest/employees", Employee[].class);
    List<Employee> emp= Arrays.asList(empArray);
    return emp;
}

(또는)

    @RequestMapping(value = "/emp4", produces = "application/json")
public Employee[] getEmp4()
{
    ResponseEntity<Employee[]> responseEntity = restTemplate.getForEntity("http://hello-server/rest/employees", Employee[].class);
    Employee[] empList = responseEntity.getBody();
    //MediaType contentType = responseEntity.getHeaders().getContentType();
    //HttpStatus statusCode = responseEntity.getStatusCode();
    return  empList;
}

Employee.class

public class Employee {

private Integer id;
private String name;
private String Designation;
private String company;

//getter setters and toString()

}

특히 에서 제네릭스를 사용하고 싶은 경우는, 이 회답을 참조해 주세요.List 목록과 같은 Spring Rest Template 및 범용 유형 Parameterized Type Reference 컬렉션 <T>

일반적인 모듈로서 »Page<?>오브젝트는 에 의해 역직렬화될 수 있다module같은JodaModule,Log4jJsonModule기타 등등. 제 답을 참고하세요.Pageable 필드를 사용하여 엔드포인트를 테스트할 때의 JsonMappingException

간단한 방법:
Authorization header를 재생한 경우와 사용하지 않은 경우의 양쪽 모두를 나타냅니다.

  1. 승인 없음:
    a. 의존성 주입(시공자 주입):현장 주입을 선호할 수도 있습니다.저는 컨스트럭터 주입을 고려했습니다.
public class RestTemplateService {
private final RestTemplate template;
public RestTemplateService(RestTemplate template) {
    this.template = template;
  }
}

b. getList() 메서드를 호출합니다.

public ResponseEntity<List> getResponseList(String url, HttpMethod type) {
    return template.exchange(url, type, new HttpEntity<>(new HttpHeaders()), List.class);
  }
  1. 인증:나는 작은 방법을 좋아한다.그래서 기능을 다음과 같이 구분했습니다.
 public ResponseEntity<List> getResponse(String url, HttpMethod type) {
    return template.exchange(url, type, getRequest(getHeaders(USERNAME, PASS)), List.class);
  }

 private HttpEntity<String> getRequest(HttpHeaders headers) {
    return new HttpEntity<>(headers);
  }

 private HttpHeaders getHeaders(String username, String password) {
    HttpHeaders headers = new HttpHeaders();
    headers.add("Authorization", "Basic " + new String(Base64.encodeBase64((username + ":" + password).getBytes())));
    return headers;
  }


이 문제가 해결되기를 바랍니다!

저는 https://jira.spring.io/browse/SPR-8263이라는 게시물에서 작업을 찾았습니다.

이 투고에 따라 다음과 같은 입력 목록을 반환할 수 있습니다.

ResponseEntity<? extends ArrayList<User>> responseEntity = restTemplate.getForEntity(restEndPointUrl, (Class<? extends ArrayList<User>>)ArrayList.class, userId);

언급URL : https://stackoverflow.com/questions/23674046/get-list-of-json-objects-with-spring-resttemplate

반응형