diff --git a/build.gradle b/build.gradle index 8d45e13..92ba7e4 100644 --- a/build.gradle +++ b/build.gradle @@ -27,6 +27,10 @@ dependencies { implementation 'org.springframework.cloud:spring-cloud-starter-openfeign' compileOnly 'org.projectlombok:lombok' developmentOnly 'org.springframework.boot:spring-boot-devtools' + implementation 'org.json:json:20190722' + implementation group: 'com.fasterxml.jackson.core', name: 'jackson-core', version: '2.12.5' + implementation group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.12.5' + annotationProcessor 'org.projectlombok:lombok' testImplementation 'org.springframework.boot:spring-boot-starter-test' } diff --git a/src/main/java/com/catcher/batch/openapi/jsonparser/CatcherJsonParser.java b/src/main/java/com/catcher/batch/openapi/jsonparser/CatcherJsonParser.java new file mode 100644 index 0000000..83fc108 --- /dev/null +++ b/src/main/java/com/catcher/batch/openapi/jsonparser/CatcherJsonParser.java @@ -0,0 +1,41 @@ +package com.catcher.batch.openapi.jsonparser; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.json.JSONObject; + +public abstract class CatcherJsonParser { + private final ObjectMapper objectMapper = new ObjectMapper(); + private String headerPath; + private String bodyPath; + + public CatcherJsonParser(String headerPath, String bodyPath) { + this.headerPath = headerPath; + this.bodyPath = bodyPath; + } + + public H parseHeader(String json ,Class clazz) throws JsonProcessingException { + JSONObject headerJson = getJsonObject(json, headerPath); + return objectMapper.readValue(headerJson.toString(), clazz); + } + + public B parseBody(String json ,Class clazz) throws JsonProcessingException { + JSONObject bodyJson = getJsonObject(json, bodyPath); + return objectMapper.readValue(bodyJson.toString(), clazz); + } + + private JSONObject getJsonObject(String json, String path) { + JSONObject jsonObject = new JSONObject(json); + if (path != null) { + String[] split = path.split("\\."); + + for (String s : split) { + jsonObject = jsonObject.getJSONObject(s); + } + } + return jsonObject; + } + + public abstract String getUri(int page, int count); + +} diff --git a/src/main/java/com/catcher/batch/openapi/jsonparser/JsonBody.java b/src/main/java/com/catcher/batch/openapi/jsonparser/JsonBody.java new file mode 100644 index 0000000..0d13039 --- /dev/null +++ b/src/main/java/com/catcher/batch/openapi/jsonparser/JsonBody.java @@ -0,0 +1,6 @@ +package com.catcher.batch.openapi.jsonparser; + + +public interface JsonBody { + +} diff --git a/src/main/java/com/catcher/batch/openapi/jsonparser/JsonHeader.java b/src/main/java/com/catcher/batch/openapi/jsonparser/JsonHeader.java new file mode 100644 index 0000000..b005b13 --- /dev/null +++ b/src/main/java/com/catcher/batch/openapi/jsonparser/JsonHeader.java @@ -0,0 +1,6 @@ +package com.catcher.batch.openapi.jsonparser; + + +public interface JsonHeader { + boolean validate(); +} diff --git a/src/main/java/com/catcher/batch/openapi/jsonparser/festival/FestivalBody.java b/src/main/java/com/catcher/batch/openapi/jsonparser/festival/FestivalBody.java new file mode 100644 index 0000000..2062c2f --- /dev/null +++ b/src/main/java/com/catcher/batch/openapi/jsonparser/festival/FestivalBody.java @@ -0,0 +1,19 @@ +package com.catcher.batch.openapi.jsonparser.festival; + +import com.catcher.batch.openapi.jsonparser.JsonBody; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Getter; + +import java.util.List; + +@Getter +public class FestivalBody implements JsonBody { + @JsonProperty("items") + private List items; + @JsonProperty("totalCount") + private Integer totalCount; + @JsonProperty("numOfRows") + private Integer numOfRows; + @JsonProperty("pageNo") + private Integer pageNo; +} diff --git a/src/main/java/com/catcher/batch/openapi/jsonparser/festival/FestivalHeader.java b/src/main/java/com/catcher/batch/openapi/jsonparser/festival/FestivalHeader.java new file mode 100644 index 0000000..97fc5fc --- /dev/null +++ b/src/main/java/com/catcher/batch/openapi/jsonparser/festival/FestivalHeader.java @@ -0,0 +1,21 @@ +package com.catcher.batch.openapi.jsonparser.festival; + +import com.catcher.batch.openapi.jsonparser.JsonHeader; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Getter; + + +@Getter +public class FestivalHeader implements JsonHeader { + @JsonProperty("resultCode") + private String resultCode; + @JsonProperty("resultMsg") + private String resultMsg; + @JsonProperty("type") + private String type; + + @Override + public boolean validate() { + return resultCode.equals("00"); + } +} diff --git a/src/main/java/com/catcher/batch/openapi/jsonparser/festival/FestivalItem.java b/src/main/java/com/catcher/batch/openapi/jsonparser/festival/FestivalItem.java new file mode 100644 index 0000000..47b9cbc --- /dev/null +++ b/src/main/java/com/catcher/batch/openapi/jsonparser/festival/FestivalItem.java @@ -0,0 +1,23 @@ +package com.catcher.batch.openapi.jsonparser.festival; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Getter; + +import java.util.Date; + +@Getter +@JsonIgnoreProperties(ignoreUnknown=true) +public class FestivalItem { + @JsonProperty("fstvlNm") + private String name; + + @JsonProperty("rdnmadr") + private String address; + + @JsonProperty("fstvlStartDate") + private Date startDate; + + @JsonProperty("fstvlEndDate") + private Date endDate; +} diff --git a/src/test/java/com/catcher/batch/openapi/jsonparser/festival/FestivalJsonParserTest.java b/src/test/java/com/catcher/batch/openapi/jsonparser/festival/FestivalJsonParserTest.java new file mode 100644 index 0000000..7544823 --- /dev/null +++ b/src/test/java/com/catcher/batch/openapi/jsonparser/festival/FestivalJsonParserTest.java @@ -0,0 +1,52 @@ +package com.catcher.batch.openapi.jsonparser.festival; + +import com.catcher.batch.openapi.jsonparser.CatcherJsonParser; +import com.fasterxml.jackson.core.JsonProcessingException; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.Test; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.ResponseEntity; +import org.springframework.web.client.RestTemplate; + +import static org.assertj.core.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.*; +import static org.springframework.http.HttpMethod.GET; + +class FestivalJsonParserTest { + + + @Test + void 축제_데이터_파싱() throws JsonProcessingException { + String headerPath = "response.header"; + String bodyPath = "response.body"; + String endPoint = "http://api.data.go.kr/openapi/tn_pubr_public_cltur_fstvl_api"; + String serviceKey = ""; + + CatcherJsonParser festivalParser = new CatcherJsonParser(headerPath, bodyPath) { + @Override + public String getUri(int page, int count) { + return new StringBuilder() + .append(endPoint).append("?") + .append("serviceKey=").append(serviceKey) + .append("&").append("pageNo=").append(page) + .append("&").append("numOfRows=").append(count) + .append("&").append("type=").append("json").toString(); + } + }; + + RestTemplate restTemplate = new RestTemplate(); + HttpHeaders header = new HttpHeaders(); + HttpEntity entity = new HttpEntity<>(header); + + //when + ResponseEntity exchange = restTemplate.exchange(festivalParser.getUri(1, 5), GET, entity, String.class); + String body = exchange.getBody(); + + //then + FestivalHeader festivalHeader = festivalParser.parseHeader(body, FestivalHeader.class); + assertThat(festivalHeader.validate()).isTrue(); + FestivalBody festivalBody = festivalParser.parseBody(body, FestivalBody.class); + assertThat(festivalBody.getItems().size()).isEqualTo(5); + } +} \ No newline at end of file