You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot 3.2如何自动注册Geolatte Jackson模块处理Point序列化反序列化

在Spring Boot 3.2中自动注册Geolatte JSON模块实现Point类型序列化/反序列化

需求

在Spring Boot 3.2环境下,完成Geolatte JSON模块的自动注册,使用其自带的序列化/反序列化器,实现Geolatte Geometry Point<G2D>类型的JSON序列化与反序列化。

当前问题

手动在控制器中注册GeolatteGeomModule后接口可正常返回结果,但无法通过配置让Spring Boot自动加载该模块,导致接口调用时出现序列化失败的错误。

具体细节

  1. 实体类定义(初始带注解版本)
@Value
@Data
public class CheckDto implements Serializable {

    Long id;
    @JsonSerialize(using = GeometrySerializer.class)
    @JsonDeserialize(using = GeometryDeserializer.class)
    Point<G2D> location;
    // getters setters 等方法
}
  1. 尝试自动注册的配置类(未生效)
@Configuration
@EnableEntityViews("com.nz.kiwi.model")
@ComponentScan("com.nz.kiwi")
public class AppConfig {
    @Bean
    public ObjectMapper mapper() {
        CoordinateReferenceSystem<G2D> crs = WGS84;
        ObjectMapper gMapper = new ObjectMapper();
        gMapper.registerModule(new GeolatteGeomModule(crs));
        return gMapper;
    }
}
  1. 接口调用报错信息

Mon Sep 04 18:45:46 NZST 2023
There was an unexpected error (type=Internal Server Error, status=500).
No converter for [class com.nz.kiwi.view.HealthCheckDto] with preset Content-Type 'application/json'
org.springframework.http.converter.HttpMessageNotWritableException: No converter for [class com.nz.kiwi.view.HealthCheckDto] with preset Content-Type 'application/json'
...(省略部分栈跟踪)

该错误说明Spring Boot并未识别到注册的GeolatteGeomModule,无法处理Point<G2D>类型的序列化。

  1. 手动注册可正常运行的场景
    移除实体类上的序列化/反序列化注解:
@Value
@Data
public class CheckDto implements Serializable {

    Long id;
    //@JsonSerialize(using = GeometrySerializer.class)
    //@JsonDeserialize(using = GeometryDeserializer.class)
    Point<G2D> location;
    // getters setters 等方法
}

在控制器中手动创建并注册模块:

@Autowired
private final ObjectMapper objectMapper;

// 注册GeoLatteGeomModule
public ObjectMapper mapper() {
    CoordinateReferenceSystem<G2D> crs = WGS84;
    ObjectMapper gMapper = new ObjectMapper();
    gMapper.registerModule(new GeolatteGeomModule(crs));
    gMapper.registerModule(new JavaTimeModule());
    return gMapper;
}

// 获取带位置信息的测试数据
@GetMapping(value = "/custom5/{id}", produces = "application/json")
public ResponseEntity<?> BirdSummaryDTOCustom5(@PathVariable Long id) throws JsonProcessingException {
    HealthCheckDto hcDto = customBirdRepository.customQuery5(id);
    ObjectMapper objectMapper = mapper();
    String json = objectMapper.writeValueAsString(hcDto);
    return ResponseEntity.ok()
            .contentType(MediaType.APPLICATION_JSON)
            .header("Custom-Header", "birdApp")
            .body(json);
}

此时接口可返回正确的JSON结果:

{
    "id": 5,
    "catchDateTime": "2023-06-05 11:18",
    "releaseDateTime": "2023-06-05 11:45",
    "location": {
        "type": "Point",
        "crs": {
            "type": "name",
            "properties": {
                "name": "EPSG:4326"
            }
        },
        "coordinates": [
            173.5,
            -35.5
        ]
    }
}

解决方案

问题出在原配置类中新建了一个ObjectMapper实例,但Spring Boot MVC使用的是由JacksonAutoConfiguration自动配置的全局ObjectMapper,因此手动创建的ObjectMapper并未被框架使用。正确的做法是通过Jackson2ObjectMapperBuilderCustomizer来定制全局的ObjectMapper,实现模块的自动注册:

正确的配置类

@Configuration
@EnableEntityViews("com.nz.kiwi.model")
@ComponentScan("com.nz.kiwi")
public class AppConfig {

    @Bean
    public Jackson2ObjectMapperBuilderCustomizer geolatteModuleCustomizer() {
        CoordinateReferenceSystem<G2D> crs = WGS84;
        return builder -> builder.modules(new GeolatteGeomModule(crs), new JavaTimeModule());
    }
}

关键说明

  1. 使用Jackson2ObjectMapperBuilderCustomizer可以直接对Spring Boot自动配置的ObjectMapper进行扩展,确保注册的模块被全局使用。
  2. 实体类可以完全移除@JsonSerialize和@JsonDeserialize注解,因为GeolatteGeomModule会自动为Point<G2D>类型绑定对应的序列化/反序列化器。
  3. 同时注册JavaTimeModule可以处理Java 8+的日期时间类型,避免额外的序列化问题。

配置完成后,无需在控制器中手动处理ObjectMapper,直接返回DTO对象即可实现自动序列化:

@GetMapping(value = "/custom5/{id}", produces = "application/json")
public ResponseEntity<HealthCheckDto> BirdSummaryDTOCustom5(@PathVariable Long id) {
    HealthCheckDto hcDto = customBirdRepository.customQuery5(id);
    return ResponseEntity.ok()
            .contentType(MediaType.APPLICATION_JSON)
            .header("Custom-Header", "birdApp")
            .body(hcDto);
}

内容的提问来源于stack exchange,提问作者Al Grant

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 19:40:54