02. kakao API를 기존 HttpURLConnection에서 RestTemplate로 변경, 받은 데이터 객체화
🎈 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
리턴 타입이 KaKaoResponseDTO로 바뀐 것 확인하자.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(); } }
- 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(); } }
이제 결과를 확인해보면,
제대로 출력했다. 객체화 시켜서 생각보다 다음 과정은 잘 진행될걸로(?) 예상된다......
🎁 중간에 발생했던 문제점들
- HttpURLConnection을 사용할 때, query 값을 UTF-8로 변환해서 보냈었는데, 여기선 오히려 변환했을 때 내가 원했던 응답이 오지 않았다.
👑 해결할 점
- 멤버 데이터 중 주소를 통한 위도, 경도 얻기
- 결과 중 가게 이름 데이터를 랜덤으로 1개 선택