기존에는 요청할 때 x, y 좌표를 미리 안다고 가정하고 그 좌표 기준 맛집 데이터를 요청했었는데,
이제는 유저가 있다면 유저의 주소 기준으로 x, y 좌표를 구하고 그 좌표 기준으로 맛집 데이터를 요청하는 작업을 진행할 것이다.
일단 유저의 주소는 안다고 가정을 했다. 스프링시큐리티를 적용할 예정인데, 스프링 시큐리티에서 로그인한 유저의 정보를 가져올 수 있다고 알고 있기에... 일단 지금은 적용 안된 상태이므로 그 유저에 대한 정보를 가져와서 시작하기로 했다.
public void dbInit() { User user = new User(); user.setAge(30); user.setAddressCompany("서울 여의도구"); user.setAddressHome("서울 서대문구 이화여대1안길"); em.persist(user); }
일단 DB에 유저에 대한 정보를 넣었다.
먼저 패키지들을 보면,
이렇게 만들었다.
import com.lunchpick.lunchpick.domain.model.User; import com.lunchpick.lunchpick.service.LocationService; import com.lunchpick.lunchpick.service.UserService; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.*; @RestController @RequiredArgsConstructor public class PickController { private final LocationService locationService; private final UserService userService; @RequestMapping(value = "/test", method = RequestMethod.GET) @ResponseBody public KaKaoResponseDTO getRest() { // 로그인한 회원이 첫 번째임을 가정 User user = userService.findOne(1L); return locationService.getRestaurant(user); } }
먼저 로그인한 유저의 정보를 가져와야한다. 그런데 스프링 시큐리티를 적용하기 전이기 때문에 요청하는 컨트롤러에 저장한 유저 정보를 가져온다. UserService와 UserRepository 부분을 보면
import com.lunchpick.lunchpick.domain.model.User; import com.lunchpick.lunchpick.repository.UserRepository; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; @Service @RequiredArgsConstructor public class UserService { private final UserRepository userRepository; public User findOne(Long userId) { return userRepository.findOne(userId); } }
import com.lunchpick.lunchpick.domain.model.User; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Repository; import javax.persistence.EntityManager; @Repository @RequiredArgsConstructor public class UserRepository { private final EntityManager em; public User findOne(Long id) { return em.find(User.class, id); } }
그냥 각자의 역할에 충실하게 했다....
그리고 API를 다시 봐보면
근데 여기서 나는 address_name과 x, y값만 필요하므로, 응답 DTO를 다음과 같이 만들었다.
import lombok.Data; @Data public class LocationResponseDTO { public Document[] documents; @Data static class Document { public String address_name; public String x; public String y; } }
이제 요청하는 코드를 보면,
import com.lunchpick.lunchpick.controller.KaKaoResponseDTO; import com.lunchpick.lunchpick.domain.model.User; 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(User user) { LocationResponseDTO coordinate = getCoordinate(user); 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=" + coordinate.documents[0].x + "&y=" + coordinate.documents[0].y + "&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(); } public LocationResponseDTO getCoordinate(User user) { String address = user.getAddressHome(); final HttpHeaders headers = new HttpHeaders(); headers.set("Authorization", "KakaoAK " + kakao_apikey); RestTemplate restTemplate = new RestTemplate(); String apiURL = "https://dapi.kakao.com/v2/local/search/address.JSON?" + "query=" + address; final HttpEntity<String> entity = new HttpEntity<>(headers); return restTemplate.exchange(apiURL, HttpMethod.GET, entity,LocationResponseDTO.class).getBody(); } }
getCoordinate 메서드는 User 객체를 파라미터로 받아 주소에 대한 x, y 좌표를 담음 LocationResponseDTO 객체로 리턴한다.
이제 LocationService에서 요청을 관리한다.
import com.lunchpick.lunchpick.controller.KaKaoResponseDTO; import com.lunchpick.lunchpick.domain.model.User; 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(User user) { return kakaoAPI.getRestaurant(user); } }
아까 Controller 코드는 올렸으므로 끝이다.
결과를 확인해보면,
정상적으로 출력했다.
기존에 했던거에서 같은 것들을 추가하는 것이라 문제는 발생하지 않았다.
02. kakao API를 기존 HttpURLConnection에서 RestTemplate로 변경, 받은 데이터 객체화 (2) | 2021.12.19 |
---|---|
01. kakao API 호출, git에 API key 숨기기 ( 스프링 ) (0) | 2021.12.18 |