From 212725a5729d64c7808bfe9b539d37828d80efbf Mon Sep 17 00:00:00 2001 From: tobbot16 Date: Fri, 19 Dec 2025 11:23:38 +0900 Subject: [PATCH 1/7] =?UTF-8?q?feat:=20dto=20=ED=8C=8C=EC=9D=BC=20?= =?UTF-8?q?=EC=9D=B4=EB=8F=99=20=EB=B0=8F=20=EC=B9=B4=EC=B9=B4=EC=98=A4=20?= =?UTF-8?q?=EB=84=A4=EB=B9=84=20=EC=84=9C=EB=B9=84=EC=8A=A4=20=ED=8C=8C?= =?UTF-8?q?=EC=9D=BC=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/location/controller/KakaoApiController.java | 2 +- .../location/dto/{ => response}/KakaoLocalResponse.java | 2 +- .../domain/location/dto/{ => response}/TmapResponse.java | 2 +- .../domain/location/service/KakaoLocalService.java | 2 +- .../domain/location/service/KakaoNaviService.java | 7 +++++++ .../domain/location/service/LocationService.java | 3 --- .../domain/location/service/TmapService.java | 3 +-- .../domain/location/service/KakaoLocalServiceTest.java | 2 +- .../domain/location/service/TmapServiceTest.java | 6 ------ 9 files changed, 13 insertions(+), 16 deletions(-) rename src/main/java/com/back/web7_9_codecrete_be/domain/location/dto/{ => response}/KakaoLocalResponse.java (94%) rename src/main/java/com/back/web7_9_codecrete_be/domain/location/dto/{ => response}/TmapResponse.java (92%) create mode 100644 src/main/java/com/back/web7_9_codecrete_be/domain/location/service/KakaoNaviService.java diff --git a/src/main/java/com/back/web7_9_codecrete_be/domain/location/controller/KakaoApiController.java b/src/main/java/com/back/web7_9_codecrete_be/domain/location/controller/KakaoApiController.java index 594d4639..ca686878 100644 --- a/src/main/java/com/back/web7_9_codecrete_be/domain/location/controller/KakaoApiController.java +++ b/src/main/java/com/back/web7_9_codecrete_be/domain/location/controller/KakaoApiController.java @@ -1,6 +1,6 @@ package com.back.web7_9_codecrete_be.domain.location.controller; -import com.back.web7_9_codecrete_be.domain.location.dto.KakaoLocalResponse; +import com.back.web7_9_codecrete_be.domain.location.dto.response.KakaoLocalResponse; import com.back.web7_9_codecrete_be.domain.location.service.KakaoLocalService; import com.back.web7_9_codecrete_be.global.rsData.RsData; import io.swagger.v3.oas.annotations.Operation; diff --git a/src/main/java/com/back/web7_9_codecrete_be/domain/location/dto/KakaoLocalResponse.java b/src/main/java/com/back/web7_9_codecrete_be/domain/location/dto/response/KakaoLocalResponse.java similarity index 94% rename from src/main/java/com/back/web7_9_codecrete_be/domain/location/dto/KakaoLocalResponse.java rename to src/main/java/com/back/web7_9_codecrete_be/domain/location/dto/response/KakaoLocalResponse.java index 46dcaf31..8b1ecda3 100644 --- a/src/main/java/com/back/web7_9_codecrete_be/domain/location/dto/KakaoLocalResponse.java +++ b/src/main/java/com/back/web7_9_codecrete_be/domain/location/dto/response/KakaoLocalResponse.java @@ -1,4 +1,4 @@ -package com.back.web7_9_codecrete_be.domain.location.dto; +package com.back.web7_9_codecrete_be.domain.location.dto.response; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; diff --git a/src/main/java/com/back/web7_9_codecrete_be/domain/location/dto/TmapResponse.java b/src/main/java/com/back/web7_9_codecrete_be/domain/location/dto/response/TmapResponse.java similarity index 92% rename from src/main/java/com/back/web7_9_codecrete_be/domain/location/dto/TmapResponse.java rename to src/main/java/com/back/web7_9_codecrete_be/domain/location/dto/response/TmapResponse.java index 87121037..3c07c0e2 100644 --- a/src/main/java/com/back/web7_9_codecrete_be/domain/location/dto/TmapResponse.java +++ b/src/main/java/com/back/web7_9_codecrete_be/domain/location/dto/response/TmapResponse.java @@ -1,4 +1,4 @@ -package com.back.web7_9_codecrete_be.domain.location.dto; +package com.back.web7_9_codecrete_be.domain.location.dto.response; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; diff --git a/src/main/java/com/back/web7_9_codecrete_be/domain/location/service/KakaoLocalService.java b/src/main/java/com/back/web7_9_codecrete_be/domain/location/service/KakaoLocalService.java index b8299297..51922f39 100644 --- a/src/main/java/com/back/web7_9_codecrete_be/domain/location/service/KakaoLocalService.java +++ b/src/main/java/com/back/web7_9_codecrete_be/domain/location/service/KakaoLocalService.java @@ -1,7 +1,7 @@ package com.back.web7_9_codecrete_be.domain.location.service; import com.back.web7_9_codecrete_be.domain.location.dto.KakaoCoordinateResponse; -import com.back.web7_9_codecrete_be.domain.location.dto.KakaoLocalResponse; +import com.back.web7_9_codecrete_be.domain.location.dto.response.KakaoLocalResponse; import com.back.web7_9_codecrete_be.global.error.code.LocationErrorCode; import com.back.web7_9_codecrete_be.global.error.exception.BusinessException; import lombok.RequiredArgsConstructor; diff --git a/src/main/java/com/back/web7_9_codecrete_be/domain/location/service/KakaoNaviService.java b/src/main/java/com/back/web7_9_codecrete_be/domain/location/service/KakaoNaviService.java new file mode 100644 index 00000000..1f5569d9 --- /dev/null +++ b/src/main/java/com/back/web7_9_codecrete_be/domain/location/service/KakaoNaviService.java @@ -0,0 +1,7 @@ +package com.back.web7_9_codecrete_be.domain.location.service; + +//카카오 api를 이용한 자동차 길찾기 +public class KakaoNaviService { + + +} diff --git a/src/main/java/com/back/web7_9_codecrete_be/domain/location/service/LocationService.java b/src/main/java/com/back/web7_9_codecrete_be/domain/location/service/LocationService.java index 262dcaa2..468ee645 100644 --- a/src/main/java/com/back/web7_9_codecrete_be/domain/location/service/LocationService.java +++ b/src/main/java/com/back/web7_9_codecrete_be/domain/location/service/LocationService.java @@ -1,13 +1,10 @@ package com.back.web7_9_codecrete_be.domain.location.service; -import com.back.web7_9_codecrete_be.domain.location.dto.KakaoLocalResponse; import com.back.web7_9_codecrete_be.domain.location.dto.request.LocationRequestDto; import com.back.web7_9_codecrete_be.domain.location.dto.response.LocationResponseDto; import com.back.web7_9_codecrete_be.domain.location.entity.Location; import com.back.web7_9_codecrete_be.domain.location.repository.LocationRepository; import com.back.web7_9_codecrete_be.domain.users.entity.User; -import com.back.web7_9_codecrete_be.domain.users.repository.UserRepository; -import com.back.web7_9_codecrete_be.global.error.code.AuthErrorCode; import com.back.web7_9_codecrete_be.global.error.code.LocationErrorCode; import com.back.web7_9_codecrete_be.global.error.exception.BusinessException; import lombok.RequiredArgsConstructor; diff --git a/src/main/java/com/back/web7_9_codecrete_be/domain/location/service/TmapService.java b/src/main/java/com/back/web7_9_codecrete_be/domain/location/service/TmapService.java index 055166d3..a5fc5e41 100644 --- a/src/main/java/com/back/web7_9_codecrete_be/domain/location/service/TmapService.java +++ b/src/main/java/com/back/web7_9_codecrete_be/domain/location/service/TmapService.java @@ -1,7 +1,6 @@ package com.back.web7_9_codecrete_be.domain.location.service; -import com.back.web7_9_codecrete_be.domain.location.dto.KakaoLocalResponse; -import com.back.web7_9_codecrete_be.domain.location.dto.TmapResponse; +import com.back.web7_9_codecrete_be.domain.location.dto.response.TmapResponse; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.web.reactive.function.client.WebClient; diff --git a/src/test/java/com/back/web7_9_codecrete_be/domain/location/service/KakaoLocalServiceTest.java b/src/test/java/com/back/web7_9_codecrete_be/domain/location/service/KakaoLocalServiceTest.java index a44046f1..2ffb4073 100644 --- a/src/test/java/com/back/web7_9_codecrete_be/domain/location/service/KakaoLocalServiceTest.java +++ b/src/test/java/com/back/web7_9_codecrete_be/domain/location/service/KakaoLocalServiceTest.java @@ -1,6 +1,6 @@ package com.back.web7_9_codecrete_be.domain.location.service; -import com.back.web7_9_codecrete_be.domain.location.dto.KakaoLocalResponse; +import com.back.web7_9_codecrete_be.domain.location.dto.response.KakaoLocalResponse; import com.back.web7_9_codecrete_be.global.config.WebClientConfig; import com.back.web7_9_codecrete_be.global.error.exception.BusinessException; import okhttp3.mockwebserver.MockResponse; diff --git a/src/test/java/com/back/web7_9_codecrete_be/domain/location/service/TmapServiceTest.java b/src/test/java/com/back/web7_9_codecrete_be/domain/location/service/TmapServiceTest.java index d00223f4..de782c10 100644 --- a/src/test/java/com/back/web7_9_codecrete_be/domain/location/service/TmapServiceTest.java +++ b/src/test/java/com/back/web7_9_codecrete_be/domain/location/service/TmapServiceTest.java @@ -1,6 +1,5 @@ package com.back.web7_9_codecrete_be.domain.location.service; -import com.back.web7_9_codecrete_be.domain.location.dto.KakaoLocalResponse; import com.back.web7_9_codecrete_be.global.config.WebClientConfig; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; @@ -9,17 +8,12 @@ import org.junit.jupiter.api.TestInstance; import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.context.annotation.Import; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.DynamicPropertyRegistry; import org.springframework.test.context.DynamicPropertySource; import org.springframework.test.context.junit.jupiter.SpringExtension; import java.io.IOException; -import java.net.URLEncoder; -import java.nio.charset.StandardCharsets; -import java.util.List; import static org.assertj.core.api.Assertions.assertThat; From d27cf5ff1f678fa70e4dce07fa1002cb937f60bd Mon Sep 17 00:00:00 2001 From: tobbot16 Date: Fri, 19 Dec 2025 12:16:01 +0900 Subject: [PATCH 2/7] =?UTF-8?q?feat:=20WebClient=20->=20RestClient?= =?UTF-8?q?=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../global/config/WebClientConfig.java | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/back/web7_9_codecrete_be/global/config/WebClientConfig.java b/src/main/java/com/back/web7_9_codecrete_be/global/config/WebClientConfig.java index 01ad8736..6441c9f5 100644 --- a/src/main/java/com/back/web7_9_codecrete_be/global/config/WebClientConfig.java +++ b/src/main/java/com/back/web7_9_codecrete_be/global/config/WebClientConfig.java @@ -7,6 +7,7 @@ import org.springframework.http.MediaType; import org.springframework.http.client.ClientHttpRequestInterceptor; import org.springframework.http.client.reactive.ReactorClientHttpConnector; +import org.springframework.web.client.RestClient; import org.springframework.web.client.RestTemplate; import org.springframework.web.reactive.function.client.WebClient; @@ -61,19 +62,21 @@ public RestTemplate restTemplate() { return restTemplate; } + @Bean - public WebClient kakaoWebClient() { + public RestClient kakaoRestClient(){ - return WebClient.builder() + return RestClient.builder() .baseUrl(kakaoBaseUrl) .defaultHeader("Authorization", kakaomapApiKey) .build(); + } @Bean - public WebClient TmapClient(){ - return WebClient.builder() + public RestClient TmapRestClient(){ + return RestClient.builder() .baseUrl(tmapBaseUrl) .defaultHeader("appKey", tmapApiKey) .build(); From cad20c43262b760f25180e9c6927ce46a27e077b Mon Sep 17 00:00:00 2001 From: tobbot16 Date: Mon, 22 Dec 2025 02:15:08 +0900 Subject: [PATCH 3/7] =?UTF-8?q?feat:=20kakaomap=EC=9D=84=20tmap=EA=B3=BC?= =?UTF-8?q?=20=EB=B9=84=EC=8A=B7=C3=AD=ED=95=98=EA=B2=8C=20=EC=9D=91?= =?UTF-8?q?=EB=8B=B5=ED=95=98=EA=B2=8C=20=EC=A4=80=EB=B9=84=EC=A4=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/KakaoApiController.java | 31 ++++++++++- .../dto/response/KakaoMobilityResponse.java | 52 +++++++++++++++++++ .../location/service/KakaoLocalService.java | 42 +++++++++++---- .../location/service/KakaoNaviService.java | 7 --- .../domain/location/service/TmapService.java | 27 +++++----- .../global/config/WebClientConfig.java | 12 +++++ .../global/error/code/LocationErrorCode.java | 3 +- 7 files changed, 142 insertions(+), 32 deletions(-) create mode 100644 src/main/java/com/back/web7_9_codecrete_be/domain/location/dto/response/KakaoMobilityResponse.java delete mode 100644 src/main/java/com/back/web7_9_codecrete_be/domain/location/service/KakaoNaviService.java diff --git a/src/main/java/com/back/web7_9_codecrete_be/domain/location/controller/KakaoApiController.java b/src/main/java/com/back/web7_9_codecrete_be/domain/location/controller/KakaoApiController.java index ca686878..f7b17505 100644 --- a/src/main/java/com/back/web7_9_codecrete_be/domain/location/controller/KakaoApiController.java +++ b/src/main/java/com/back/web7_9_codecrete_be/domain/location/controller/KakaoApiController.java @@ -1,6 +1,7 @@ package com.back.web7_9_codecrete_be.domain.location.controller; import com.back.web7_9_codecrete_be.domain.location.dto.response.KakaoLocalResponse; +import com.back.web7_9_codecrete_be.domain.location.dto.response.KakaoMobilityResponse; import com.back.web7_9_codecrete_be.domain.location.service.KakaoLocalService; import com.back.web7_9_codecrete_be.global.rsData.RsData; import io.swagger.v3.oas.annotations.Operation; @@ -32,7 +33,7 @@ public class KakaoApiController { public List KakaoRestaurants( @RequestParam double lat, @RequestParam double lon - ){ + ) { return kakaoLocalService.searchNearbyRestaurants(lat, lon); } @@ -46,7 +47,7 @@ public List KakaoRestaurants( public List KakaoCafes( @RequestParam double lat, @RequestParam double lon - ){ + ) { return kakaoLocalService.searchNearbyCafes(lat, lon); } @@ -68,4 +69,30 @@ public RsData coord2Address( String addressName = kakaoLocalService.coordinateToAddressName(lat, lon); return RsData.success("좌표를 주소로 변환했습니다.", addressName); } + + + @GetMapping("/navigate/guides") + public List navigateGuides( + @RequestParam double startX, + @RequestParam double startY, + @RequestParam double endX, + @RequestParam double endY + ) { + KakaoMobilityResponse res = kakaoLocalService.NaviSearch(startX, startY, endX, endY); + + if (res == null || res.getRoutes() == null || res.getRoutes().isEmpty()) { + return List.of(); + } + + KakaoMobilityResponse.Route route0 = res.getRoutes().get(0); + if (route0.getSections() == null || route0.getSections().isEmpty()) { + return List.of(); + } + + return route0.getSections().stream() + .filter(section -> section.getGuides() != null && !section.getGuides().isEmpty()) + .flatMap(section -> section.getGuides().stream()) + .toList(); + } } + diff --git a/src/main/java/com/back/web7_9_codecrete_be/domain/location/dto/response/KakaoMobilityResponse.java b/src/main/java/com/back/web7_9_codecrete_be/domain/location/dto/response/KakaoMobilityResponse.java new file mode 100644 index 00000000..74ebaf64 --- /dev/null +++ b/src/main/java/com/back/web7_9_codecrete_be/domain/location/dto/response/KakaoMobilityResponse.java @@ -0,0 +1,52 @@ +package com.back.web7_9_codecrete_be.domain.location.dto.response; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.util.List; +@Getter +@AllArgsConstructor +public class KakaoMobilityResponse { + + + private List routes; + + @Getter + public static class Route { + private Summary summary; + private List
sections; + } + + @Getter + public static class Summary { + private int distance; // meters + private int duration; // seconds + } + + @Getter + public static class Section{ + private List roads; + private List guides; + public List getGuides() { + return guides; + } + } + + @Getter + public static class Road{ + private List vertexes; + } + + + @Getter + public static class Guide { // ✅ 추가 + private String name; + private double x; + private double y; + private int distance; + private int duration; + private int type; + private String guidance; + private int road_index; + } +} diff --git a/src/main/java/com/back/web7_9_codecrete_be/domain/location/service/KakaoLocalService.java b/src/main/java/com/back/web7_9_codecrete_be/domain/location/service/KakaoLocalService.java index 51922f39..b9a11de2 100644 --- a/src/main/java/com/back/web7_9_codecrete_be/domain/location/service/KakaoLocalService.java +++ b/src/main/java/com/back/web7_9_codecrete_be/domain/location/service/KakaoLocalService.java @@ -2,10 +2,12 @@ import com.back.web7_9_codecrete_be.domain.location.dto.KakaoCoordinateResponse; import com.back.web7_9_codecrete_be.domain.location.dto.response.KakaoLocalResponse; +import com.back.web7_9_codecrete_be.domain.location.dto.response.KakaoMobilityResponse; import com.back.web7_9_codecrete_be.global.error.code.LocationErrorCode; import com.back.web7_9_codecrete_be.global.error.exception.BusinessException; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; +import org.springframework.web.client.RestClient; import org.springframework.web.reactive.function.client.WebClient; import java.util.List; @@ -14,14 +16,16 @@ @RequiredArgsConstructor public class KakaoLocalService { - private final WebClient kakaoWebClient; + private final RestClient kakaoRestClient; + private final RestClient kakaoMobilityClient; public List searchNearbyRestaurants(double lat, double lng) { - return kakaoWebClient.get() + return kakaoRestClient.get() .uri(uriBuilder -> uriBuilder .path("/v2/local/search/keyword.json") .queryParam("query", "음식점") + .queryParam("category_group_code", "FD6") .queryParam("y", lat) .queryParam("x", lng) .queryParam("radius", 1000) // 반경 1km @@ -29,13 +33,12 @@ public List searchNearbyRestaurants(double lat, dou .build() ) .retrieve() - .bodyToMono(KakaoLocalResponse.class) - .block() // 동기 호출 (필요하면 비동기로 변경 가능) + .body(KakaoLocalResponse.class) .getDocuments(); } public List searchNearbyCafes(double lat, double lng) { - return kakaoWebClient.get() + return kakaoRestClient.get() .uri(uriBuilder -> uriBuilder .path("/v2/local/search/keyword.json") .queryParam("query", "카페") @@ -47,14 +50,13 @@ public List searchNearbyCafes(double lat, double ln .build() ) .retrieve() - .bodyToMono(KakaoLocalResponse.class) - .block() // 동기 호출 (필요하면 비동기로 변경 가능) + .body(KakaoLocalResponse.class) .getDocuments(); } public String coordinateToAddressName(double lat, double lng) { - KakaoCoordinateResponse response = kakaoWebClient.get() + KakaoCoordinateResponse response = kakaoRestClient.get() .uri(uriBuilder -> uriBuilder .path("/v2/local/geo/coord2address.json") .queryParam("x", lng) @@ -62,8 +64,7 @@ public String coordinateToAddressName(double lat, double lng) { .build() ) .retrieve() - .bodyToMono(KakaoCoordinateResponse.class) - .block(); + .body(KakaoCoordinateResponse.class); if (response == null || response.getDocuments() == null || response.getDocuments().isEmpty()) { throw new BusinessException(LocationErrorCode.ADDRESS_NOT_FOUND); @@ -85,4 +86,25 @@ public String coordinateToAddressName(double lat, double lng) { return addressName; } + public KakaoMobilityResponse NaviSearch(double startX, double startY, double endX, double endY) { + + KakaoMobilityResponse response = kakaoMobilityClient.get() + .uri(uriBuilder -> uriBuilder + .path("/v1/directions") + .queryParam("origin", startX + "," + startY) + .queryParam("destination", endX + "," + endY) + .queryParam("priority", "TIME") + .queryParam("summary", "false") + .build() + ) + .retrieve() + .body(KakaoMobilityResponse.class); + + + if (response == null || response.getRoutes().isEmpty()) { + throw new BusinessException(LocationErrorCode.ROUTE_NOT_FOUND); + } + + return response; + } } \ No newline at end of file diff --git a/src/main/java/com/back/web7_9_codecrete_be/domain/location/service/KakaoNaviService.java b/src/main/java/com/back/web7_9_codecrete_be/domain/location/service/KakaoNaviService.java deleted file mode 100644 index 1f5569d9..00000000 --- a/src/main/java/com/back/web7_9_codecrete_be/domain/location/service/KakaoNaviService.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.back.web7_9_codecrete_be.domain.location.service; - -//카카오 api를 이용한 자동차 길찾기 -public class KakaoNaviService { - - -} diff --git a/src/main/java/com/back/web7_9_codecrete_be/domain/location/service/TmapService.java b/src/main/java/com/back/web7_9_codecrete_be/domain/location/service/TmapService.java index a5fc5e41..bf2697c8 100644 --- a/src/main/java/com/back/web7_9_codecrete_be/domain/location/service/TmapService.java +++ b/src/main/java/com/back/web7_9_codecrete_be/domain/location/service/TmapService.java @@ -2,30 +2,33 @@ import com.back.web7_9_codecrete_be.domain.location.dto.response.TmapResponse; import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.http.MediaType; import org.springframework.stereotype.Service; +import org.springframework.web.client.RestClient; import org.springframework.web.reactive.function.client.WebClient; @Service @RequiredArgsConstructor public class TmapService { - private final WebClient TmapClient; + private final RestClient TmapRestClient; public String getRoute(double startX, double startY, double endX, double endY) { - TmapResponse request = new TmapResponse(); - request.setStartX(String.valueOf(startX)); - request.setStartY(String.valueOf(startY)); - request.setEndX(String.valueOf(endX)); - request.setEndY(String.valueOf(endY)); - request.setFormat("json"); - request.setCount(5); + TmapResponse req = new TmapResponse(); + req.setStartX(String.valueOf(startX)); + req.setStartY(String.valueOf(startY)); + req.setEndX(String.valueOf(endX)); + req.setEndY(String.valueOf(endY)); + req.setCount(5); + req.setFormat("json"); - return TmapClient.post() + return TmapRestClient.post() .uri("/transit/routes") - .bodyValue(request) + .contentType(MediaType.APPLICATION_JSON) + .body(req) .retrieve() - .bodyToMono(String.class) - .block(); + .body(String.class); } } diff --git a/src/main/java/com/back/web7_9_codecrete_be/global/config/WebClientConfig.java b/src/main/java/com/back/web7_9_codecrete_be/global/config/WebClientConfig.java index 6441c9f5..2d928360 100644 --- a/src/main/java/com/back/web7_9_codecrete_be/global/config/WebClientConfig.java +++ b/src/main/java/com/back/web7_9_codecrete_be/global/config/WebClientConfig.java @@ -36,6 +36,10 @@ public class WebClientConfig { @Value("${tmap.base-url}") private String tmapBaseUrl; + + @Value("https://apis-navi.kakaomobility.com") + private String kakaoMobilityUrl; + @Bean public WebClient mailgunClient() { String auth = "api:" + mailgunApiKey; @@ -73,6 +77,14 @@ public RestClient kakaoRestClient(){ } + @Bean + public RestClient kakaoMobilityClient(){ + return RestClient.builder() + .baseUrl(kakaoMobilityUrl) + .defaultHeader("Authorization", kakaomapApiKey) + .build(); + + } @Bean public RestClient TmapRestClient(){ diff --git a/src/main/java/com/back/web7_9_codecrete_be/global/error/code/LocationErrorCode.java b/src/main/java/com/back/web7_9_codecrete_be/global/error/code/LocationErrorCode.java index c18a2bcd..e16c8029 100644 --- a/src/main/java/com/back/web7_9_codecrete_be/global/error/code/LocationErrorCode.java +++ b/src/main/java/com/back/web7_9_codecrete_be/global/error/code/LocationErrorCode.java @@ -13,7 +13,8 @@ public enum LocationErrorCode implements ErrorCode{ LOCATION_ALREADY_EXISTS(HttpStatus.NOT_FOUND, "L-102", "이미 저장되어있는 위치입니다."), INVALID_KOREA_COORDINATE(HttpStatus.NOT_FOUND, "L-103" , "한국 좌표가 아닙니다"), LOCATION_NOT_EXIST_IN_KAKAO(HttpStatus.NOT_FOUND, "L-104", "해당 좌표는 카카오에 등록되어있지 않습니다."), - LOCATION_NOT_HAVE(HttpStatus.NOT_FOUND, "L-105", "저장되어있는 좌표가 없어서 삭제가 불가능합니다."); + LOCATION_NOT_HAVE(HttpStatus.NOT_FOUND, "L-105", "저장되어있는 좌표가 없어서 삭제가 불가능합니다."), + ROUTE_NOT_FOUND(HttpStatus.NOT_FOUND, "L-106", "추천 경로가 존재하지 않습니다"); private final HttpStatus status; private final String code; From 53a2ec3391477a84696307e6eadb4e5decdf3b74 Mon Sep 17 00:00:00 2001 From: tobbot16 Date: Mon, 22 Dec 2025 12:01:12 +0900 Subject: [PATCH 4/7] =?UTF-8?q?feat:=20tmap=20=EB=8C=80=EC=A4=91=EA=B5=90?= =?UTF-8?q?=ED=86=B5=20=EC=9A=94=EC=95=BD=20=EC=97=B0=EB=8F=99=20=EB=B0=8F?= =?UTF-8?q?=20=EC=BD=94=EB=93=9C=EB=A6=AC=EB=B7=B0=20=EB=B6=80=EB=B6=84=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=20=EC=99=84=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/TmapApiController.java | 7 ++++ .../dto/request/TmapSummaryRequest.java | 32 +++++++++++++++ .../{TmapResponse.java => TmapRequest.java} | 3 +- .../dto/response/TmapSummaryResponse.java | 40 +++++++++++++++++++ .../domain/location/service/TmapService.java | 22 ++++++++-- .../global/config/WebClientConfig.java | 4 +- 6 files changed, 101 insertions(+), 7 deletions(-) create mode 100644 src/main/java/com/back/web7_9_codecrete_be/domain/location/dto/request/TmapSummaryRequest.java rename src/main/java/com/back/web7_9_codecrete_be/domain/location/dto/response/{TmapResponse.java => TmapRequest.java} (97%) create mode 100644 src/main/java/com/back/web7_9_codecrete_be/domain/location/dto/response/TmapSummaryResponse.java diff --git a/src/main/java/com/back/web7_9_codecrete_be/domain/location/controller/TmapApiController.java b/src/main/java/com/back/web7_9_codecrete_be/domain/location/controller/TmapApiController.java index fb45f64a..cc0603f4 100644 --- a/src/main/java/com/back/web7_9_codecrete_be/domain/location/controller/TmapApiController.java +++ b/src/main/java/com/back/web7_9_codecrete_be/domain/location/controller/TmapApiController.java @@ -1,5 +1,7 @@ package com.back.web7_9_codecrete_be.domain.location.controller; +import com.back.web7_9_codecrete_be.domain.location.dto.request.TmapSummaryRequest; +import com.back.web7_9_codecrete_be.domain.location.dto.response.TmapSummaryResponse; import com.back.web7_9_codecrete_be.domain.location.service.TmapService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; @@ -71,4 +73,9 @@ public String getTransit( ) { return tmapService.getRoute(startX, startY, endX, endY); } + + @GetMapping("/tmap/summary") + public TmapSummaryResponse getSummaryTransit(double startX, double startY, double endX, double endY){ + return tmapService.getSummaryRoute(startX, startY, endX, endY); + } } diff --git a/src/main/java/com/back/web7_9_codecrete_be/domain/location/dto/request/TmapSummaryRequest.java b/src/main/java/com/back/web7_9_codecrete_be/domain/location/dto/request/TmapSummaryRequest.java new file mode 100644 index 00000000..2da83ee0 --- /dev/null +++ b/src/main/java/com/back/web7_9_codecrete_be/domain/location/dto/request/TmapSummaryRequest.java @@ -0,0 +1,32 @@ +package com.back.web7_9_codecrete_be.domain.location.dto.request; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public class TmapSummaryRequest { + + @Schema(description = "출발지 경도 (longitude)", example = "126.9780") + private double startX; + + @Schema(description = "출발지 위도 (latitude)", example = "37.5665") + private double startY; + + @Schema(description = "도착지 경도 (longitude)", example = "127.0276") + private double endX; + + @Schema(description = "도착지 위도 (latitude)", example = "37.4979") + private double endY; + + @Schema(description = "최대 응답 결과 개수", example = "5") + private int count; + + @Schema( + description = "응답 포맷 (json / xml)", + example = "json", + allowableValues = {"json", "xml"} + ) + private String format; +} diff --git a/src/main/java/com/back/web7_9_codecrete_be/domain/location/dto/response/TmapResponse.java b/src/main/java/com/back/web7_9_codecrete_be/domain/location/dto/response/TmapRequest.java similarity index 97% rename from src/main/java/com/back/web7_9_codecrete_be/domain/location/dto/response/TmapResponse.java rename to src/main/java/com/back/web7_9_codecrete_be/domain/location/dto/response/TmapRequest.java index 3c07c0e2..62bb055e 100644 --- a/src/main/java/com/back/web7_9_codecrete_be/domain/location/dto/response/TmapResponse.java +++ b/src/main/java/com/back/web7_9_codecrete_be/domain/location/dto/response/TmapRequest.java @@ -4,8 +4,9 @@ import lombok.Data; @Data + @Schema(description = "Tmap 대중교통 경로 조회 요청 DTO") -public class TmapResponse { +public class TmapRequest { @Schema(description = "출발지 경도 (longitude)", example = "126.9780") private String startX; diff --git a/src/main/java/com/back/web7_9_codecrete_be/domain/location/dto/response/TmapSummaryResponse.java b/src/main/java/com/back/web7_9_codecrete_be/domain/location/dto/response/TmapSummaryResponse.java new file mode 100644 index 00000000..eb08b9e8 --- /dev/null +++ b/src/main/java/com/back/web7_9_codecrete_be/domain/location/dto/response/TmapSummaryResponse.java @@ -0,0 +1,40 @@ +package com.back.web7_9_codecrete_be.domain.location.dto.response; + +import lombok.Getter; + +import java.util.List; + +@Getter +public class TmapSummaryResponse { + + private MetaData metaData; + + @Getter + public static class MetaData { + private Plan plan; + } + + @Getter + public static class Plan { + private List itineraries; + } + + @Getter + public static class Itinerary { + private int totalTime; + private int totalDistance; + private int transferCount; + private Fare fare; + } + + @Getter + public static class Fare { + private Regular regular; + } + + @Getter + public static class Regular { + private int totalFare; + } + +} diff --git a/src/main/java/com/back/web7_9_codecrete_be/domain/location/service/TmapService.java b/src/main/java/com/back/web7_9_codecrete_be/domain/location/service/TmapService.java index bf2697c8..6ce52850 100644 --- a/src/main/java/com/back/web7_9_codecrete_be/domain/location/service/TmapService.java +++ b/src/main/java/com/back/web7_9_codecrete_be/domain/location/service/TmapService.java @@ -1,12 +1,12 @@ package com.back.web7_9_codecrete_be.domain.location.service; -import com.back.web7_9_codecrete_be.domain.location.dto.response.TmapResponse; +import com.back.web7_9_codecrete_be.domain.location.dto.response.TmapRequest; +import com.back.web7_9_codecrete_be.domain.location.dto.request.TmapSummaryRequest; +import com.back.web7_9_codecrete_be.domain.location.dto.response.TmapSummaryResponse; import lombok.RequiredArgsConstructor; -import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.http.MediaType; import org.springframework.stereotype.Service; import org.springframework.web.client.RestClient; -import org.springframework.web.reactive.function.client.WebClient; @Service @RequiredArgsConstructor @@ -16,7 +16,7 @@ public class TmapService { public String getRoute(double startX, double startY, double endX, double endY) { - TmapResponse req = new TmapResponse(); + TmapRequest req = new TmapRequest(); req.setStartX(String.valueOf(startX)); req.setStartY(String.valueOf(startY)); req.setEndX(String.valueOf(endX)); @@ -31,4 +31,18 @@ public String getRoute(double startX, double startY, double endX, double endY) { .retrieve() .body(String.class); } + + public TmapSummaryResponse getSummaryRoute(double startX, double startY, double endX, double endY){ + return TmapRestClient.post() + .uri("/transit/routes/sub") + .contentType(MediaType.APPLICATION_JSON) + .body(new TmapSummaryRequest( + startX, startY, + endX, endY, + 1, + "json" + )) + .retrieve() + .body(TmapSummaryResponse.class); + } } diff --git a/src/main/java/com/back/web7_9_codecrete_be/global/config/WebClientConfig.java b/src/main/java/com/back/web7_9_codecrete_be/global/config/WebClientConfig.java index 2d928360..8f2589ce 100644 --- a/src/main/java/com/back/web7_9_codecrete_be/global/config/WebClientConfig.java +++ b/src/main/java/com/back/web7_9_codecrete_be/global/config/WebClientConfig.java @@ -37,7 +37,7 @@ public class WebClientConfig { @Value("${tmap.base-url}") private String tmapBaseUrl; - @Value("https://apis-navi.kakaomobility.com") + @Value("${https://apis-navi.kakaomobility.com}") private String kakaoMobilityUrl; @Bean @@ -87,7 +87,7 @@ public RestClient kakaoMobilityClient(){ } @Bean - public RestClient TmapRestClient(){ + public RestClient tmapRestClient(){ return RestClient.builder() .baseUrl(tmapBaseUrl) .defaultHeader("appKey", tmapApiKey) From 8a6786f84c1d9ff9e02fa82b11d983dc5f7f9a02 Mon Sep 17 00:00:00 2001 From: tobbot16 Date: Mon, 22 Dec 2025 12:36:03 +0900 Subject: [PATCH 5/7] =?UTF-8?q?feat:=20tmap=20=EC=9A=94=EC=95=BD=20?= =?UTF-8?q?=EC=A0=84=EC=B2=B4=EC=BD=94=EB=93=9C=20=EC=9D=91=EB=8B=B5=20?= =?UTF-8?q?=C3=AB=C2=B0=EB=B0=9B=EB=8A=94=20=EC=BD=94=EB=93=9C=20=EC=9E=91?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/KakaoApiController.java | 23 ++++++ .../controller/TmapApiController.java | 3 +- .../dto/response/TmapSummaryAllResponse.java | 71 +++++++++++++++++++ .../location/service/KakaoLocalService.java | 22 ++++++ .../domain/location/service/TmapService.java | 16 +++-- 5 files changed, 128 insertions(+), 7 deletions(-) create mode 100644 src/main/java/com/back/web7_9_codecrete_be/domain/location/dto/response/TmapSummaryAllResponse.java diff --git a/src/main/java/com/back/web7_9_codecrete_be/domain/location/controller/KakaoApiController.java b/src/main/java/com/back/web7_9_codecrete_be/domain/location/controller/KakaoApiController.java index f7b17505..f27218a2 100644 --- a/src/main/java/com/back/web7_9_codecrete_be/domain/location/controller/KakaoApiController.java +++ b/src/main/java/com/back/web7_9_codecrete_be/domain/location/controller/KakaoApiController.java @@ -89,6 +89,29 @@ public List navigateGuides( return List.of(); } + return route0.getSections().stream() + .filter(section -> section.getGuides() != null && !section.getGuides().isEmpty()) + .flatMap(section -> section.getGuides().stream()) + .toList(); + } + @GetMapping("/navigate/summary") + public List navigateSummary( + @RequestParam double startX, + @RequestParam double startY, + @RequestParam double endX, + @RequestParam double endY + ) { + KakaoMobilityResponse res = kakaoLocalService.NaviSearchSummary(startX, startY, endX, endY); + + if (res == null || res.getRoutes() == null || res.getRoutes().isEmpty()) { + return List.of(); + } + + KakaoMobilityResponse.Route route0 = res.getRoutes().get(0); + if (route0.getSections() == null || route0.getSections().isEmpty()) { + return List.of(); + } + return route0.getSections().stream() .filter(section -> section.getGuides() != null && !section.getGuides().isEmpty()) .flatMap(section -> section.getGuides().stream()) diff --git a/src/main/java/com/back/web7_9_codecrete_be/domain/location/controller/TmapApiController.java b/src/main/java/com/back/web7_9_codecrete_be/domain/location/controller/TmapApiController.java index cc0603f4..e406a724 100644 --- a/src/main/java/com/back/web7_9_codecrete_be/domain/location/controller/TmapApiController.java +++ b/src/main/java/com/back/web7_9_codecrete_be/domain/location/controller/TmapApiController.java @@ -1,6 +1,7 @@ package com.back.web7_9_codecrete_be.domain.location.controller; import com.back.web7_9_codecrete_be.domain.location.dto.request.TmapSummaryRequest; +import com.back.web7_9_codecrete_be.domain.location.dto.response.TmapSummaryAllResponse; import com.back.web7_9_codecrete_be.domain.location.dto.response.TmapSummaryResponse; import com.back.web7_9_codecrete_be.domain.location.service.TmapService; import io.swagger.v3.oas.annotations.Operation; @@ -75,7 +76,7 @@ public String getTransit( } @GetMapping("/tmap/summary") - public TmapSummaryResponse getSummaryTransit(double startX, double startY, double endX, double endY){ + public TmapSummaryAllResponse getSummaryTransit(double startX, double startY, double endX, double endY){ return tmapService.getSummaryRoute(startX, startY, endX, endY); } } diff --git a/src/main/java/com/back/web7_9_codecrete_be/domain/location/dto/response/TmapSummaryAllResponse.java b/src/main/java/com/back/web7_9_codecrete_be/domain/location/dto/response/TmapSummaryAllResponse.java new file mode 100644 index 00000000..055662e2 --- /dev/null +++ b/src/main/java/com/back/web7_9_codecrete_be/domain/location/dto/response/TmapSummaryAllResponse.java @@ -0,0 +1,71 @@ +package com.back.web7_9_codecrete_be.domain.location.dto.response; + +import lombok.Getter; + +import java.util.List; +@Getter +public class TmapSummaryAllResponse { + + private MetaData metaData; + + // ===================== metaData ===================== + @Getter + public static class MetaData { + private Plan plan; + private RequestParameters requestParameters; + } + + // ===================== plan ===================== + @Getter + public static class Plan { + private List itineraries; + } + + // ===================== itineraries ===================== + @Getter + public static class Itinerary { + + private int pathType; // 경로 탐색 결과 종류 + private int totalTime; // 총 소요시간 (sec) + private int transferCount; // 환승 횟수 + private int totalWalkDistance; // 총 보행 거리 (m) + private int totalDistance; // 총 이동 거리 (m) + private int totalWalkTime; // 총 보행 시간 (sec) + + private Fare fare; // 요금 정보 + } + + // ===================== fare ===================== + @Getter + public static class Fare { + private Regular regular; + } + + // ===================== regular ===================== + @Getter + public static class Regular { + private Currency currency; + private int totalFare; // 대중교통 요금 + } + + // ===================== currency ===================== + @Getter + public static class Currency { + private String symbol; // ₩ + private String currency; // 원 + private String currencyCode; // KRW + } + + // ===================== requestParameters ===================== + @Getter + public static class RequestParameters { + + private String reqDttm; // 요청 시각 (yyyymmddhhmiss) + + private String startX; // 출발지 경도 + private String startY; // 출발지 위도 + private String endX; // 도착지 경도 + private String endY; // 도착지 위도 + } + +} diff --git a/src/main/java/com/back/web7_9_codecrete_be/domain/location/service/KakaoLocalService.java b/src/main/java/com/back/web7_9_codecrete_be/domain/location/service/KakaoLocalService.java index b9a11de2..7949eca1 100644 --- a/src/main/java/com/back/web7_9_codecrete_be/domain/location/service/KakaoLocalService.java +++ b/src/main/java/com/back/web7_9_codecrete_be/domain/location/service/KakaoLocalService.java @@ -101,6 +101,28 @@ public KakaoMobilityResponse NaviSearch(double startX, double startY, double end .body(KakaoMobilityResponse.class); + if (response == null || response.getRoutes().isEmpty()) { + throw new BusinessException(LocationErrorCode.ROUTE_NOT_FOUND); + } + + return response; + } + + public KakaoMobilityResponse NaviSearchSummary(double startX, double startY, double endX, double endY) { + + KakaoMobilityResponse response = kakaoMobilityClient.get() + .uri(uriBuilder -> uriBuilder + .path("/v1/directions") + .queryParam("origin", startX + "," + startY) + .queryParam("destination", endX + "," + endY) + .queryParam("priority", "TIME") + .queryParam("summary", "true") + .build() + ) + .retrieve() + .body(KakaoMobilityResponse.class); + + if (response == null || response.getRoutes().isEmpty()) { throw new BusinessException(LocationErrorCode.ROUTE_NOT_FOUND); } diff --git a/src/main/java/com/back/web7_9_codecrete_be/domain/location/service/TmapService.java b/src/main/java/com/back/web7_9_codecrete_be/domain/location/service/TmapService.java index 6ce52850..1f415784 100644 --- a/src/main/java/com/back/web7_9_codecrete_be/domain/location/service/TmapService.java +++ b/src/main/java/com/back/web7_9_codecrete_be/domain/location/service/TmapService.java @@ -2,18 +2,22 @@ import com.back.web7_9_codecrete_be.domain.location.dto.response.TmapRequest; import com.back.web7_9_codecrete_be.domain.location.dto.request.TmapSummaryRequest; +import com.back.web7_9_codecrete_be.domain.location.dto.response.TmapSummaryAllResponse; import com.back.web7_9_codecrete_be.domain.location.dto.response.TmapSummaryResponse; import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.http.MediaType; import org.springframework.stereotype.Service; import org.springframework.web.client.RestClient; @Service -@RequiredArgsConstructor public class TmapService { - private final RestClient TmapRestClient; + private final RestClient tmapRestClient; + public TmapService(@Qualifier("tmapRestClient") RestClient tmapRestClient) { + this.tmapRestClient = tmapRestClient; + } public String getRoute(double startX, double startY, double endX, double endY) { TmapRequest req = new TmapRequest(); @@ -24,7 +28,7 @@ public String getRoute(double startX, double startY, double endX, double endY) { req.setCount(5); req.setFormat("json"); - return TmapRestClient.post() + return tmapRestClient.post() .uri("/transit/routes") .contentType(MediaType.APPLICATION_JSON) .body(req) @@ -32,8 +36,8 @@ public String getRoute(double startX, double startY, double endX, double endY) { .body(String.class); } - public TmapSummaryResponse getSummaryRoute(double startX, double startY, double endX, double endY){ - return TmapRestClient.post() + public TmapSummaryAllResponse getSummaryRoute(double startX, double startY, double endX, double endY){ + return tmapRestClient.post() .uri("/transit/routes/sub") .contentType(MediaType.APPLICATION_JSON) .body(new TmapSummaryRequest( @@ -43,6 +47,6 @@ public TmapSummaryResponse getSummaryRoute(double startX, double startY, double "json" )) .retrieve() - .body(TmapSummaryResponse.class); + .body(TmapSummaryAllResponse.class); } } From fd51c06573c2d91740e4a471cb5bde05699c81fb Mon Sep 17 00:00:00 2001 From: tobbot16 Date: Mon, 22 Dec 2025 14:03:19 +0900 Subject: [PATCH 6/7] =?UTF-8?q?feat:=20yml=EB=B6=80=EB=B6=84(=EC=BD=94?= =?UTF-8?q?=EB=93=9C=EB=A6=AC=EB=B7=B0)=20=EC=88=98=EC=A0=95=20=EC=99=84?= =?UTF-8?q?=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../location/controller/KakaoApiController.java | 16 ++++++++-------- .../global/config/WebClientConfig.java | 2 +- src/main/resources/application.yml | 2 ++ 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/main/java/com/back/web7_9_codecrete_be/domain/location/controller/KakaoApiController.java b/src/main/java/com/back/web7_9_codecrete_be/domain/location/controller/KakaoApiController.java index f27218a2..1acbb43e 100644 --- a/src/main/java/com/back/web7_9_codecrete_be/domain/location/controller/KakaoApiController.java +++ b/src/main/java/com/back/web7_9_codecrete_be/domain/location/controller/KakaoApiController.java @@ -3,6 +3,8 @@ import com.back.web7_9_codecrete_be.domain.location.dto.response.KakaoLocalResponse; import com.back.web7_9_codecrete_be.domain.location.dto.response.KakaoMobilityResponse; import com.back.web7_9_codecrete_be.domain.location.service.KakaoLocalService; +import com.back.web7_9_codecrete_be.global.error.code.LocationErrorCode; +import com.back.web7_9_codecrete_be.global.error.exception.BusinessException; import com.back.web7_9_codecrete_be.global.rsData.RsData; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; @@ -95,7 +97,7 @@ public List navigateGuides( .toList(); } @GetMapping("/navigate/summary") - public List navigateSummary( + public KakaoMobilityResponse.Summary navigateSummary( @RequestParam double startX, @RequestParam double startY, @RequestParam double endX, @@ -104,18 +106,16 @@ public List navigateSummary( KakaoMobilityResponse res = kakaoLocalService.NaviSearchSummary(startX, startY, endX, endY); if (res == null || res.getRoutes() == null || res.getRoutes().isEmpty()) { - return List.of(); + throw new BusinessException(LocationErrorCode.ROUTE_NOT_FOUND); } KakaoMobilityResponse.Route route0 = res.getRoutes().get(0); - if (route0.getSections() == null || route0.getSections().isEmpty()) { - return List.of(); + if (route0.getSummary() == null) { + throw new BusinessException(LocationErrorCode.ROUTE_NOT_FOUND); } - return route0.getSections().stream() - .filter(section -> section.getGuides() != null && !section.getGuides().isEmpty()) - .flatMap(section -> section.getGuides().stream()) - .toList(); + return route0.getSummary(); + } } diff --git a/src/main/java/com/back/web7_9_codecrete_be/global/config/WebClientConfig.java b/src/main/java/com/back/web7_9_codecrete_be/global/config/WebClientConfig.java index 8f2589ce..c23c502d 100644 --- a/src/main/java/com/back/web7_9_codecrete_be/global/config/WebClientConfig.java +++ b/src/main/java/com/back/web7_9_codecrete_be/global/config/WebClientConfig.java @@ -37,7 +37,7 @@ public class WebClientConfig { @Value("${tmap.base-url}") private String tmapBaseUrl; - @Value("${https://apis-navi.kakaomobility.com}") + @Value("${kakao.mobility.base-url}") private String kakaoMobilityUrl; @Bean diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 3bf45408..9764f0f8 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -51,6 +51,8 @@ tmap: #Tmap 대중교통 추천 api 키 kakao: #Kakao map REST API 키 base-url: https://dapi.kakao.com restapi-key: ${KAKAOMAP_API_KEY} + mobility: + base-url: https://apis-navi.kakaomobility.com kopis: api-key: ${KOPIST_API_KEY} From d2e73fee5d827ad98fc93a69eb149589869f4c1c Mon Sep 17 00:00:00 2001 From: tobbot16 Date: Mon, 22 Dec 2025 17:01:05 +0900 Subject: [PATCH 7/7] =?UTF-8?q?feat:=20fe=EB=B6=84=EB=93=A4=EC=9D=B4=20?= =?UTF-8?q?=EC=9B=90=ED=95=98=EB=8A=94=20=EB=82=B4=EC=9A=A9=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=EC=A0=9C=EC=A1=B0=EC=A4=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/KakaoApiController.java | 24 ++++++ .../{response => request}/TmapRequest.java | 2 +- .../dto/response/KakaoMobilityResponse.java | 2 +- .../response/KakaoRouteTransitResponse.java | 79 +++++++++++++++++++ .../location/service/KakaoLocalService.java | 18 +++++ .../domain/location/service/TmapService.java | 4 +- 6 files changed, 124 insertions(+), 5 deletions(-) rename src/main/java/com/back/web7_9_codecrete_be/domain/location/dto/{response => request}/TmapRequest.java (92%) create mode 100644 src/main/java/com/back/web7_9_codecrete_be/domain/location/dto/response/KakaoRouteTransitResponse.java diff --git a/src/main/java/com/back/web7_9_codecrete_be/domain/location/controller/KakaoApiController.java b/src/main/java/com/back/web7_9_codecrete_be/domain/location/controller/KakaoApiController.java index 1acbb43e..32acd9c6 100644 --- a/src/main/java/com/back/web7_9_codecrete_be/domain/location/controller/KakaoApiController.java +++ b/src/main/java/com/back/web7_9_codecrete_be/domain/location/controller/KakaoApiController.java @@ -2,6 +2,7 @@ import com.back.web7_9_codecrete_be.domain.location.dto.response.KakaoLocalResponse; import com.back.web7_9_codecrete_be.domain.location.dto.response.KakaoMobilityResponse; +import com.back.web7_9_codecrete_be.domain.location.dto.response.KakaoRouteTransitResponse; import com.back.web7_9_codecrete_be.domain.location.service.KakaoLocalService; import com.back.web7_9_codecrete_be.global.error.code.LocationErrorCode; import com.back.web7_9_codecrete_be.global.error.exception.BusinessException; @@ -117,5 +118,28 @@ public KakaoMobilityResponse.Summary navigateSummary( return route0.getSummary(); } + + @PostMapping("/navigate/onlyguide") + public List navigateOnlyGuides( + @RequestParam double startX, + @RequestParam double startY, + @RequestParam double endX, + @RequestParam double endY, + @RequestParam double wayX, + @RequestParam double wayY + ) { + KakaoRouteTransitResponse res = kakaoLocalService.NaviSearchTransit(startX, startY, endX, endY, wayX, wayY); + + if (res == null || res.getRoutes() == null || res.getRoutes().isEmpty()) { + return List.of(); + } + + KakaoRouteTransitResponse.Route route0 = res.getRoutes().get(0); + + return route0.getSections().stream() + .filter(section -> section.getGuides() != null && !section.getGuides().isEmpty()) + .flatMap(section -> section.getGuides().stream()) + .toList(); + } } diff --git a/src/main/java/com/back/web7_9_codecrete_be/domain/location/dto/response/TmapRequest.java b/src/main/java/com/back/web7_9_codecrete_be/domain/location/dto/request/TmapRequest.java similarity index 92% rename from src/main/java/com/back/web7_9_codecrete_be/domain/location/dto/response/TmapRequest.java rename to src/main/java/com/back/web7_9_codecrete_be/domain/location/dto/request/TmapRequest.java index 62bb055e..d63b11fe 100644 --- a/src/main/java/com/back/web7_9_codecrete_be/domain/location/dto/response/TmapRequest.java +++ b/src/main/java/com/back/web7_9_codecrete_be/domain/location/dto/request/TmapRequest.java @@ -1,4 +1,4 @@ -package com.back.web7_9_codecrete_be.domain.location.dto.response; +package com.back.web7_9_codecrete_be.domain.location.dto.request; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; diff --git a/src/main/java/com/back/web7_9_codecrete_be/domain/location/dto/response/KakaoMobilityResponse.java b/src/main/java/com/back/web7_9_codecrete_be/domain/location/dto/response/KakaoMobilityResponse.java index 74ebaf64..c2c191c6 100644 --- a/src/main/java/com/back/web7_9_codecrete_be/domain/location/dto/response/KakaoMobilityResponse.java +++ b/src/main/java/com/back/web7_9_codecrete_be/domain/location/dto/response/KakaoMobilityResponse.java @@ -39,7 +39,7 @@ public static class Road{ @Getter - public static class Guide { // ✅ 추가 + public static class Guide { private String name; private double x; private double y; diff --git a/src/main/java/com/back/web7_9_codecrete_be/domain/location/dto/response/KakaoRouteTransitResponse.java b/src/main/java/com/back/web7_9_codecrete_be/domain/location/dto/response/KakaoRouteTransitResponse.java new file mode 100644 index 00000000..848a0199 --- /dev/null +++ b/src/main/java/com/back/web7_9_codecrete_be/domain/location/dto/response/KakaoRouteTransitResponse.java @@ -0,0 +1,79 @@ +package com.back.web7_9_codecrete_be.domain.location.dto.response; + +import lombok.Getter; +import java.util.List; + +@Getter +public class KakaoRouteTransitResponse { + + private List routes; + + @Getter + public static class Route { + private Summary summary; + private List
sections; + } + + @Getter + public static class Summary { + private Origin origin; + private Destination destination; + private List waypoints; // ✅ 경유지(요청값) + + private String priority; + private Fare fare; + + private int distance; // meters + private int duration; // seconds + } + + @Getter + public static class Origin { + private String name; + private double x; + private double y; + } + + @Getter + public static class Destination { + private String name; + private double x; + private double y; + } + + @Getter + public static class Waypoint { + private String name; + private double x; + private double y; + } + + @Getter + public static class Fare { + private int taxi; + private int toll; + } + + @Getter + public static class Section { + private List roads; + private List guides; + } + + @Getter + public static class Road { + private List vertexes; + } + + @Getter + public static class Guide { + private String name; + private double x; + private double y; + private int distance; + private int duration; + private int type; + private String guidance; + private int road_index; + } +} diff --git a/src/main/java/com/back/web7_9_codecrete_be/domain/location/service/KakaoLocalService.java b/src/main/java/com/back/web7_9_codecrete_be/domain/location/service/KakaoLocalService.java index 7949eca1..f8d18b48 100644 --- a/src/main/java/com/back/web7_9_codecrete_be/domain/location/service/KakaoLocalService.java +++ b/src/main/java/com/back/web7_9_codecrete_be/domain/location/service/KakaoLocalService.java @@ -3,6 +3,7 @@ import com.back.web7_9_codecrete_be.domain.location.dto.KakaoCoordinateResponse; import com.back.web7_9_codecrete_be.domain.location.dto.response.KakaoLocalResponse; import com.back.web7_9_codecrete_be.domain.location.dto.response.KakaoMobilityResponse; +import com.back.web7_9_codecrete_be.domain.location.dto.response.KakaoRouteTransitResponse; import com.back.web7_9_codecrete_be.global.error.code.LocationErrorCode; import com.back.web7_9_codecrete_be.global.error.exception.BusinessException; import lombok.RequiredArgsConstructor; @@ -129,4 +130,21 @@ public KakaoMobilityResponse NaviSearchSummary(double startX, double startY, dou return response; } + + public KakaoRouteTransitResponse NaviSearchTransit(double startX, double startY + , double endX, double endY, double wayX, double wayY){ + KakaoRouteTransitResponse response = kakaoMobilityClient.post() + .uri(uriBuilder -> uriBuilder + .path("/v1/waypoints/directions") + .queryParam("origin", startX + "," + startY) + .queryParam("destination", endX + "," + endY) + .queryParam("waypoints", wayX + "," + wayY) + .queryParam("priority", "TIME") + .queryParam("summary", "false") + .build() + ) + .retrieve() + .body(KakaoRouteTransitResponse.class); + return response; + } } \ No newline at end of file diff --git a/src/main/java/com/back/web7_9_codecrete_be/domain/location/service/TmapService.java b/src/main/java/com/back/web7_9_codecrete_be/domain/location/service/TmapService.java index 1f415784..abf37484 100644 --- a/src/main/java/com/back/web7_9_codecrete_be/domain/location/service/TmapService.java +++ b/src/main/java/com/back/web7_9_codecrete_be/domain/location/service/TmapService.java @@ -1,10 +1,8 @@ package com.back.web7_9_codecrete_be.domain.location.service; -import com.back.web7_9_codecrete_be.domain.location.dto.response.TmapRequest; +import com.back.web7_9_codecrete_be.domain.location.dto.request.TmapRequest; import com.back.web7_9_codecrete_be.domain.location.dto.request.TmapSummaryRequest; import com.back.web7_9_codecrete_be.domain.location.dto.response.TmapSummaryAllResponse; -import com.back.web7_9_codecrete_be.domain.location.dto.response.TmapSummaryResponse; -import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.http.MediaType; import org.springframework.stereotype.Service;