프로젝트/LunchPick

02. kakao API를 기존 HttpURLConnection에서 RestTemplate로 변경, 받은 데이터 객체화

Yanoo 2021. 12. 19. 17:44
728x90
반응형

 

🎈 RestTemplate로 변경

일단 RestTemplate로 바꾼 이유가 중요한데, 어제 진행했던 HttpURLConnection으로 진행했을 때를 보면된다.

일단 첫 번째로, 코드가 너무 길다.

물론 RestTemplate도 status code 를 처리해야할 것 같지만, 먼저 결과를 봐보면,

public KaKaoResponseDTO test() {

        final HttpHeaders headers = new HttpHeaders();
        headers.set("Authorization", "KakaoAK " + kakao_apikey);

        RestTemplate restTemplate = new RestTemplate();

        String apiURL = "https://dapi.kakao.com/v2/local/search/keyword.JSON?" +
                "query=" + "맛집"//query
                + "&category_group_code=" + "FD6"
                + "&x=" + "37.5606326"
                + "&y=" + "126.9433486"
                + "&radius=" + "100";
        final HttpEntity<String> entity = new HttpEntity<>(headers);

//        System.out.println(restTemplate.exchange(apiURL, HttpMethod.GET, entity,String.class).toString());

        return restTemplate.exchange(apiURL, HttpMethod.GET, entity,KaKaoResponseDTO.class).getBody();

    }

확실히 어제 진행했던 코드보다 많이 줄어들었다. 또한 다른 게시글을 보니 반복적 코드 작성을 피할 수 있다고 한다.

 

두 번째 이유는 사실 이 이유가 가장 컸는데, HttpURLConnection으로 데이터를 받았을 때 타입이 String이었다. 그래서 이걸 어떻게 처리할지 걱정이었다. 즉, 나는 내가 만들어 놓은 KaKaoResponseDTO라는 형식으로 응답을 받고 싶었음.

뭐 JSONObject를 사용해서 하는 방법이 있는걸로 알고있는데, 여러 방법들을 찾다가 RestTemplate으로 진행하면, 간단하게

return restTemplate.exchange(apiURL, HttpMethod.GET, entity,KaKaoResponseDTO.class).getBody();

이렇게 하면 처리가 된다고.... ㄷㄷ...

그래서 무조건 바꿔야겠다고 생각을 했다.

 

 

🎈 받은 데이터 객체화

일단 KaKaoResponseDTO라는 클래스를 만든다.

import lombok.Data;

@Data
public class KaKaoResponseDTO {
    public Document[] documents;

    @Data
    static class Document {
        public String address_name;
        public String category_group_code;
        public String category_group_name;
        public String category_name;
        public String distance;
        public String id;
        public String phone;
        public String place_name;
        public String place_url;
        public String road_address_name;
        public String x;
        public String y;
    }

}

그리고 중요한 포인트가 응답이 아래와 같다고 했을 때,

내가 필요한 것들만 받아서 처리할 수 있다는 점!!

예를 들어 가게 장소명과, 전화번호만 내가 처리하고 싶다면

import lombok.Data;

@Data
public class KaKaoResponseDTO {
    public Document[] documents;

    @Data
    static class Document {
        public String place_name;
        public String phone;
    }
}

이렇게만 하면 장소명과, 전화번호만 가져온다! 나는 일단 모든 데이터를 가져온다고 가정할 것이니, 원상복구 해놓고,

마침 바꾼 것이 파란색 패키지 뿐이니 결과 코드를 보면,

  • KaKaoAPI
    import com.lunchpick.lunchpick.controller.KaKaoResponseDTO;
    import lombok.RequiredArgsConstructor;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.http.HttpEntity;
    import org.springframework.http.HttpHeaders;
    import org.springframework.http.HttpMethod;
    import org.springframework.stereotype.Service;
    import org.springframework.web.client.RestTemplate;
    
    import java.io.BufferedReader;
    import java.io.InputStreamReader;
    import java.net.HttpURLConnection;
    import java.net.URL;
    import java.net.URLEncoder;
    
    @Service
    @RequiredArgsConstructor
    public class KakaoAPI {
    
        @Value("${kakao_apikey}")
        private String kakao_apikey;
    
        public KaKaoResponseDTO getRestaurant() {
    
            final HttpHeaders headers = new HttpHeaders();
            headers.set("Authorization", "KakaoAK " + kakao_apikey);
    
            RestTemplate restTemplate = new RestTemplate();
    
            String apiURL = "https://dapi.kakao.com/v2/local/search/keyword.JSON?" +
                    "query=" + "맛집"//query
                    + "&category_group_code=" + "FD6"
                    + "&x=" + "37.5606326"
                    + "&y=" + "126.9433486"
                    + "&radius=" + "100";
            final HttpEntity<String> entity = new HttpEntity<>(headers);
    
    //        System.out.println(restTemplate.exchange(apiURL, HttpMethod.GET, entity,String.class).toString());
    
            return restTemplate.exchange(apiURL, HttpMethod.GET, entity,KaKaoResponseDTO.class).getBody();
    
        }​
  • LocationService
    import com.lunchpick.lunchpick.controller.KaKaoResponseDTO;
    import com.lunchpick.lunchpick.service.externalAPI.KakaoAPI;
    import lombok.RequiredArgsConstructor;
    import org.springframework.stereotype.Service;
    
    
    @Service
    @RequiredArgsConstructor
    public class LocationService {
    
        private final KakaoAPI kakaoAPI;
    
        public KaKaoResponseDTO getRestaurant() {
            return kakaoAPI.getRestaurant();
        }
    
    }​
    리턴 타입이 KaKaoResponseDTO로 바뀐 것 확인하자.
  • PickController
    import com.lunchpick.lunchpick.service.LocationService;
    import lombok.RequiredArgsConstructor;
    import org.springframework.web.bind.annotation.*;
    
    @RestController
    @RequiredArgsConstructor
    public class PickController {
    
        private final LocationService locationService;
    
        @RequestMapping(value = "/test", method = RequestMethod.GET)
        @ResponseBody
        public KaKaoResponseDTO getRest() {
            return locationService.getRestaurant();
        }
    }​

이제 결과를 확인해보면,

제대로 출력했다. 객체화 시켜서 생각보다 다음 과정은 잘 진행될걸로(?) 예상된다......

 

🎁 중간에 발생했던 문제점들

  1. HttpURLConnection을 사용할 때, query 값을 UTF-8로 변환해서 보냈었는데, 여기선 오히려 변환했을 때 내가 원했던 응답이 오지 않았다.

 

👑 해결할 점

  1. 멤버 데이터 중 주소를 통한 위도, 경도 얻기
  2. 결과 중 가게 이름 데이터를 랜덤으로 1개 선택

 


 

728x90
반응형