blu*_*ish 20 postgresql spring hibernate postgis spring-boot
在我的PostgreSQL 9.3 + PostGIS 2.1.5中,我有一个PLACE包含coordinates类型列的表Geometry(Point,26910).
我想Place在我的Spring Boot 1.1.9 Web应用程序中将它映射到实体,该应用程序使用Hibernate 4.0.0 +.Place可以使用REST存储库.
不幸的是,当我GET http://localhost:8080/mywebapp/places收到这个奇怪的JSON响应时:
{
  "_embedded" : {
    "venues" : [ {
      "id" : 1,
      "coordinates" : {
        "envelope" : {
          "envelope" : {
            "envelope" : {
              "envelope" : {
                "envelope" : {
                  "envelope" : {
                    "envelope" : {
                      "envelope" : {
                        "envelope" : {
                          "envelope" : {
                            "envelope" : {
                              "envelope" : {
                                "envelope" : {
                                  "envelope" : {
                                    "envelope" : {
                                      "envelope" : {
                                        "envelope" : {
                                          "envelope" : {
                                            "envelope" : {
等等......!春天日志没有帮助..
我正在使用这个application.properties:
spring.jpa.database-platform=org.hibernate.spatial.dialect.postgis.PostgisDialect
spring.jpa.show-sql=false
spring.jpa.hibernate.ddl-auto=update
spring.datasource.url=jdbc:postgresql://192.168.1.123/mywebapp
spring.datasource.username=postgres
spring.datasource.password=mypwd
spring.datasource.driverClassName=org.postgresql.Driver
首先,是否可以使用database-platform而不是database?也许我必须使用以下设置而不是上述设置?
spring.datasource.url=jdbc:postgresql_postGIS://192.168.1.123/mywebapp
spring.datasource.driverClassName=org.postgis.DriverWrapper
无论如何,我的实体是这样的:
@Entity
public class Place {
    @Id
    public int id;
    @Column(columnDefinition="Geometry")
    @Type(type="org.hibernate.spatial.GeometryType")    //"org.hibernatespatial.GeometryUserType" seems to be for older versions of Hibernate Spatial
    public com.vividsolutions.jts.geom.Point coordinates;
}
我的pom.xml包含这个相关部分:
<dependency>
    <groupId>org.postgresql</groupId>
    <artifactId>postgresql</artifactId>
    <version>9.3-1102-jdbc41</version>
</dependency>
<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-spatial</artifactId>
    <version>4.3</version><!-- compatible with Hibernate 4.3.x -->
    <exclusions>
        <exclusion>
            <artifactId>postgresql</artifactId>
            <groupId>postgresql</groupId>
        </exclusion>
    </exclusions>
</dependency>
有点奇怪的配置,我发现它在互联网上,它是现在最好用的.
我希望有人可以帮助我解决这个问题.:)
blu*_*ish 21
最后我发现我的配置没问题,可能是Jackson无法Point正确管理数据类型.所以我定制了它的JSON序列化和反序列化:
将这些注释添加到我们的coordinates字段:
@JsonSerialize(using = PointToJsonSerializer.class)
@JsonDeserialize(using = JsonToPointDeserializer.class)
创建这样的序列化器:
import java.io.IOException;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.vividsolutions.jts.geom.Point;
public class PointToJsonSerializer extends JsonSerializer<Point> {
    @Override
    public void serialize(Point value, JsonGenerator jgen,
            SerializerProvider provider) throws IOException,
            JsonProcessingException {
        String jsonValue = "null";
        try
        {
            if(value != null) {             
                double lat = value.getY();
                double lon = value.getX();
                jsonValue = String.format("POINT (%s %s)", lat, lon);
            }
        }
        catch(Exception e) {}
        jgen.writeString(jsonValue);
    }
}
创建这样的反序列化器:
import java.io.IOException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.vividsolutions.jts.geom.Point;
import com.vividsolutions.jts.geom.PrecisionModel;
public class JsonToPointDeserializer extends JsonDeserializer<Point> {
    private final static GeometryFactory geometryFactory = new GeometryFactory(new PrecisionModel(), 26910); 
    @Override
    public Point deserialize(JsonParser jp, DeserializationContext ctxt)
            throws IOException, JsonProcessingException {
        try {
            String text = jp.getText();
            if(text == null || text.length() <= 0)
                return null;
            String[] coordinates = text.replaceFirst("POINT ?\\(", "").replaceFirst("\\)", "").split(" ");
            double lat = Double.parseDouble(coordinates[0]);
            double lon = Double.parseDouble(coordinates[1]);
            Point point = geometryFactory.createPoint(new Coordinate(lat, lon));
            return point;
        }
        catch(Exception e){
            return null;
        }
    }
}
上面的解决方案帮助我解决了这个问题。我把它简化了,以便其他人可以理解。
我在我的 pom.xml 中包含了这个库:
<dependency>
  <groupId>com.bedatadriven</groupId>
  <artifactId>jackson-datatype-jts</artifactId>
  <version>2.2</version>
</dependency>
这是我使用的 POJO 对象。然后我能够在没有包络错误和正确坐标的情况下使 REST 调用正常工作。
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;
@Entity
@Table(name = "boundary")
public class Boundary {
    private int id;
    private Geometry geometry;
    @Id
    public int getId() {
        return ogc_fid;
    }
    public void setId(int id) {
        this.id = id;
    }
    
    @JsonSerialize(using = GeometrySerializer.class)
    @JsonDeserialize(using = GeometryDeserializer.class)
    @Column(name = "geometry", columnDefinition = "Geometry")
    public Geometry getGeometry() {
        return geometry;
    }
    public void setGeometry(Geometry geometry) {
        this.geometry = geometry;
    }
}
我的表有以下两列:
id       | integer            
geometry | geometry(Geometry,4326) | 
| 归档时间: | 
 | 
| 查看次数: | 11556 次 | 
| 最近记录: |