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를 재생한 경우와 사용하지 않은 경우의 양쪽 모두를 나타냅니다.
- 승인 없음:
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);
}
- 인증:나는 작은 방법을 좋아한다.그래서 기능을 다음과 같이 구분했습니다.
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
'programing' 카테고리의 다른 글
Vuetify를 사용하여 v-stepper-header 번호 제거 (0) | 2022.08.09 |
---|---|
Java - POST 방식으로 HTTP 파라미터를 쉽게 전송 (0) | 2022.08.09 |
gcc/g++: "그런 파일 또는 디렉터리가 없습니다." (0) | 2022.08.09 |
Synchronized(이것)를 사용할 수 있는데 ReentrantLock을 사용하는 이유는 무엇입니까? (0) | 2022.08.09 |
퀘이사 프레임워크에서 전역 개체를 저장할 위치 (0) | 2022.08.09 |