Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
226 views
in Technique[技术] by (71.8m points)

java - Parsing JTS Geometry to GeoGSON with RESTEasy / Jackson / Quarkus

I'm trying to wrap an old EJB service (the logic inside) in a micro-service. I use Quarkus / RESTEasy to implement this microservice

However, I'm running into problems with customizing the serialization / deserialization.

Problem: Cannot construct instance of com.vividsolutions.jts.geom.Geometry which leads me to believe that Jackson is not considering Geometry as the class to parse into but a String. Which leads to believe me that the object mapper is not picked up..

Note1: I can see in the provided log statement in the Quarkus log: customizing ObjectMapper, adding geometry serializer / deserializer

Note2: Unit tests work nicely on the RegisterGeometryMapper .

This is the JSON I want to parse (note: the geometry is GeoGSON)

{
  "geometry": {
    "type": "Point",
    "coordinates": [
      134750,
      477800,
      3.18
    ],
    "crs": {
      "type": "name",
      "properties": {
        "name": "EPSG:28992"
      }
    }
  },
  "date": 1612519294297
}

This is the REST resource method:

    @POST
    @Path( "/etrs89-transformation" )
    @Consumes( MediaType.APPLICATION_JSON )
    @Produces( MediaType.APPLICATION_JSON )
    TransformationResult transformToEtrs89(@NotNull @Valid TransformationRequest request);

And its request DTO:

public class TransformationRequest {
    @NotNull private Geometry geometry;
    private Date date;
}

This is the mapper I registered.

@Singleton
public class RegisterGeometryMapper implements ObjectMapperCustomizer {

    private static final Logger LOG = Logger.getLogger( RegisterGeometryMapper .class );

    public void customize(ObjectMapper mapper) {
        LOG.debug( "customizing ObjectMapper, adding geometry serializer / deserializer." );
        SimpleModule module = new SimpleModule();
        module.addDeserializer( Geometry.class, new GeometryDeserializer() );
        module.addSerializer( Geometry.class, new GeometrySerializer() );
        mapper.registerModule( module );
    }

    public static class GeometryDeserializer extends StdDeserializer<Geometry> {

        private final GeoJsonReader reader = new GeoJsonReader();

        public GeometryDeserializer() {
            this( Geometry.class );
        }

        public GeometryDeserializer(Class<Geometry> vc) {
            super( vc );
        }

        @Override
        public Geometry deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
            JsonNode node = jp.getCodec().readTree( jp );
            String geoGson = node.toString();
            try {
                return reader.read( geoGson );
            }
            catch ( ParseException ex ) {
                throw new IOException( ex );
            }
        }
    }

    public static class GeometrySerializer extends StdSerializer<Geometry> {

        private final GeoJsonWriter writer = new GeoJsonWriter();

        protected GeometrySerializer() {
            this( Geometry.class );
        }

        protected GeometrySerializer(Class<Geometry> t) {
            super( t );
        }

        @Override
        public void serialize(Geometry geometry, JsonGenerator jgen, SerializerProvider serializerProvider) throws IOException {
            jgen.writeRawValue( writer.write( geometry ) );
        }
    }
}

The writer / reader originate from jts io.

        <!-- GeoJson -->
        <dependency>
            <groupId>com.vividsolutions</groupId>
            <artifactId>jts-io</artifactId>
            <version>1.14.0</version>
        </dependency>

Furthermore: I'm stuck to jts (cant migrate to the newer version - locationtech - because of legacy reasons, JBOSS EAP is stuck on a Hibernate which does not support locationtech).

question from:https://stackoverflow.com/questions/66059958/parsing-jts-geometry-to-geogson-with-resteasy-jackson-quarkus

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The solution above is correct and works.

The problem was that somewhere else in my code I added:

@Provider
public class JacksonConfig implements ContextResolver<ObjectMapper> {
    private final ObjectMapper objectMapper;

    public JacksonConfig() throws Exception {
        objectMapper = new ObjectMapper();
        objectMapper.enable( SerializationFeature.WRITE_DATES_AS_TIMESTAMPS );
    }

    @Override
    public ObjectMapper getContext(Class<?> arg0) {
        return objectMapper;
    }
}

Which creates a new ObjectMapper and undoes whatever I've done in my @Singleton class.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...