외부 API로부터 데이터 받아오기

aj4941·2023년 7월 19일
0

이번 프로젝트를 진행하면서 solved.ac를 이용하여 API를 호출하여 원하는
데이터를 가져오는 작업을 진행해보았다.

WebClient

먼저 외부에 http 요청을 보낸 후 해당 요청의 응답 데이터를 가져와야 했고 여기서 WebClient를 사용했다.

WebClient webClient = WebClient.builder().build();
            String jsonString = webClient.get()
                    .uri(apiUrl + "?query=" + query + "&page=1" + "&sort=random")
                    .retrieve()
                    .bodyToMono(String.class)
                    .block();

먼저 builder().build()를 통해 WebClient를 만들고 uri를 보낸다.
그리고 retrieve를 통해 응답을 받아오며 bodyToMono를 통해 Mono 스트림으로 변환을 하는 과정에서 String.class를 지정하여 문자열로 변환한다.
그리고 .block() 에서 메서드를 호출하면 현재 스레드가 블로킹되어서 Mono 결과 값이 준비될 때까지 기다린다. 여기서 코드가 실행이 된다면 응답 데이터가 문자열로 변환된 후에 다음 코드로 진행된다.

ObjectMapper, JsonNode

이제 받아온 jsonString으로 받아온 JSON 데이터를 Java 클래스의 필드 값으로
변환하여 원하는 형태로 저장 할 필요가 있다.

ObjectMapper mapper = new ObjectMapper();
JsonNode rootNode = mapper.readTree(jsonString);
JsonNode itemsArray = rootNode.get("items");
if (itemsArray != null && itemsArray.isArray() && itemsArray.size() > 0) {
    JsonNode firstProblem = itemsArray.get(0);
    BojProblem bojProblem = mapper.treeToValue(firstProblem, BojProblem.class);
    System.out.println("bojProblemId : " + bojProblem.getProblemId() + "level : " + bojProblem.getLevel());           
}

ObjectMapper는 Json 데이터와 Java 객체 간의 변환을 담당한다.
그리고 JsonNode는 jsonString을 ObjectMapper를 사용해 파싱하여 JsonNode 객체로 변환한다. JsonNode는 Json 데이터의 노드를 나타내는 객체로 여기서는 전체 Json 데이터를 rootNode로 저장했다.
이렇게 저장된 rootNode에서 "items" 키에 해당하는 값을 추출하여 JsonNode 객체인 itemsArray에 저장했다.
그리고 여기서 문제 데이터의 개수가 1000개가 넘는 경우도 있었는데 내가 원하는건 1개의 데이터였고 이를 위해 itemsArray.get(0)으로 하나의 데이터만 가져오도록 했다.
그리고 ObjectMapper를 통해 이 firstProblem에 나온 Json 데이터를 BojProblem의 필드에 맞춰서 넣었다.

@JsonIgnoreProperties

@Getter @Setter
@AllArgsConstructor
@NoArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
public class BojProblem {
    private Long problemId;
    private Integer level;
}

추가로 Json 데이터에 나온 값들이 너무 많았고 필요없는 정보들도 있었다.
여기서 유의미한 데이터인 문제 번호와 난이도만 얻고 싶었고 이것을 @JsonIgnoreProperties(ignoreUnknown = true)로 해결할 수 있었다.
이 ignoreUnknown = true인 경우 클래스 필드에 맞지 않는 데이터가 올 경우 클래스 필드에
넣으려는 시도를 하지 않고 패스한다. 만약 false로 지정을 한다면 오류가 발생할 것이다.

profile
안녕하세요 aj4941 입니다.

0개의 댓글