自定义注解,jackson 序列化 GeoJSON Feature FeatureCollection GeometryCollection对象

自定义注解,jackson 序列化 GeoJSON Feature FeatureCollection GeometryCollection对象

自定义注解

@Documented
@Target({TYPE})
@Retention(RUNTIME)
public @interface GeoJsonType {
    /**
     * Returns the {@link FeatureType} to serialize to.
     *
     * @return the {@link FeatureType}
     */
    FeatureType type();
}
@Documented
@Target({METHOD, FIELD})
@Retention(RUNTIME)
@Inherited
public @interface GeoJsonProperty {
   String name() default "";
}
@Documented
@Target({METHOD, FIELD})
@Retention(RUNTIME)
public @interface GeoJsonId {
}
@Inherited
@Documented
@Target({METHOD, FIELD})
@Retention(RUNTIME)
public @interface GeoJsonGeometry {
}
@Inherited
@Documented
@Target({METHOD, FIELD})
@Retention(RUNTIME)
public @interface GeoJsonGeometries {
}
@Inherited
@Documented
@Target({METHOD, FIELD})
@Retention(RUNTIME)
public @interface GeoJsonFeatures {
}
@Getter
public enum FeatureType {
    /**
     * Geometry type <em>GeometryCollection</em>
     */
    GEOMETRY_COLLECTION(GeomConstants.GEOMETRY_COLLECTION),

    /**
     * GeoJson type <em>Feature</em>
     */
    FEATURE(GeomConstants.FEATURE),

    /**
     * GeoJson type <em>FeatureCollection</em>
     */
    FEATURE_COLLECTION(GeomConstants.FEATURE_COLLECTION);

    private String name;

    FeatureType(String name) {
        this.name = name;
    }
}

Jackson序列化类

public class ToGeoJsonSerializer extends JsonSerializer<Object> {

    @Override
    public Class<Object> handledType() {
        return Object.class;
    }

    @SneakyThrows
    @Override
    public void serialize(Object object, JsonGenerator gen, SerializerProvider provider) throws IOException {
        GeoJsonType geoJsonTypeAnnotation = object.getClass().getAnnotation(GeoJsonType.class);
        if (geoJsonTypeAnnotation == null) {
            throw BizException.newInstance("Annotation @GeoJson is not present.");
        }

        switch (geoJsonTypeAnnotation.type().getName()) {
            case GeomConstants.FEATURE:
                write(getFeatureFrom(object), gen, provider);
                break;
            case GeomConstants.FEATURE_COLLECTION:
                write(getFeatureCollectionFrom(object), gen);
                break;
            case GeomConstants.GEOMETRY_COLLECTION:
                write(getGeometryCollectionFrom(object), gen);
                break;
            default:
                throw BizException.newInstance("Unsupported GeoJsonType: " + geoJsonTypeAnnotation.type());
        }
    }

    private void write(GeometryCollectionDTO geometryCollection, JsonGenerator gen) throws IOException {
        gen.writeStartObject();
        gen.writeStringField(GeomConstants.TYPE, GeomConstants.GEOMETRY_COLLECTION);
        gen.writeObjectField(GeomConstants.GEOMETRIES, geometryCollection.getGeometries());
        gen.writeEndObject();
    }

    private void write(FeatureCollectionDTO featureCollection, JsonGenerator gen) throws IOException {
        gen.writeStartObject();
        gen.writeStringField(GeomConstants.TYPE, GeomConstants.FEATURE_COLLECTION);
        gen.writeObjectField(GeomConstants.FEATURES, featureCollection.getFeatures());
        gen.writeEndObject();
    }

    private void write(FeatureDTO feature, JsonGenerator gen, SerializerProvider provider) throws IOException {
        gen.writeStartObject();
        gen.writeStringField(GeomConstants.TYPE, GeomConstants.FEATURE);
        Object id = feature.getId();
        if (id != null) {
            gen.writeObjectField(GeomConstants.ID, id);
        }
        gen.writeFieldName(GeomConstants.GEOMETRY);
        Geometry geometry = feature.getGeometry();
        if (geometry != null) {
            new ToJsonGeometrySerializer().serialize(geometry, gen, provider);
        } else {
            gen.writeNull();
        }
        Object properties = feature.getProperties();
        if (null != properties) {
            gen.writeObjectField(GeomConstants.PROPERTIES, properties);
        }
        gen.writeEndObject();
    }

