问题
I have a @Entity
model that has a property of type com.vividsolutions.jts.geom.Point
. When I try to render this model in a @RestController
I get a recursion exception.
(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\"]....
The entity looks like this (shortened for brevity):
@Entity
@Data
public class MyEntity{
// ...
@Column(columnDefinition = "geometry")
private Point location;
// ...
}
After some research I found out that this is because Jackson cannot deserialize GeoJson by default. Adding this library should solve the issue: https://github.com/bedatadriven/jackson-datatype-jts.
I am now not sure how to include this module in the object mapper in spring boot. As per documentation in boot, I tried adding it to the @Configuration
in the following two ways:
@Bean
public Jackson2ObjectMapperBuilder jacksonBuilder() {
Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
builder.modulesToInstall(new JtsModule());
return builder;
}
and
@Bean
public JtsModule jtsModule(){
return new JtsModule();
}
Both didn't remove the exception. Sry if this is a duplicate, but all I was able to find SO were customising the ObjectMapper
which in my understanding of the documentation is no the "spring boot way".
As a workaround I am @JsonIgnore
ing the Point
and have custom getters and setters for a non existent coordinated object,... but it's not the way I'd like to keep it.
回答1:
Maybe you should tag your geometric attribute with @JsonSerialize
and @JsonDeserialize
. Like this:
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;
// ...
}
If you are using Spring-Boot you only need for:
import com.bedatadriven.jackson.datatype.jts.JtsModule;
// ...
@Bean
public JtsModule jtsModule()
{
return new JtsModule();
}
As Dave said you need to add this dependency to your pom.xml:
<dependency>
<groupId>com.bedatadriven</groupId>
<artifactId>jackson-datatype-jts</artifactId>
<version>2.4</version>
</dependency>
来源:https://stackoverflow.com/questions/45713934/jackson-deserialize-geojson-point-in-spring-boot