我希望能够通过成功注册Geolatte JSON模块并使用其反序列化程序来反序列化Spring Boot 3.2中的Geolatte Geometry

我可以在控制器中手动注册GeolatteGeomModule,但不能让Spring Boot自动取走它.

Entity个个

我的点数据实体是:

@Value
@Data
public class CheckDto implements Serializable {

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

然后我的AppConfig自动为杰克逊注册定制GeolatterGeomModule:

AppConfig

@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;
}

当我try 这个类的端点时,我得到堆栈跟踪:

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'
    at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:319)
    at org.springframework.web.servlet.mvc.method.annotation.HttpEntityMethodProcessor.handleReturnValue(HttpEntityMethodProcessor.java:245)
    at org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite.handleReturnValue(HandlerMethodReturnValueHandlerComposite.java:78)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:136)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:884)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:797)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1081)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:974)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1011)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:903)
    at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:564)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885)
    at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:205)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149)
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:166)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:482)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:115)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:341)
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:391)
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:894)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1740)
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52)
    at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
    at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.base/java.lang.Thread.run(Thread.java:833)  
    

从上面看,这GeolatteGeomModule是没有拿起来的.

如果我将控制器修改为手动呼叫GeolatteGeomModule,并从实体中删除@JsonDeserialize(using = GeometryDeserializer.class),则我将拥有:

Entity个个

@Value
@Data
public class CheckDto implements Serializable {

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

和我的控制器执行以下操作:

Controller

@Autowired
private final ObjectMapper objectMapper;

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

// Get test data with location
@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);
}

    

我得到了预期的结果:

    {
        "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
        ]
    }
}

我怎样才能让Spring注册模块,以便它自动完成这项工作?

推荐答案

与创建自己的对象映射器相比,定制Spring Boot为Web应用程序自动创建的对象映射器要容易得多.

有多种方法可以做到这一点,如下所述:https://www.baeldung.com/spring-boot-customize-jackson-objectmapper

在您的情况下,这应该足够了:

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

使用此定制器以及以下示例控制器和DTO:

@RestController
class GeolatteTestController {
    @GetMapping(value = "/custom5/{id}", produces = "application/json")
    public ResponseEntity<?> BirdSummaryDTOCustom5(@PathVariable Long id) {
        return ResponseEntity.ok()
                .contentType(MediaType.APPLICATION_JSON)
                .header("Custom-Header", "birdApp")
                .body(new CheckDto(id, point(WGS84, g(4.33, 53.21))));
    }
}

@Data
@AllArgsConstructor
class CheckDto implements Serializable {
    Long id;

    Point<G2D> location;
    // getters setters etc
}

达到localhost:8080/custom5/123将产生以下结果:

{
  "id": 123,
  "location": {
    "type": "Point",
    "crs": {
      "type": "name",
      "properties": {
        "name": "EPSG:4326"
      }
    },
    "coordinates": [
      4.33,
      53.21
    ]
  }
}

已使用Spring Boot 3.2.0-M2和org.geolatte:geolatte-geojson:1.9.1进行测试.

Java相关问答推荐

当列顺序更改时,Table View列列表的Change. wasPermanted()总是返回假

为什么我们仍然需要实现noArgsConstructor如果Java默认提供一个非参数化的构造函数?''

JUnit—如何模拟局部变量对象方法调用

存根基类的受保护方法

Spring data JPA/Hibernate根据id获取一个列值

放气总是压缩整个街区吗?

多重延迟签名

使用UTC时区将startDatetime转换为本地时间

格式中的特定回录键-值对

如何在我的世界中为互动增加冷却时间?

Cordova Android Gradle内部版本组件不兼容

无法播放音频:从资源加载库GStreamer-Lite失败

在应用getCellFormula()时,Excel引用中的文件名始终为";[1]";使用Apache POI()

RestTemplate Bean提供OkHttp3ClientHttpRequestFactory不支持Spring Boot 3中的请求正文缓冲

JavaFX,GridPane:在GridPane的列中生成元素将保持所有列的宽度

如何将RESTAssured';S的Http标题转换为<;字符串、字符串和>的映射?

Java递归泛型是否可以被视为继承和重写的语法糖

rest api服务 spring 启动中出现IllegalFormatConversionException

如何使用Rascal Evaluator从编译的JAR访问Rascal函数?

将天数添加到ZonedDateTime不会更改时间