    private GeometryCollectionDTO getGeometryCollectionFrom(Object object) throws IllegalAccessException {
        GeometryCollectionDTO feature = new GeometryCollectionDTO();
        final Field[] fields = object.getClass().getDeclaredFields();

        for (Field field : fields) {
            final Annotation[] annotations = field.getAnnotations();
            if (annotations.length == 0) {
                continue;
            }

            field.setAccessible(true);
            final GeoJsonGeometries geoJsonGeometries = field.getAnnotation(GeoJsonGeometries.class);
            if (geoJsonGeometries != null) {
                final Object value = field.get(object);
                List<?> features;
                if (value == null) {
                    features = Collections.emptyList();
                } else if (value instanceof Object[]) {
                    features = Arrays.asList(((Object[]) value));
                } else if (value instanceof Collection) {
                    features = new ArrayList<>((Collection<?>) value);
                } else {
                    throw BizException.newInstance("Value of " + value.getClass().getName() + " is not an Array or Collection.");
                }
                feature.setGeometries(features);
            }
        }
        return feature;
    }

    private FeatureCollectionDTO getFeatureCollectionFrom(Object object) throws IllegalAccessException {
        FeatureCollectionDTO feature = new FeatureCollectionDTO();
        final Field[] fields = object.getClass().getDeclaredFields();

        for (Field field : fields) {
            final Annotation[] annotations = field.getAnnotations();
            if (annotations.length == 0) {
                continue;
            }

            field.setAccessible(true);
            final GeoJsonFeatures geoJsonFeatures = field.getAnnotation(GeoJsonFeatures.class);
            if (geoJsonFeatures != null) {
                final Object value = field.get(object);
                List<?> features;
                if (value == null) {
                    features = Collections.emptyList();
                } else if (value instanceof Object[]) {
                    features = Arrays.asList(((Object[]) value));
                } else if (value instanceof Collection) {
                    features = new ArrayList<>((Collection<?>) value);
                } else {
                    throw BizException.newInstance("Value of " + value.getClass().getName() + " is not an Array or Collection.");
                }
                feature.setFeatures(features);
            }
        }
        return feature;
    }

    private FeatureDTO getFeatureFrom(Object object) throws IllegalAccessException {
        FeatureDTO feature = new FeatureDTO();
        final Field[] fields = object.getClass().getDeclaredFields();
        for (Field field : fields) {
            final Annotation[] annotations = field.getAnnotations();
            if (annotations.length == 0) {
                continue;
            }

            field.setAccessible(true);
            final GeoJsonId geoJsonId = field.getAnnotation(GeoJsonId.class);
            if (geoJsonId != null) {
                feature.setId(field.get(object));
            }

            final GeoJsonProperty geoJsonProperty = field.getAnnotation(GeoJsonProperty.class);
            if (geoJsonProperty != null) {
                String name = StringUtils.isNotBlank(geoJsonProperty.name()) ? geoJsonProperty.name() : field.getName();
                feature.getProperties().put(name, field.get(object));
            }

            final GeoJsonGeometry geoJsonGeometry = field.getAnnotation(GeoJsonGeometry.class);
            if (geoJsonGeometry != null) {
                if (!field.getType().getName().equals(Geometry.class.getName())) {
                    throw BizException.newInstance("@GeoJsonGeometry only supported Geometry");
                }
                feature.setGeometry((Geometry) field.get(object));
            }
        }
        return feature;
    }
}

Jackson工具类

@Slf4j
public final class GisJacksonUtils {
    private static ObjectMapper OBJECT_MAPPER;

    private GisJacksonUtils() {
    }

    static {
        init();
    }

    private static void init() {
        OBJECT_MAPPER = new ObjectMapper();

        OBJECT_MAPPER.registerModule(new JtsModule());
    }

    public static String toJson(Object obj) {
        try {
            return OBJECT_MAPPER.writeValueAsString(obj);
        } catch (JsonProcessingException e) {
            log.error("输出json数据失败", e);
            throw BizException.newInstance(String.format("输出json数据失败 %s", e.getMessage()));
        }
    }

    public static String toPrettyJson(Object obj) {
        try {
            return OBJECT_MAPPER.writerWithDefaultPrettyPrinter().writeValueAsString(obj);
        } catch (JsonProcessingException e) {
            log.error("输出json数据失败", e);
            throw BizException.newInstance(String.format("输出json数据失败 %s", e.getMessage()));
        }
    }
}
import com.fasterxml.jackson.databind.module.SimpleModule;

