杰克逊在春季启动中反序列化GeoJson Point

Tom*_*Tom 6 java geojson jackson spring-boot

我有一个@Entity具有type属性的模型com.vividsolutions.jts.geom.Point。当我尝试在中呈现此模型时,出现@RestController了递归异常。

(StackOverflowError); nested exception is 
com.fasterxml.jackson.databind.JsonMappingException: Infinite 
recursion (StackOverflowError) (through reference chain: 
com.vividsolutions.jts.geom.Point[\"envelope\"]-
>com.vividsolutions.jts.geom.Point[\"envelope\"]....
Run Code Online (Sandbox Code Playgroud)

实体看起来像这样(为简洁起见简称):

@Entity
@Data
public class MyEntity{
    // ...
    @Column(columnDefinition = "geometry")
    private Point location;
    // ...
}
Run Code Online (Sandbox Code Playgroud)

经过研究,我发现这是因为杰克逊默认情况下无法反序列化GeoJson。添加此库应该可以解决此问题:https : //github.com/bedatadriven/jackson-datatype-jts

我现在不确定如何在Spring Boot的对象映射器中包含此模块。根据引导中的文档,我尝试通过@Configuration以下两种方式将其添加到中:

@Bean
public Jackson2ObjectMapperBuilder jacksonBuilder() {
    Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
    builder.modulesToInstall(new JtsModule());
    return builder;
}
Run Code Online (Sandbox Code Playgroud)

@Bean
public JtsModule jtsModule(){
    return new JtsModule();
}
Run Code Online (Sandbox Code Playgroud)

两者都没有删除异常。不好意思,如果这是重复的,但是我能找到的就是自定义ObjectMapper,在我对文档的理解中,这不是“弹簧启动方式”。

作为一种变通方法,我@JsonIgnore荷兰国际集团的Point和定制的getter和setter一个不存在协调对象,......但它不是我想保持它的方式。

Gho*_*tli 8

截至 2020 年,大多数 JTS 库都已过时并且不再工作。我在 Maven Central 上发现了一个最近更新的分支,它与 jackson-core:2.10.0和完美配合jts-core:1.16.1

implementation 'org.n52.jackson:jackson-datatype-jts:1.2.4'

使用示例:

    @Test
    void testJson() throws IOException {

        var objectMapper = new ObjectMapper();
        objectMapper.registerModule(new JtsModule());

        GeometryFactory gf = new GeometryFactory();
        Point point = gf.createPoint(new Coordinate(1.2345678, 2.3456789));

        String geojson = objectMapper.writeValueAsString(point);

        InputStream targetStream = new ByteArrayInputStream(geojson.getBytes());
        Point point2 = objectMapper.readValue(targetStream, Point.class);

        assertEquals(point, point2);
    }
Run Code Online (Sandbox Code Playgroud)

您不需要在类字段上使用任何注释或注册新的 Spring Bean,只需向 Jackson 注册 JTS 模块即可。


Kru*_*ein 6

@JsonSerialize也许您应该用和标记您的几何属性@JsonDeserialize。像这样:

import com.bedatadriven.jackson.datatype.jts.serialization.GeometryDeserializer;
import com.bedatadriven.jackson.datatype.jts.serialization.GeometrySerializer;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.vividsolutions.jts.geom.Geometry;
import fr.info.groloc.entity.json.GreffeDeserializer;

import javax.persistence.Entity;

@Entity
public class Table
{
    @JsonSerialize(using = GeometrySerializer.class)
    @JsonDeserialize(contentUsing = GeometryDeserializer.class)
    private Geometry coord;
    // ...
}
Run Code Online (Sandbox Code Playgroud)

如果您使用 Spring-Boot,您只需要:

import com.bedatadriven.jackson.datatype.jts.JtsModule;
// ...
@Bean
public JtsModule jtsModule()
{
    return new JtsModule();
}
Run Code Online (Sandbox Code Playgroud)

正如 Dave 所说,您需要将此依赖项添加到 pom.xml 中:

<dependency>
    <groupId>com.bedatadriven</groupId>
    <artifactId>jackson-datatype-jts</artifactId>
    <version>2.4</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)

  • 尝试将您的依赖项更改为:`&lt;dependency&gt; &lt;groupId&gt;org.n52.jackson&lt;/groupId&gt; &lt;artifactId&gt;jackson-datatype-jts&lt;/artifactId&gt; &lt;version&gt;1.2.9&lt;/version&gt; &lt;/dependency&gt; `这解决了我的几何序列化问题。 (2认同)