Error de-serializing Geometry with Jackson

人走茶凉 提交于 2020-01-25 07:29:04

问题


I am trying to implement a simple geometry (GIS) controller with PostGIS database in Spring-Boot 2.2.1.

When I try to de-serialize my task entity which contains the Point Geometry I am getting error:

There was an unexpected error (type=Internal Server Error, status=500).
Could not write JSON: org.locationtech.jts.geom.Point cannot be cast to com.vividsolutions.jts.geom.Geometry; nested exception is com.fasterxml.jackson.databind.JsonMappingException: org.locationtech.jts.geom.Point cannot be cast to com.vividsolutions.jts.geom.Geometry `enter code here`(through reference chain: java.util.ArrayList[0]->com.example.depdev.entity.Task["location"])

My task entity is :

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
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 org.locationtech.jts.geom.Point;

@Entity
@Table(name = "task")
public class Task {

public Task () {
};

@Id
private Long id;
private String title;
@Column(columnDefinition = "geometry(Point,4326)")
@JsonSerialize(using = GeometrySerializer.class)
@JsonDeserialize(using = GeometryDeserializer.class)
private Point location;

// trimmed

I have tried to define location as both a point and a geometry but the error is the same.

My controller is able to persist a new task, but I get the previously posted error when I try to de-serialize it:

@GetMapping("/alltasks")
@ResponseBody
public List allTasks() throws JsonProcessingException {

    GeometryFactory gf = new GeometryFactory();
    Double y = -36.829;
    Double x = 174.896;

    Task testTask = new Task();
    testTask.setId(new Long(01));
    testTask.setTitle("Test Task");
    Point p = gf.createPoint(new Coordinate(x, y));
    p.setSRID(4326);
    testTask.setLocation(p);
    taskRepository.save(testTask);

    List<Task> listTasks = new ArrayList<>();
    listTasks = taskService.findAll();
    return listTasks;

I did have the recursion error that is posted here - but adding the JacksonConfig class has fixed this error.

For the sake of completeness here is the Jackson config class:

import com.bedatadriven.jackson.datatype.jts.JtsModule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class JacksonConfig {
    @Bean
    public JtsModule jtsModule() {
        return new JtsModule();
    }
}

My dependencies in my build.gradle is:

dependencies {
implementation 'org.hibernate:hibernate-spatial'
compile group: 'org.locationtech.jts', name: 'jts-core', version: '1.16.0'
compile group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.10.0'
compile group: 'com.bedatadriven', name: 'jackson-datatype-jts', version: '2.4'
implementation 'org.springframework.boot:spring-boot-starter-data-jdbc'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-data-ldap'
implementation 'org.springframework.boot:spring-boot-starter-jdbc'
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.springframework.boot:spring-boot-starter-web'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
runtimeOnly 'org.postgresql:postgresql'
testImplementation('org.springframework.boot:spring-boot-starter-test') {
    exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
}
testImplementation 'org.springframework.security:spring-security-test'

What do I need to do to get the task entity to JSON without this error?

UPDATE

There is no reference in my code to vividsolutions:


回答1:


The 3-rd party library which contains custom JTS Jackson serializers is still transitively using the old version.

As the vividsolutions namespace was translated to locationtech you get the runtime exception.

Consider to create a custom serializer which accepted the new locationtech geometries.




回答2:


As other pointed out there is a dependency still using the old version of point geometry (vividsolutions.geom rather than the newer locationtech).

Fortunately someone has branched jackson-databind. This branch will work with location tech :

https://mvnrepository.com/artifact/com.graphhopper.external/jackson-datatype-jts/0.10-2.5-1



来源:https://stackoverflow.com/questions/59291785/error-de-serializing-geometry-with-jackson

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!