From e1f846bfb147c0db24a1bceead17cf403d297635 Mon Sep 17 00:00:00 2001 From: inyoung Date: Tue, 10 Oct 2023 07:22:17 +0900 Subject: [PATCH 1/2] =?UTF-8?q?feat:=20camping=20API=20=ED=98=B8=EC=B6=9C?= =?UTF-8?q?=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 12 ++ .../com/catcher/batch/CampingController.java | 32 +++++ .../java/com/catcher/batch/JsonConverter.java | 29 +++++ .../batch/core/config/RestTemplateConfig.java | 16 +++ .../batch/core/config/WebClientConfig.java | 29 +++++ .../batch/core/dto/CampingApiResponse.java | 121 ++++++++++++++++++ .../batch/service/CampingApiService.java | 34 +++++ .../catcher/batch/service/RestApiService.java | 39 ++++++ 8 files changed, 312 insertions(+) create mode 100644 src/main/java/com/catcher/batch/CampingController.java create mode 100644 src/main/java/com/catcher/batch/JsonConverter.java create mode 100644 src/main/java/com/catcher/batch/core/config/RestTemplateConfig.java create mode 100644 src/main/java/com/catcher/batch/core/config/WebClientConfig.java create mode 100644 src/main/java/com/catcher/batch/core/dto/CampingApiResponse.java create mode 100644 src/main/java/com/catcher/batch/service/CampingApiService.java create mode 100644 src/main/java/com/catcher/batch/service/RestApiService.java diff --git a/build.gradle b/build.gradle index 8d45e13..bca2698 100644 --- a/build.gradle +++ b/build.gradle @@ -29,6 +29,18 @@ dependencies { developmentOnly 'org.springframework.boot:spring-boot-devtools' annotationProcessor 'org.projectlombok:lombok' testImplementation 'org.springframework.boot:spring-boot-starter-test' + implementation 'org.springframework.boot:spring-boot-starter-data-jpa' + + // webclinet 설정 + implementation 'org.springframework.boot:spring-boot-starter-webflux' + // m1 netty 로컬 설정 + implementation("io.netty:netty-resolver-dns-native-macos:4.1.75.Final:osx-aarch_64") +} + +dependencyManagement { + imports { + mavenBom "org.springframework.cloud:spring-cloud-dependencies:2022.0.3" + } } dependencyManagement { diff --git a/src/main/java/com/catcher/batch/CampingController.java b/src/main/java/com/catcher/batch/CampingController.java new file mode 100644 index 0000000..6b20dc2 --- /dev/null +++ b/src/main/java/com/catcher/batch/CampingController.java @@ -0,0 +1,32 @@ +package com.catcher.batch; + +import com.catcher.batch.core.dto.CampingApiResponse; +import com.catcher.batch.service.CampingApiService; +import com.catcher.batch.service.RestApiService; +import lombok.RequiredArgsConstructor; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import reactor.core.publisher.Mono; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/camping") +public class CampingController { + private final CampingApiService campingApiService; + private final RestApiService restApiService; + + @GetMapping("/webclient") + public Mono> testWebClient() { + return campingApiService.getOpenApi() + .map(ResponseEntity::ok) + .defaultIfEmpty(ResponseEntity.notFound().build()); + } + + @GetMapping("/resttemplate") + public ResponseEntity testRestTemplate() { + CampingApiResponse response = restApiService.getOpenApi(); + return ResponseEntity.ok(response); + } +} diff --git a/src/main/java/com/catcher/batch/JsonConverter.java b/src/main/java/com/catcher/batch/JsonConverter.java new file mode 100644 index 0000000..10d230a --- /dev/null +++ b/src/main/java/com/catcher/batch/JsonConverter.java @@ -0,0 +1,29 @@ +package com.catcher.batch; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; +import jakarta.annotation.PostConstruct; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +@Slf4j +@Component +public class JsonConverter { + private ObjectMapper objectMapper; + + @PostConstruct + public void init() { + objectMapper = new ObjectMapper().registerModule(new JavaTimeModule()); + } + + public T jsonToObject(String json, Class clazz) { + T obj = null; + try { + obj = objectMapper.readValue(json, clazz); + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException(); + } + return obj; + } +} diff --git a/src/main/java/com/catcher/batch/core/config/RestTemplateConfig.java b/src/main/java/com/catcher/batch/core/config/RestTemplateConfig.java new file mode 100644 index 0000000..1ab39ec --- /dev/null +++ b/src/main/java/com/catcher/batch/core/config/RestTemplateConfig.java @@ -0,0 +1,16 @@ +package com.catcher.batch.core.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.client.SimpleClientHttpRequestFactory; +import org.springframework.web.client.RestTemplate; + +@Configuration +public class RestTemplateConfig { + + @Bean + public RestTemplate restTemplate() { + SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory(); + return new RestTemplate(factory); + } +} diff --git a/src/main/java/com/catcher/batch/core/config/WebClientConfig.java b/src/main/java/com/catcher/batch/core/config/WebClientConfig.java new file mode 100644 index 0000000..2eb1d82 --- /dev/null +++ b/src/main/java/com/catcher/batch/core/config/WebClientConfig.java @@ -0,0 +1,29 @@ +package com.catcher.batch.core.config; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.http.client.reactive.ReactorResourceFactory; +import org.springframework.web.reactive.function.client.WebClient; +import org.springframework.web.util.DefaultUriBuilderFactory; + +@Configuration +public class WebClientConfig { + + @Value("${catcher.api.url}") + private String BASE_URL; + + DefaultUriBuilderFactory factory = new DefaultUriBuilderFactory(); + + @Bean + public WebClient webClient(){ + factory.setEncodingMode(DefaultUriBuilderFactory.EncodingMode.NONE); + + return WebClient.builder() + .baseUrl(BASE_URL) + .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) + .build(); + } +} diff --git a/src/main/java/com/catcher/batch/core/dto/CampingApiResponse.java b/src/main/java/com/catcher/batch/core/dto/CampingApiResponse.java new file mode 100644 index 0000000..5058958 --- /dev/null +++ b/src/main/java/com/catcher/batch/core/dto/CampingApiResponse.java @@ -0,0 +1,121 @@ +package com.catcher.batch.core.dto; + +import lombok.Getter; + +import java.util.List; + +@Getter +public class CampingApiResponse { + private Response response; + + @Getter + public static class Response { + private Header header; + private Body body; + } + + @Getter + public static class Header { + private String resultCode; + private String resultMsg; + } + + @Getter + public static class Body { + private Items items; + private String numOfRows; + private String pageNo; + private String totalCount; + } + + @Getter + public static class Items { + private List item; + } + + // TODO 응답값 추후 필요한 것만 걸러내야 함 + @Getter + public static class CampingItemDTO { + private String contentId; + private String facltNm; + private String lineIntro; + private String intro; + private String allar; + private String insrncAt; + private String trsagntNo; + private String bizrno; + private String facltDivNm; + private String mangeDivNm; + private String mgcDiv; + private String manageSttus; + private String hvofBgnde; + private String hvofEnddle; + private String featureNm; + private String induty; + private String lctCl; + private String doNm; + private String sigunguNm; + private String zipcode; + private String addr1; + private String addr2; + private String mapX; + private String mapY; + private String direction; + private String tel; + private String homepage; + private String resveUrl; + private String resveCl; + private String manageNmpr; + private String gnrlSiteCo; + private String autoSiteCo; + private String glampSiteCo; + private String caravSiteCo; + private String indvdlCaravSiteCo; + private String sitedStnc; + private String siteMg1Width; + private String siteMg2Width; + private String siteMg3Width; + private String siteMg1Vrticl; + private String siteMg2Vrticl; + private String siteMg3Vrticl; + private String siteMg1Co; + private String siteMg2Co; + private String siteMg3Co; + private String siteBottomCl1; + private String siteBottomCl2; + private String siteBottomCl3; + private String siteBottomCl4; + private String siteBottomCl5; + private String tooltip; + private String glampInnerFclty; + private String caravInnerFclty; + private String prmisnDe; + private String operPdCl; + private String operDeCl; + private String trlerAcmpnyAt; + private String caravAcmpnyAt; + private String toiletCo; + private String swrmCo; + private String wtrplCo; + private String brazierCl; + private String sbrsCl; + private String sbrsEtc; + private String posblFcltyCl; + private String posblFcltyEtc; + private String clturEventAt; + private String clturEvent; + private String exprnProgrmAt; + private String exprnProgrm; + private String extshrCo; + private String frprvtWrppCo; + private String frprvtSandCo; + private String fireSensorCo; + private String themaEnvrnCl; + private String eqpmnLendCl; + private String animalCmgCl; + private String tourEraCl; + private String firstImageUrl; + private String createdtime; + private String modifiedtime; + } +} diff --git a/src/main/java/com/catcher/batch/service/CampingApiService.java b/src/main/java/com/catcher/batch/service/CampingApiService.java new file mode 100644 index 0000000..6369220 --- /dev/null +++ b/src/main/java/com/catcher/batch/service/CampingApiService.java @@ -0,0 +1,34 @@ +package com.catcher.batch.service; + +import com.catcher.batch.JsonConverter; +import com.catcher.batch.core.config.WebClientConfig; +import com.catcher.batch.core.dto.CampingApiResponse; +import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; +import reactor.core.publisher.Mono; + +@Service +@RequiredArgsConstructor +public class CampingApiService { + + @Value("${catcher.api.key}") + private String SERVICE_KEY; + + private final JsonConverter jsonConverter; + private final WebClientConfig webClientConfig; + + public Mono getOpenApi() { + return webClientConfig.webClient().get() + .uri(uriBuilder -> uriBuilder + .path("/basedList") + .queryParam("serviceKey", SERVICE_KEY) + .queryParam("MobileOS", "ETC") + .queryParam("MobileApp", "AppTest") + .queryParam("_type", "json") + .build()) + .retrieve() + .bodyToMono(String.class) + .map(json -> jsonConverter.jsonToObject(json, CampingApiResponse.class)); + } +} diff --git a/src/main/java/com/catcher/batch/service/RestApiService.java b/src/main/java/com/catcher/batch/service/RestApiService.java new file mode 100644 index 0000000..e3c74dc --- /dev/null +++ b/src/main/java/com/catcher/batch/service/RestApiService.java @@ -0,0 +1,39 @@ +package com.catcher.batch.service; + +import com.catcher.batch.core.config.RestTemplateConfig; +import com.catcher.batch.core.dto.CampingApiResponse; +import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Service; +import org.springframework.web.util.UriComponentsBuilder; + +import java.net.URI; + +@Service +@RequiredArgsConstructor +public class RestApiService { + + // TODO 하드코딩 수정 + private final String BASE_URL = "https://apis.data.go.kr/B551011/GoCamping"; + + @Value("${catcher.api.key}") + private String SERVICE_KEY; + + private final RestTemplateConfig restTemplateConfig; + + public CampingApiResponse getOpenApi() { + URI apiUrl = UriComponentsBuilder + .fromUriString(BASE_URL).path("/basedList") + .queryParam("serviceKey", SERVICE_KEY) + .queryParam("MobileOS", "ETC") + .queryParam("MobileApp", "AppTest") + .queryParam("_type", "json") + .build() + .encode() + .toUri(); + + ResponseEntity responseEntity = restTemplateConfig.restTemplate().getForEntity(apiUrl, CampingApiResponse.class); + return responseEntity.getBody(); + } +} From 760a06a4eee0d0194f07a05d29d1b72682455ab1 Mon Sep 17 00:00:00 2001 From: inyoung Date: Tue, 10 Oct 2023 07:22:58 +0900 Subject: [PATCH 2/2] =?UTF-8?q?chore:=20=EC=82=AC=EC=9A=A9=ED=95=98?= =?UTF-8?q?=EC=A7=80=20=EC=95=8A=EB=8A=94=20import=EB=AC=B8=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/catcher/batch/core/config/WebClientConfig.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/com/catcher/batch/core/config/WebClientConfig.java b/src/main/java/com/catcher/batch/core/config/WebClientConfig.java index 2eb1d82..042e1cb 100644 --- a/src/main/java/com/catcher/batch/core/config/WebClientConfig.java +++ b/src/main/java/com/catcher/batch/core/config/WebClientConfig.java @@ -5,7 +5,6 @@ import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; -import org.springframework.http.client.reactive.ReactorResourceFactory; import org.springframework.web.reactive.function.client.WebClient; import org.springframework.web.util.DefaultUriBuilderFactory;