/**
 * @author chenjunfan
 * @date 2023-06-29
 */
public class JtsModule extends SimpleModule {
    public JtsModule() {
        super("JtsModule");

        this.addSerializer(new ToJsonGeometrySerializer());
    }
}

Test代码

Feature

public class GeomFeatureTest {
    @Test
    public void test() {
        DemoFeature demoFeature = new DemoFeature();
        demoFeature.setId(1L);
        demoFeature.setGeom(GeomUtils.createPoint(1, 2));
        demoFeature.setName("test");
        demoFeature.setAddr("addr");

        System.out.println(JacksonUtils.toPrettyJson(demoFeature));
    }


    @Data
    @GeoJsonType(type = FeatureType.FEATURE)
    @JsonSerialize(using = ToGeoJsonSerializer.class)
    public static class DemoFeature {
        @GeoJsonId
        private Long id;
        @GeoJsonGeometry
        private Geometry geom;
        @GeoJsonProperty
        private String name;
        @GeoJsonProperty
        private String addr;
    }
}

运行结果

{
  "type" : "Feature",
  "id" : 1,
  "geometry" : {
    "type" : "Point",
    "coordinates" : [ 1.0, 2.0 ]
  },
  "properties" : {
    "name" : "test",
    "addr" : "addr"
  }
}

FeatureCollection

public class GeomFeatureCollectionTest {
    @Test
    public void test() {
        DemoFeature demoFeature = new DemoFeature();
        demoFeature.setId(1L);
        demoFeature.setGeom(GeomUtils.createPoint(1, 2));
        demoFeature.setName("test");
        demoFeature.setAddr("addr");

        DemoFeature demoFeature2 = new DemoFeature();
        demoFeature2.setId(2L);
        demoFeature2.setGeom(GeomUtils.createPoint(1, 2));
        demoFeature2.setName("test2");
        demoFeature2.setAddr("addr2");

        DemoFeatureCollection demoFeatureCollection = new DemoFeatureCollection();
        demoFeatureCollection.setList(Arrays.asList(demoFeature, demoFeature2));

        System.out.println(JacksonUtils.toPrettyJson(demoFeatureCollection));
    }

    @Data
    @GeoJsonType(type = FeatureType.FEATURE_COLLECTION)
    @JsonSerialize(using = ToGeoJsonSerializer.class)
    public static class DemoFeatureCollection {
        @GeoJsonFeatures
        private List<?> list;
    }

    @Data
    @GeoJsonType(type = FeatureType.FEATURE)
    @JsonSerialize(using = ToGeoJsonSerializer.class)
    public static class DemoFeature {
        @GeoJsonId
        private Long id;
        @GeoJsonGeometry
        private Geometry geom;
        @GeoJsonProperty
        private String name;
        @GeoJsonProperty
        private String addr;
    }
}

运行结果

{
  "type" : "FeatureCollection",
  "features" : [ {
    "type" : "Feature",
    "id" : 1,
    "geometry" : {
      "type" : "Point",
      "coordinates" : [ 1.0, 2.0 ]
    },
    "properties" : {
      "name" : "test",
      "addr" : "addr"
    }
  }, {
    "type" : "Feature",
    "id" : 2,
    "geometry" : {
      "type" : "Point",
      "coordinates" : [ 1.0, 2.0 ]
    },
    "properties" : {
      "name" : "test2",
      "addr" : "addr2"
    }
  } ]
}

GeometryCollection

public class GeometryCollectionTest {
    @Test
    public void test() {
        DemoGeometryCollection geometryCollection = new DemoGeometryCollection();
        geometryCollection.setList(Arrays.asList(GeomUtils.createPoint(1, 2),
                GeomUtils.createPoint(1, 2)));

        System.out.println(GisJacksonUtils.toPrettyJson(geometryCollection));
    }

    @Data
    @GeoJsonType(type = FeatureType.GEOMETRY_COLLECTION)
    @JsonSerialize(using = ToGeoJsonSerializer.class)
    public static class DemoGeometryCollection<T extends Geometry> {
        @GeoJsonGeometries
        private List<T> list;
    }
}

运行结果

{
  "type" : "GeometryCollection",
  "geometries" : [ {
    "type" : "Point",
    "coordinates" : [ 1.0, 2.0 ]
  }, {
    "type" : "Point",
    "coordinates" : [ 1.0, 2.0 ]
  } ]
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值