Vert.x中LocalDateTime类型转化报错问题

简介

最近在学习Vert.x,至于它是什么有什么用等我学习的差不多了会更新在博客中,总之它比SpringBoot要轻,快速。本篇内容是在练习中遇到的一个报错,在这里记录以下,分享给遇到同样问题的初学Vert.x的小伙伴。

报错Demo描述

这个Demo是用来练习路由请求并进行处理后返回json响应数据,下面我创建了一个实体类,包含了四个属性,主要报错是在类型为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;
  }
}

测试路由主要代码如下:

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

测试demo中我定义了俩个路由,这里主要看path2这个路由,它返回了一个将UserInfo序列化为JSON的结果,问题就出现在这里,报错内容如下:

十一月 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)

报错内容显示需要添加jackson-datatype-jsr310依赖,但是我添加了,还是这个错误。

问题原因

根据网上查找资料得知,在2.13版本后默认不再支持Java8 date/time 的序列化,然后去Vert.x的官网发现其实官方已经给出了解决方法
在这里插入图片描述

解决方法

为ObjectMapper注册time模块

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

解决后的代码

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

运行结果
在这里插入图片描述

总结

Vert.x 在对LocalDate或LocalDateTime进行序列化时需要将jsr310的日期时间模块注册到ObjectMapper中生效。
还是得仔细阅读官网文档呀!!!

猜你喜欢

转载自blog.csdn.net/hhl18730252820/article/details/127767556