如何通过 Spring Boot Rest API 发送 PostGiS 几何和点数据类型

How to send PostGiS Geometry and Point data types through Spring Boot Rest API

提问人:Simonas Petkevičius 提问时间:8/11/2022 更新时间:9/7/2022 访问量:1429

问:

我有一个查询,它返回一个接口 OverlayDTO,这是我从本机查询中获取的。中心是PostGIS,正如您可能已经猜到的那样pointgeometrygeometry

@Query("SELECT " +
        "o.geometry as geometry, " +
        "o.center as center, " +
        "FROM Overlay o " +
        "WHERE  o.layer.id = :layerId")
List<OverlayDTO> getAllOverlays(long layerId);

接口:

import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.geom.Point;

public interface OverlayDTO {
    Geometry getGeometry();
    Point getCenter();
}

我想像这样通过REST API发送它(如果可能的话)(它应该调用一个服务并做更多的逻辑,但这是它的基本要点)

    @GetMapping(value="{layerId}")
public ResponseEntity<List<OverlayDTO>> getCompanyLayers(@PathVariable Long layerId) {
    List<OverlayDTO> overlays = mapRepository.getAllOverlays(layerId);
        
    return ResponseEntity.ok(overlays);
}

但是,我收到一个错误,杰克逊由于递归而无法映射。

Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: Infinite recursion (StackOverflowError); nested exception is com.fasterxml.jackson.databind.JsonMappingException: Infinite recursion (StackOverflowError) (through reference chain: org.locationtech.jts.geom.Polygon["envelope"]->org.locationtech.jts.geom.Polygon["envelope"]->org.locationtech.jts.geom.Polygon["envelope"]->org.locationtech.jts.geom.Polygon["envelope"]->org.locationtech.jts.geom.Polygon["envelope"]->org.locationtech.jts.geom.Polygon["envelope"]->org.locationtech.jts.geom.Polygon["envelope"]->org.locationtech.jts.geom.Polygon["envelope"]->org.locationtech.jts.geom.Polygon["envelope"]->org.locationtech.jts.geom.Polygon["envelope"]->org.locationtech.jts.geom.Polygon["envelope"]->org.locationtech.jts.geom.Polygon["envelope"]->org.locationtech.jts.geom.Polygon["envelope"]->org.locationtech.jts.geom.Polygon["envelope"]->org.locationtech.jts.geom.Polygon["envelope"]->org.locationtech.jts.geom.Polygon["envelope"]->org.locationtech.jts.geom.Polygon["envelope"]->org.locationtech.jts.geom.Polygon["envelope"]->org.locationtech.jts.geom.Polygon["envelope"]->org.locationtech.jts.geom.Polygon["envelope"]->org.locationtech.jts.geom.Polygon["envelope"]->org.locationtech.jts.geom.Polygon["envelope"]->org.locationtech.jts.geom.Polygon["envelope"]->org.locationtech.jts.geom.Polygon["envelope"]->org.locationtech.jts.geom.Polygon["envelope"]->org.locationtech.jts.geom.Polygon["envelope"]->org.locationtech.jts.geom.Polygon["envelope"]->org.locationtech.jts.geom.Polygon["envelope"]->org.locationtech.jts.geom.Polygon["envelope"]->org.locationtech.jts.geom.Polygon["envelope"]

我该如何解决这个问题?我应该以不同的方式查询数据,还是应该构建自己的 DTO 类并只发送 POJO?还是需要构建一些序列化器/反序列化器?

java spring postgis jts 休眠空间

评论


答:

2赞 Karel Maesen 8/11/2022 #1

您需要注册一个 Jackson 模块,该模块为 JTS 几何对象提供适当的序列化器和反序列化器。一个很好的候选者是 jackson-datatype-jts

如果你想要一个关于如何做到这一点的例子,你可以看看这篇博文。(我使用替代几何库编写了它,但该方法应该适用于 JTS 和 jackson-datatype-jts 模块)。

评论

0赞 Simonas Petkevičius 8/11/2022
答案应该有效,但是,我最终使用了这个 jackson-datatype-jts 实现 mvnrepository.com/artifact/org.n52.jackson/jackson-datatype-jts
0赞 slambeth 9/7/2022 #2

有一种通用的交换格式,即 GeoJSON。您可能需要编写 JTS 代码才能执行此操作,或者 PostGIS 具有直接从数据库对象生成 GeoJSON 的功能。

另一种更简单的方法是将对象转换为 WKT 并以 String 形式返回它们。PostGIS 和 JTS 都可以从 WKT 生成和转换。对于其他服务来说,这可能更容易使用,也可能不更容易,具体取决于进行调用的系统。WKT 唯一令人讨厌的事情是假设了 SRID。我创建了我的服务,以具有一个参数来请求客户端想要的 SRID(这当然需要您可以转换为请求的 SRID),或者,使您的服务始终以事实标准(如 4326)返回数据。