기존에는 요청할 때 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 |