본문 바로가기
카카오 API

Rest Template 통해 Kakao map API 호출하기 + 데이터 추출

by 반오십 코린이 2023. 2. 13.
728x90
Client 역할을 하는 Postman에서 위도 경도를 백앤드 서버로 보내보자

 

 

다음과 같은 위도 경도 정보를 Body에 실어 Request를 백앤드 서버로 보내자.

uri 정보를 인지하고 다음으로 넘어가자


API 통신을 통해 보낼 데이터를 만들자. (Postman에서 보낸 data와 임의로 지정한 파라미터를 동시에 담자)

 

 

MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
params.add("y", form.getLatitude()); // y는 위도이다.
params.add("x", form.getLongitude()); // x는 경도이다.
params.add("page", "0");
params.add("category_group_code", "CS2");
params.add("radius", "20000"); //근방 2km의 편의점을 조회
params.add("sort", "distance");

RestTemplate 핵심 코드

 

 

RestTemplate rest = new RestTemplate();
HttpHeaders httpHeaders = new HttpHeaders();

//헤더 세팅
httpHeaders.set("Authorization", "KakaoAK " + kakaoProperties.getRestapi());

HttpEntity<String> httpEntity = new HttpEntity<>(httpHeaders);

while (is_end == "false") {
    page+=1;
    params.remove("page");
    params.add("page", Integer.toString(page));

    //한번에 페이지 하나만 불러올 수 있음
    URI targetUrl = UriComponentsBuilder
            .fromUriString("https://dapi.kakao.com/v2/local/search/category.json")
            .queryParams(params)
            .build()
            .encode()
            .toUri();
    //post 방식 보내기
    ResponseEntity<String> res = rest.exchange(targetUrl, HttpMethod.POST, httpEntity, String.class);

 

RestTemplate 객체를 생성하고 헤더를 세팅한다.

헤더에는 rest api 인증키 값이 들어가는 곳이라 생각하면 된다.

HttpEntity에 헤더를 넣고

URL에 접속하려는 api uri 정보를 입력하고

 

exchange 메서드를 사용하여 post 방식으로 String 형식으로 ResponseEntity를 반환 받는다.


데이터 추출하기

 

 

//String to json 역할을 하는 method
JSONParser jsonParser = new JSONParser();

//res의 body 부분을 담을 곳
JSONObject body = null;

//String to json 시도
try {
    body = (JSONObject) jsonParser.parse(res.getBody().toString());
} catch (ParseException e) {
    logger.info("변환 실패");
    e.printStackTrace();
}
//마지막 페이지 여부 확인 - meta에서 is_end 추출 가능
JSONObject meta = (JSONObject) body.get("meta");

//documents를 열어보면 JsonArray가 추출됨
JSONArray docu = (JSONArray) body.get("documents");

//헤당 페이지가 마지막이 아닐경우
if (docu.size() != 0) {
    for (int i = 0; i < docu.size(); i++) {
        JSONObject temp = (JSONObject) docu.get(i);
        logger.info("편의점 :: {}", temp);
    }
}
//object to String
is_end = String.valueOf(meta.get("is_end"));
logger.info("is_end :: {}",is_end);

 

String to json 역할을 하는 메서드인 JSONParser을 만들고 result의 body 부분을 담을 JSONObject를 생성한다.

JSONParser을 통해 json으로 변환하는데 예외 처리를 해주기 위해 try catch문 사용..



JSONObject meta = (JSONObject) body.get("meta");

 

meta에서 페이지의 마지막인지 여부를 확인하기 위한 is_end 값을 추출하기 위해 다음과 같은 코드 사용


JSONArray docu = (JSONArray) body.get("documents");

 

documents에서 핵심 데이터를 추출할 수 있기 때문에 다음과 같은 코드 사용


//헤당 페이지가 마지막이 아닐경우
if (docu.size() != 0) {
    for (int i = 0; i < docu.size(); i++) {
        JSONObject temp = (JSONObject) docu.get(i);
        logger.info("편의점 :: {}", temp);
    }
}
//object to String
is_end = String.valueOf(meta.get("is_end"));
logger.info("is_end :: {}",is_end);

 

추출한 docu의 사이즈를 통해 반복문 실행 여부를 결정하고

해당 사이즈 만큼 데이터를 추출하여 로거로 찍어본다.

 

is_end의 값을 통해 api 요청을 한번 더 보낼지 말지를 결정하기에

Object 자료형인 meta.get("is_end")를 String 형으로 바꾸기 위해

String.valueOf() 문법을 활용.


전체 코드

 

 

@RestController
@RequiredArgsConstructor
@RequestMapping("/facility/*")
public class FacilityController {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());
    private final KakaoProperties kakaoProperties;
    
    @PostMapping("/search")
    public void search(@RequestBody FacilityForm form) {
        String is_end = "false";
        int page = 0;
        MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
        params.add("y", form.getLatitude()); // y는 위도이다.
        params.add("x", form.getLongitude()); // x는 경도이다.
        params.add("page", "0");
        params.add("category_group_code", "CS2");
        params.add("radius", "2000"); //근방 2km의 편의점을 조회
        params.add("sort", "distance");

        RestTemplate rest = new RestTemplate();
        HttpHeaders httpHeaders = new HttpHeaders();

        //헤더 세팅
        httpHeaders.set("Authorization", "KakaoAK " + kakaoProperties.getRestapi());

        HttpEntity<String> httpEntity = new HttpEntity<>(httpHeaders);

        while (is_end == "false") {
            page+=1;
            params.remove("page");
            params.add("page", Integer.toString(page));

            //한번에 페이지 하나만 불러올 수 있음
            URI targetUrl = UriComponentsBuilder
                    .fromUriString("https://dapi.kakao.com/v2/local/search/category.json")
                    .queryParams(params)
                    .build()
                    .encode()
                    .toUri();
            //post 방식 보내기
            ResponseEntity<String> res = rest.exchange(targetUrl, HttpMethod.POST, httpEntity, String.class);

            //String to json 역할을 하는 method
            JSONParser jsonParser = new JSONParser();

            //res의 body 부분을 담을 곳
            JSONObject body = null;

            //String to json 시도
            try {
                body = (JSONObject) jsonParser.parse(res.getBody().toString());
            } catch (ParseException e) {
                logger.info("변환 실패");
                e.printStackTrace();
            }
            //마지막 페이지 여부 확인 - meta에서 is_end 추출 가능
            JSONObject meta = (JSONObject) body.get("meta");

            //documents를 열어보면 JsonArray가 추출됨
            JSONArray docu = (JSONArray) body.get("documents");

            //헤당 페이지가 마지막이 아닐경우
            if (docu.size() != 0) {
                for (int i = 0; i < docu.size(); i++) {
                    JSONObject temp = (JSONObject) docu.get(i);
                    logger.info("편의점 :: {}", temp);
                }
            }
            //object to String
            is_end = String.valueOf(meta.get("is_end"));
            logger.info("is_end :: {}",is_end);
        }
    }



}
728x90