LocalDateTime type conversion error reporting problem in Vert.x

Introduction

I am learning Vert.x recently. As for what it is and what it is useful for, I will update it in the blog when I have almost learned it. In short, it is lighter and faster than SpringBoot. The content of this article is an error encountered in the practice. Record it here and share it with the beginner Vert.x friends who encounter the same problem.

Error Demo Description

This demo is used to practice routing requests and return json response data after processing. Below I created an entity class that contains four attributes. The main error is reported on the attribute of type LocalDateTime.

package demo.module;

import com.fasterxml.jackson.annotation.JsonFormat;

import java.time.LocalDateTime;

/**
 * @author Huhailong
 * @Description
 * @Date 2022/11/9.
 */
public class UserInfo {
    
    
  private String username;
  private Integer age;
  private String gender;
  @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
  private LocalDateTime createTime;

  public String getUsername() {
    
    
    return username;
  }

  public void setUsername(String username) {
    
    
    this.username = username;
  }

  public Integer getAge() {
    
    
    return age;
  }

  public void setAge(Integer age) {
    
    
    this.age = age;
  }

  public String getGender() {
    
    
    return gender;
  }

  public void setGender(String gender) {
    
    
    this.gender = gender;
  }

  public LocalDateTime getCreateTime() {
    
    
    return createTime;
  }

  public void setCreateTime(LocalDateTime createTime) {
    
    
    this.createTime = createTime;
  }
}

The main code of the test route is as follows:

package demo;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import demo.module.UserInfo;
import io.vertx.core.AbstractVerticle;
import io.vertx.core.Future;
import io.vertx.core.Promise;
import io.vertx.core.http.HttpServer;
import io.vertx.core.http.HttpServerResponse;
import io.vertx.core.json.JsonObject;
import io.vertx.core.json.jackson.DatabindCodec;
import io.vertx.ext.web.Route;
import io.vertx.ext.web.Router;

import java.time.LocalDateTime;

public class MainVerticle extends AbstractVerticle {
    
    

  @Override
  public void start(Promise<Void> startPromise) throws Exception {
    
    
    System.setProperty("vertxweb.environment","dev");
    HttpServer httpServer = vertx.createHttpServer(); //创建HTTP服务
    Router router = Router.router(vertx); //创建路由对象
    UserInfo userInfo = new UserInfo();
    userInfo.setUsername("huhailong");
    userInfo.setAge(26);
    userInfo.setGender("man");
    userInfo.setCreateTime(LocalDateTime.now());
    router.get("/some/path/").respond(ctx-> Future.succeededFuture(new JsonObject().put("hello","world")));
    router.get("/some/path2/").respond(ctx-> Future.succeededFuture(userInfo));
    httpServer.requestHandler(router).listen(8888);
  }
}

In the test demo, I defined two routes. Here I mainly look at the path2 route. It returns a result of serializing UserInfo into JSON. The problem occurs here. The error content is as follows:

