From 71daf78a50ede45b9e79d7750a4faa2911b0573d Mon Sep 17 00:00:00 2001 From: "gayoun.park" Date: Wed, 12 Nov 2025 13:58:40 +0900 Subject: [PATCH] =?UTF-8?q?ObjectMapper=20=EB=B9=88=20=EC=85=8B=ED=8C=85?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 1 + .../utils/geometry/GeometryDeserializer.java | 37 +++++++++++++++++++ .../utils/geometry/GeometrySerializer.java | 31 ++++++++++++++++ .../kamco/cd/kamcoback/config/WebConfig.java | 33 +++++++++++++++++ 4 files changed, 102 insertions(+) create mode 100644 src/main/java/com/kamco/cd/kamcoback/common/utils/geometry/GeometryDeserializer.java create mode 100644 src/main/java/com/kamco/cd/kamcoback/common/utils/geometry/GeometrySerializer.java create mode 100644 src/main/java/com/kamco/cd/kamcoback/config/WebConfig.java diff --git a/build.gradle b/build.gradle index 3d8296ed..f55ce79c 100644 --- a/build.gradle +++ b/build.gradle @@ -36,6 +36,7 @@ dependencies { //geometry implementation 'com.fasterxml.jackson.core:jackson-databind' implementation 'org.locationtech.jts.io:jts-io-common:1.20.0' + implementation 'org.locationtech.jts:jts-core:1.19.0' // QueryDSL JPA implementation 'com.querydsl:querydsl-jpa:5.0.0:jakarta' diff --git a/src/main/java/com/kamco/cd/kamcoback/common/utils/geometry/GeometryDeserializer.java b/src/main/java/com/kamco/cd/kamcoback/common/utils/geometry/GeometryDeserializer.java new file mode 100644 index 00000000..f6eecdb2 --- /dev/null +++ b/src/main/java/com/kamco/cd/kamcoback/common/utils/geometry/GeometryDeserializer.java @@ -0,0 +1,37 @@ +package com.kamco.cd.kamcoback.common.utils.geometry; + +import com.fasterxml.jackson.core.JacksonException; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.deser.std.StdDeserializer; +import org.locationtech.jts.geom.Geometry; +import org.locationtech.jts.io.geojson.GeoJsonReader; +import org.springframework.util.StringUtils; + +import java.io.IOException; + +public class GeometryDeserializer extends StdDeserializer { + + public GeometryDeserializer(Class targetType) { + super(targetType); + } + + // TODO: test code + @SuppressWarnings("unchecked") + @Override + public T deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) + throws IOException, JacksonException { + String json = jsonParser.readValueAsTree().toString(); + + if (!StringUtils.hasText(json)) { + return null; + } + + try { + GeoJsonReader reader = new GeoJsonReader(); + return (T) reader.read(json); + } catch (Exception e) { + throw new IllegalArgumentException("Failed to deserialize GeoJSON into Geometry", e); + } + } +} diff --git a/src/main/java/com/kamco/cd/kamcoback/common/utils/geometry/GeometrySerializer.java b/src/main/java/com/kamco/cd/kamcoback/common/utils/geometry/GeometrySerializer.java new file mode 100644 index 00000000..b5433da6 --- /dev/null +++ b/src/main/java/com/kamco/cd/kamcoback/common/utils/geometry/GeometrySerializer.java @@ -0,0 +1,31 @@ +package com.kamco.cd.kamcoback.common.utils.geometry; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.ser.std.StdSerializer; +import org.locationtech.jts.geom.Geometry; +import org.locationtech.jts.io.geojson.GeoJsonWriter; + +import java.io.IOException; +import java.util.Objects; + +public class GeometrySerializer extends StdSerializer { + + // TODO: test code + public GeometrySerializer(Class targetType) { + super(targetType); + } + + @Override + public void serialize(T geometry, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) + throws IOException { + if (Objects.nonNull(geometry)) { + // default: 8자리 강제로 반올림시킴. 16자리로 늘려줌 + GeoJsonWriter writer = new GeoJsonWriter(16); + String json = writer.write(geometry); + jsonGenerator.writeRawValue(json); + } else { + jsonGenerator.writeNull(); + } + } +} diff --git a/src/main/java/com/kamco/cd/kamcoback/config/WebConfig.java b/src/main/java/com/kamco/cd/kamcoback/config/WebConfig.java new file mode 100644 index 00000000..6671faba --- /dev/null +++ b/src/main/java/com/kamco/cd/kamcoback/config/WebConfig.java @@ -0,0 +1,33 @@ +package com.kamco.cd.kamcoback.config; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.module.SimpleModule; +import com.kamco.cd.kamcoback.common.utils.geometry.GeometryDeserializer; +import com.kamco.cd.kamcoback.common.utils.geometry.GeometrySerializer; +import org.locationtech.jts.geom.Geometry; +import org.locationtech.jts.geom.Point; +import org.locationtech.jts.geom.Polygon; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; + +@Configuration +public class WebConfig { + + @Bean + public ObjectMapper objectMapper() { + SimpleModule module = new SimpleModule(); + module.addSerializer(Geometry.class, new GeometrySerializer<>(Geometry.class)); + module.addDeserializer(Geometry.class, new GeometryDeserializer<>(Geometry.class)); + + module.addSerializer(Polygon.class, new GeometrySerializer<>(Polygon.class)); + module.addDeserializer(Polygon.class, new GeometryDeserializer<>(Polygon.class)); + + module.addSerializer(Point.class, new GeometrySerializer<>(Point.class)); + module.addDeserializer(Point.class, new GeometryDeserializer<>(Point.class)); + + return Jackson2ObjectMapperBuilder.json() + .modulesToInstall(module) + .build(); + } +}