十一月 09, 2022 12:28:46 下午 io.vertx.ext.web.RoutingContext
严重: Unhandled exception in router
io.vertx.core.json.EncodeException: Failed to encode as JSON: Java 8 date/time type `java.time.LocalDateTime` not supported by default: add Module "com.fasterxml.jackson.datatype:jackson-datatype-jsr310" to ena
ble handling (through reference chain: demo.module.UserInfo["createTime"])
        at io.vertx.core.json.jackson.DatabindCodec.toBuffer(DatabindCodec.java:173)
        at io.vertx.core.spi.json.JsonCodec.toBuffer(JsonCodec.java:69)
        at io.vertx.core.json.Json.encodeToBuffer(Json.java:60)
        at io.vertx.ext.web.RoutingContext.json(RoutingContext.java:752)
        at io.vertx.ext.web.Route.lambda$null$0(Route.java:361)
        at io.vertx.core.impl.future.SucceededFuture.onSuccess(SucceededFuture.java:64)
        at io.vertx.ext.web.Route.lambda$respond$1(Route.java:341)
        at io.vertx.ext.web.impl.RouteState.handleContext(RouteState.java:1284)
        at io.vertx.ext.web.impl.RoutingContextImplBase.iterateNext(RoutingContextImplBase.java:173)
        at io.vertx.ext.web.impl.RoutingContextImpl.next(RoutingContextImpl.java:140)
        at io.vertx.ext.web.impl.RouterImpl.handle(RouterImpl.java:68)
        at io.vertx.ext.web.impl.RouterImpl.handle(RouterImpl.java:37)
        at io.vertx.core.http.impl.Http1xServerRequestHandler.handle(Http1xServerRequestHandler.java:67)
        at io.vertx.core.http.impl.Http1xServerRequestHandler.handle(Http1xServerRequestHandler.java:30)
        at io.vertx.core.impl.EventLoopContext.emit(EventLoopContext.java:55)
        at io.vertx.core.impl.DuplicatedContext.emit(DuplicatedContext.java:158)
        at io.vertx.core.http.impl.Http1xServerConnection.handleMessage(Http1xServerConnection.java:145)
        at io.vertx.core.net.impl.ConnectionBase.read(ConnectionBase.java:157)
        at io.vertx.core.net.impl.VertxHandler.channelRead(VertxHandler.java:153)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
        at io.netty.channel.ChannelInboundHandlerAdapter.channelRead(ChannelInboundHandlerAdapter.java:93)
        at io.netty.handler.codec.http.websocketx.extensions.WebSocketServerExtensionHandler.channelRead(WebSocketServerExtensionHandler.java:99)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
        at io.vertx.core.http.impl.Http1xUpgradeToH2CHandler.channelRead(Http1xUpgradeToH2CHandler.java:116)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
        at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:336)
        at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:308)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
        at io.vertx.core.http.impl.Http1xOrH2CHandler.end(Http1xOrH2CHandler.java:61)
        at io.vertx.core.http.impl.Http1xOrH2CHandler.channelRead(Http1xOrH2CHandler.java:38)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
        at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerCon        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerConte
xt.java:357)
        at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.jav
a:1410)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerCon
text.java:379)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
        at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919)
        at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:166)
        at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:788)
        at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:724)
        at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:650)
        at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:562)
        at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:997)
        at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
        at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
        at java.lang.Thread.run(Thread.java:748)

The error content shows that jackson-datatype-jsr310dependencies need to be added, but I added it, and this error is still the same.

problem causes

According to online search information, after version 2.13, the serialization of Java8 date/time is no longer supported by default, and then I went to the official website of Vert.x to find that the official solution has been given
insert image description here

Solution

Register time module for ObjectMapper

ObjectMapper mapper = DatabindCodec.mapper();
mapper.registerModule(new JavaTimeModule());

resolved code

package demo;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import demo.module.UserInfo;
import io.vertx.core.AbstractVerticle;
import io.vertx.core.Future;
import io.vertx.core.Promise;
import io.vertx.core.http.HttpServer;
import io.vertx.core.http.HttpServerResponse;
import io.vertx.core.json.JsonObject;
import io.vertx.core.json.jackson.DatabindCodec;
import io.vertx.ext.web.Route;
import io.vertx.ext.web.Router;

import java.time.LocalDateTime;

public class MainVerticle extends AbstractVerticle {
    
    

  @Override
  public void start(Promise<Void> startPromise) throws Exception {
    
    
    System.setProperty("vertxweb.environment","dev");
    HttpServer httpServer = vertx.createHttpServer(); //创建HTTP服务
    Router router = Router.router(vertx); //创建路由对象
    ObjectMapper mapper = DatabindCodec.mapper();
    mapper.registerModule(new JavaTimeModule());
    UserInfo userInfo = new UserInfo();
    userInfo.setUsername("huhailong");
    userInfo.setAge(26);
    userInfo.setGender("man");
    userInfo.setCreateTime(LocalDateTime.now());
    router.get("/some/path/").respond(ctx-> Future.succeededFuture(new JsonObject().put("hello","world")));
    router.get("/some/path2/").respond(ctx-> Future.succeededFuture(userInfo));
    httpServer.requestHandler(router).listen(8888);
  }
}

operation result
insert image description here

Summarize

When Vert.x serializes LocalDate or LocalDateTime, it needs to register the date and time module of jsr310 with ObjectMapper to take effect.
Still have to read the official website documentation carefully !!!

Guess you like

Origin blog.csdn.net/hhl18730252820/article/details/127767556