Eclipse Vert.x:使用 jackson 解析 java.time 日期
Eclipse Vert.x : parsing java.time date with jackson
我正在尝试通过创建一个小型 ReST API 来学习 Vert.x。在我添加数据库后端之前,一切都很顺利。我选择了 Postgres 作为数据库。当 java.time LocalDate 被解析为 JSON 时,我的问题就出现了。据我了解,我需要杰克逊后端来解析它。我通过 Maven 依赖项将它添加到我的类路径中。存在依赖性,但框架会抛出一个异常,因为它找不到名为 jackson-datatype-jsr310 的 jackson 插件。好吧,它就在那里,所以我有点卡住了...
我正在使用 Vert.x 4 和 java 16,我在 Windows 上开发10 个使用 IntelliJ IDEA。
openjdk 16.0.1 2021-04-20
OpenJDK Runtime Environment AdoptOpenJDK-16.0.1+9 (build 16.0.1+9)
OpenJDK 64-Bit Server VM AdoptOpenJDK-16.0.1+9 (build 16.0.1+9, mixed mode, sharing)
我的pom
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>myapi</artifactId>
<version>1.0.0-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven-compiler-plugin.version>3.8.1</maven-compiler-plugin.version>
<maven-shade-plugin.version>3.2.4</maven-shade-plugin.version>
<maven-surefire-plugin.version>2.22.2</maven-surefire-plugin.version>
<exec-maven-plugin.version>3.0.0</exec-maven-plugin.version>
<vertx.version>4.1.4</vertx.version>
<junit-jupiter.version>5.8.0</junit-jupiter.version>
<log4j.version>2.14.1</log4j.version>
<jackson.version>2.13.0-rc2</jackson.version>
<main.verticle>dev.schaw.myapi.MainVerticle</main.verticle>
<launcher.class>io.vertx.core.Launcher</launcher.class>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-stack-depchain</artifactId>
<version>${vertx.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-web</artifactId>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-junit5</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>${junit-jupiter.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>${junit-jupiter.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-config</artifactId>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-pg-client</artifactId>
<version>${vertx.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven-compiler-plugin.version}</version>
<configuration>
<release>11</release>
</configuration>
</plugin>
<plugin>
<artifactId>maven-shade-plugin</artifactId>
<version>${maven-shade-plugin.version}</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<manifestEntries>
<Main-Class>${launcher.class}</Main-Class>
<Main-Verticle>${main.verticle}</Main-Verticle>
</manifestEntries>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
</transformers>
<outputFile>${project.build.directory}/${project.artifactId}-${project.version}-fat.jar
</outputFile>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>${maven-surefire-plugin.version}</version>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>${exec-maven-plugin.version}</version>
<configuration>
<mainClass>io.vertx.core.Launcher</mainClass>
<arguments>
<argument>run</argument>
<argument>${main.verticle}</argument>
</arguments>
</configuration>
</plugin>
</plugins>
</build>
</project>
我的垂直
package dev.schaw.myapi;
import io.vertx.config.ConfigRetriever;
import io.vertx.config.ConfigRetrieverOptions;
import io.vertx.config.ConfigStoreOptions;
import io.vertx.core.AbstractVerticle;
import io.vertx.core.AsyncResult;
import io.vertx.core.http.HttpMethod;
import io.vertx.core.http.HttpServer;
import io.vertx.core.http.HttpServerResponse;
import io.vertx.core.json.JsonObject;
import io.vertx.ext.web.Router;
import io.vertx.pgclient.PgConnectOptions;
import io.vertx.pgclient.PgPool;
import io.vertx.sqlclient.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class MainVerticle extends AbstractVerticle {
private HttpServer server;
private Router router;
private Logger logger;
private SqlClient sqlClient;
@Override
public void start() {
server = vertx.createHttpServer();
router = Router.router(vertx);
logger = LoggerFactory.getLogger(MainVerticle.class);
ConfigRetriever retriever = ConfigRetriever.create(vertx, new ConfigRetrieverOptions()
.addStore(new ConfigStoreOptions()
.setType("file")
.setConfig(new JsonObject().put("path", "config.json"))));
retriever.getConfig(this::onConfigRetrieved);
}
public void onConfigRetrieved(AsyncResult<JsonObject> configAsyncResult){
JsonObject config = configAsyncResult.result();
JsonObject dataConnection = config.getJsonObject("myapi").getJsonObject("dataConnection");
PgConnectOptions connectOptions = new PgConnectOptions()
.setHost(dataConnection.getString("host"))
.setPort(dataConnection.getInteger("port"))
.setDatabase(dataConnection.getString("database"))
.setUser(dataConnection.getString("user"))
.setPassword(dataConnection.getString("password"));
PoolOptions poolOptions = new PoolOptions().setMaxSize(5);
sqlClient = PgPool.pool(vertx, connectOptions, poolOptions);
router.route(HttpMethod.GET, "/").handler(ctx -> {
logger.info("received a request");
HttpServerResponse response = ctx.response();
response.putHeader("content-type", "text/plain");
response.end("Hello World!\n");
});
router.get("/data").handler(ctx -> {
sqlClient.preparedQuery("SELECT * FROM sample_data WHERE id=")
.execute(Tuple.of(1), queryAsyncResult -> {
RowSet<Row> set = queryAsyncResult.result();
if(set.rowCount() != 1){
ctx.fail(404);
}
Row r = set.iterator().next();
JsonObject body = new JsonObject().put("id", r.getInteger("id"))
.put("name", r.getString("name"))
.put("date", r.getLocalDate("date"));
ctx.response().putHeader("content-type", "application/json").end(body.encode());
});
});
int port = config
.getJsonObject("myapi")
.getJsonObject("server")
.getInteger("port");
server.requestHandler(router).listen(port);
}
}
数据库初始化脚本
create table sample_data (
id serial primary key,
name varchar(80) not null,
date date not null
);
这里是个例外
您可以在此处检查类路径。
"C:\Program Files\AdoptOpenJDK\jdk-16.0.1.9-hotspot\bin\java.exe" -agentlib:jdwp=transport=dt_socket,address=127.0.0.1:53414,suspend=y,server=n -javaagent:C:\Users\willi\AppData\Local\JetBrains\Toolbox\apps\IDEA-U\ch-02.5284.40\plugins\java\lib\rt\debugger-agent.jar -Dfile.encoding=UTF-8 -classpath C:\Users\willi\Projects\myapi\target\classes;C:\Users\willi\.m2\repository\com\fasterxml\jackson\core\jackson-core.13.0-rc2\jackson-core-2.13.0-rc2.jar;C:\Users\willi\.m2\repository\com\fasterxml\jackson\core\jackson-databind.13.0-rc2\jackson-databind-2.13.0-rc2.jar;C:\Users\willi\.m2\repository\com\fasterxml\jackson\core\jackson-annotations.13.0-rc2\jackson-annotations-2.13.0-rc2.jar;C:\Users\willi\.m2\repository\com\fasterxml\jackson\datatype\jackson-datatype-jsr310.13.0-rc2\jackson-datatype-jsr310-2.13.0-rc2.jar;C:\Users\willi\.m2\repository\com\fasterxml\jackson\datatype\jackson-datatype-jdk8.13.0-rc2\jackson-datatype-jdk8-2.13.0-rc2.jar;C:\Users\willi\.m2\repository\io\vertx\vertx-web.1.4\vertx-web-4.1.4.jar;C:\Users\willi\.m2\repository\io\vertx\vertx-web-common.1.4\vertx-web-common-4.1.4.jar;C:\Users\willi\.m2\repository\io\vertx\vertx-auth-common.1.4\vertx-auth-common-4.1.4.jar;C:\Users\willi\.m2\repository\io\vertx\vertx-bridge-common.1.4\vertx-bridge-common-4.1.4.jar;C:\Users\willi\.m2\repository\io\vertx\vertx-core.1.4\vertx-core-4.1.4.jar;C:\Users\willi\.m2\repository\io\netty\netty-common.1.67.Final\netty-common-4.1.67.Final.jar;C:\Users\willi\.m2\repository\io\netty\netty-buffer.1.67.Final\netty-buffer-4.1.67.Final.jar;C:\Users\willi\.m2\repository\io\netty\netty-transport.1.67.Final\netty-transport-4.1.67.Final.jar;C:\Users\willi\.m2\repository\io\netty\netty-handler.1.67.Final\netty-handler-4.1.67.Final.jar;C:\Users\willi\.m2\repository\io\netty\netty-codec.1.67.Final\netty-codec-4.1.67.Final.jar;C:\Users\willi\.m2\repository\io\netty\netty-handler-proxy.1.67.Final\netty-handler-proxy-4.1.67.Final.jar;C:\Users\willi\.m2\repository\io\netty\netty-codec-socks.1.67.Final\netty-codec-socks-4.1.67.Final.jar;C:\Users\willi\.m2\repository\io\netty\netty-codec-http.1.67.Final\netty-codec-http-4.1.67.Final.jar;C:\Users\willi\.m2\repository\io\netty\netty-codec-http2.1.67.Final\netty-codec-http2-4.1.67.Final.jar;C:\Users\willi\.m2\repository\io\netty\netty-resolver.1.67.Final\netty-resolver-4.1.67.Final.jar;C:\Users\willi\.m2\repository\io\netty\netty-resolver-dns.1.67.Final\netty-resolver-dns-4.1.67.Final.jar;C:\Users\willi\.m2\repository\io\netty\netty-codec-dns.1.67.Final\netty-codec-dns-4.1.67.Final.jar;C:\Users\willi\.m2\repository\io\vertx\vertx-config.1.4\vertx-config-4.1.4.jar;C:\Users\willi\.m2\repository\org\apache\logging\log4j\log4j-api.14.1\log4j-api-2.14.1.jar;C:\Users\willi\.m2\repository\org\apache\logging\log4j\log4j-core.14.1\log4j-core-2.14.1.jar;C:\Users\willi\.m2\repository\org\apache\logging\log4j\log4j-slf4j-impl.14.1\log4j-slf4j-impl-2.14.1.jar;C:\Users\willi\.m2\repository\org\slf4j\slf4j-api.7.25\slf4j-api-1.7.25.jar;C:\Users\willi\.m2\repository\io\vertx\vertx-pg-client.1.4\vertx-pg-client-4.1.4.jar;C:\Users\willi\.m2\repository\io\vertx\vertx-sql-client.1.4\vertx-sql-client-4.1.4.jar;C:\Users\willi\AppData\Local\JetBrains\Toolbox\apps\IDEA-U\ch-02.5284.40\lib\idea_rt.jar io.vertx.core.Launcher run dev.schaw.myapi.MainVerticle
Connected to the target VM, address: '127.0.0.1:53414', transport: 'socket'
OpenJDK 64-Bit Server VM warning: Sharing is only supported for boot loader classes because bootstrap classpath has been appended
16:06:01.100 [vert.x-eventloop-thread-0] INFO io.vertx.core.impl.launcher.commands.VertxIsolatedDeployer - Succeeded in deploying verticle
16:06:03.393 [vert.x-eventloop-thread-1] ERROR io.vertx.core.impl.ContextImpl - Unhandled exception
io.vertx.core.json.EncodeException: Failed to encode as JSON: Java 8 date/time type `java.time.LocalDate` not supported by default: add Module "com.fasterxml.jackson.datatype:jackson-datatype-jsr310" to enable handling (through reference chain: java.util.LinkedHashMap["date"])
at io.vertx.core.json.jackson.DatabindCodec.toString(DatabindCodec.java:163) ~[vertx-core-4.1.4.jar:4.1.4]
at io.vertx.core.json.JsonObject.encode(JsonObject.java:728) ~[vertx-core-4.1.4.jar:4.1.4]
at dev.schaw.myapi.MainVerticle.lambda$onConfigRetrieved(MainVerticle.java:73) ~[classes/:?]
at io.vertx.core.impl.future.FutureImpl.onSuccess(FutureImpl.java:141) ~[vertx-core-4.1.4.jar:4.1.4]
at io.vertx.core.impl.future.FutureBase.emitSuccess(FutureBase.java:60) ~[vertx-core-4.1.4.jar:4.1.4]
at io.vertx.core.impl.future.FutureImpl.tryComplete(FutureImpl.java:211) ~[vertx-core-4.1.4.jar:4.1.4]
at io.vertx.core.impl.future.PromiseImpl.tryComplete(PromiseImpl.java:23) ~[vertx-core-4.1.4.jar:4.1.4]
at io.vertx.sqlclient.impl.QueryResultBuilder.tryComplete(QueryResultBuilder.java:102) ~[vertx-sql-client-4.1.4.jar:4.1.4]
at io.vertx.sqlclient.impl.QueryResultBuilder.tryComplete(QueryResultBuilder.java:35) ~[vertx-sql-client-4.1.4.jar:4.1.4]
at io.vertx.core.Promise.complete(Promise.java:66) ~[vertx-core-4.1.4.jar:4.1.4]
at io.vertx.core.Promise.handle(Promise.java:51) ~[vertx-core-4.1.4.jar:4.1.4]
at io.vertx.core.Promise.handle(Promise.java:29) ~[vertx-core-4.1.4.jar:4.1.4]
at io.vertx.core.impl.future.FutureImpl.onSuccess(FutureImpl.java:141) ~[vertx-core-4.1.4.jar:4.1.4]
at io.vertx.core.impl.future.FutureBase.emitSuccess(FutureBase.java:60) ~[vertx-core-4.1.4.jar:4.1.4]
at io.vertx.core.impl.future.FutureImpl.tryComplete(FutureImpl.java:211) ~[vertx-core-4.1.4.jar:4.1.4]
at io.vertx.core.impl.future.PromiseImpl.tryComplete(PromiseImpl.java:23) ~[vertx-core-4.1.4.jar:4.1.4]
at io.vertx.core.impl.future.PromiseImpl.onSuccess(PromiseImpl.java:49) ~[vertx-core-4.1.4.jar:4.1.4]
at io.vertx.core.impl.future.FutureImpl$ListenerArray.onSuccess(FutureImpl.java:262) ~[vertx-core-4.1.4.jar:4.1.4]
at io.vertx.core.impl.future.FutureBase.lambda$emitSuccess[=16=](FutureBase.java:54) ~[vertx-core-4.1.4.jar:4.1.4]
at io.vertx.core.impl.EventLoopContext.execute(EventLoopContext.java:81) ~[vertx-core-4.1.4.jar:4.1.4]
at io.vertx.core.impl.DuplicatedContext.execute(DuplicatedContext.java:173) ~[vertx-core-4.1.4.jar:4.1.4]
at io.vertx.core.impl.future.FutureBase.emitSuccess(FutureBase.java:51) ~[vertx-core-4.1.4.jar:4.1.4]
at io.vertx.core.impl.future.FutureImpl.tryComplete(FutureImpl.java:211) ~[vertx-core-4.1.4.jar:4.1.4]
at io.vertx.core.impl.future.PromiseImpl.tryComplete(PromiseImpl.java:23) ~[vertx-core-4.1.4.jar:4.1.4]
at io.vertx.core.impl.future.PromiseImpl.onSuccess(PromiseImpl.java:49) ~[vertx-core-4.1.4.jar:4.1.4]
at io.vertx.core.impl.future.PromiseImpl.handle(PromiseImpl.java:41) ~[vertx-core-4.1.4.jar:4.1.4]
at io.vertx.core.impl.future.PromiseImpl.handle(PromiseImpl.java:23) ~[vertx-core-4.1.4.jar:4.1.4]
at io.vertx.sqlclient.impl.command.CommandResponse.fire(CommandResponse.java:46) ~[vertx-sql-client-4.1.4.jar:4.1.4]
at io.vertx.sqlclient.impl.SocketConnectionBase.handleMessage(SocketConnectionBase.java:287) ~[vertx-sql-client-4.1.4.jar:4.1.4]
at io.vertx.pgclient.impl.PgSocketConnection.handleMessage(PgSocketConnection.java:96) ~[vertx-pg-client-4.1.4.jar:4.1.4]
at io.vertx.sqlclient.impl.SocketConnectionBase.lambda$init[=16=](SocketConnectionBase.java:99) ~[vertx-sql-client-4.1.4.jar:4.1.4]
at io.vertx.core.net.impl.NetSocketImpl.lambda$new(NetSocketImpl.java:97) ~[vertx-core-4.1.4.jar:4.1.4]
at io.vertx.core.streams.impl.InboundBuffer.handleEvent(InboundBuffer.java:240) ~[vertx-core-4.1.4.jar:4.1.4]
at io.vertx.core.streams.impl.InboundBuffer.write(InboundBuffer.java:130) ~[vertx-core-4.1.4.jar:4.1.4]
at io.vertx.core.net.impl.NetSocketImpl.lambda$handleMessage(NetSocketImpl.java:390) ~[vertx-core-4.1.4.jar:4.1.4]
at io.vertx.core.impl.EventLoopContext.emit(EventLoopContext.java:50) ~[vertx-core-4.1.4.jar:4.1.4]
at io.vertx.core.impl.ContextImpl.emit(ContextImpl.java:274) ~[vertx-core-4.1.4.jar:4.1.4]
at io.vertx.core.impl.EventLoopContext.emit(EventLoopContext.java:22) ~[vertx-core-4.1.4.jar:4.1.4]
at io.vertx.core.net.impl.NetSocketImpl.handleMessage(NetSocketImpl.java:389) ~[vertx-core-4.1.4.jar:4.1.4]
at io.vertx.core.net.impl.ConnectionBase.read(ConnectionBase.java:155) ~[vertx-core-4.1.4.jar:4.1.4]
at io.vertx.core.net.impl.VertxHandler.channelRead(VertxHandler.java:154) ~[vertx-core-4.1.4.jar:4.1.4]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) ~[netty-transport-4.1.67.Final.jar:4.1.67.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) ~[netty-transport-4.1.67.Final.jar:4.1.67.Final]
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357) ~[netty-transport-4.1.67.Final.jar:4.1.67.Final]
at io.netty.channel.CombinedChannelDuplexHandler$DelegatingChannelHandlerContext.fireChannelRead(CombinedChannelDuplexHandler.java:436) ~[netty-transport-4.1.67.Final.jar:4.1.67.Final]
at io.vertx.pgclient.impl.codec.PgEncoder.lambda$write[=16=](PgEncoder.java:87) ~[vertx-pg-client-4.1.4.jar:4.1.4]
at io.vertx.pgclient.impl.codec.PgCommandCodec.handleReadyForQuery(PgCommandCodec.java:139) [vertx-pg-client-4.1.4.jar:4.1.4]
at io.vertx.pgclient.impl.codec.PgDecoder.decodeReadyForQuery(PgDecoder.java:237) [vertx-pg-client-4.1.4.jar:4.1.4]
at io.vertx.pgclient.impl.codec.PgDecoder.channelRead(PgDecoder.java:96) [vertx-pg-client-4.1.4.jar:4.1.4]
at io.netty.channel.CombinedChannelDuplexHandler.channelRead(CombinedChannelDuplexHandler.java:251) [netty-transport-4.1.67.Final.jar:4.1.67.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) [netty-transport-4.1.67.Final.jar:4.1.67.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) [netty-transport-4.1.67.Final.jar:4.1.67.Final]
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357) [netty-transport-4.1.67.Final.jar:4.1.67.Final]
at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410) [netty-transport-4.1.67.Final.jar:4.1.67.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) [netty-transport-4.1.67.Final.jar:4.1.67.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) [netty-transport-4.1.67.Final.jar:4.1.67.Final]
at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919) [netty-transport-4.1.67.Final.jar:4.1.67.Final]
at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:166) [netty-transport-4.1.67.Final.jar:4.1.67.Final]
at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:719) [netty-transport-4.1.67.Final.jar:4.1.67.Final]
at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:655) [netty-transport-4.1.67.Final.jar:4.1.67.Final]
at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:581) [netty-transport-4.1.67.Final.jar:4.1.67.Final]
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:493) [netty-transport-4.1.67.Final.jar:4.1.67.Final]
at io.netty.util.concurrent.SingleThreadEventExecutor.run(SingleThreadEventExecutor.java:986) [netty-common-4.1.67.Final.jar:4.1.67.Final]
at io.netty.util.internal.ThreadExecutorMap.run(ThreadExecutorMap.java:74) [netty-common-4.1.67.Final.jar:4.1.67.Final]
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) [netty-common-4.1.67.Final.jar:4.1.67.Final]
at java.lang.Thread.run(Thread.java:831) [?:?]
我找到了这个迁移指南,其中介绍了一些关于 jackson 的内容:https://vert-x3.github.io/vertx-4-migration-guide/index.html 但它没有帮助。
我也在 github 上发现了这个问题:https://github.com/vert-x3/vertx-web/issues/1841 虽然我不确定它是否适用于我。
序列化一个日期应该是一个常见的任务,所以我猜错在我身上。有人知道我该如何解决这个问题吗?
Vertx 首先 class 支持 JSON 你不需要为此导入任何额外的东西,其次你为什么需要日期?只需使用 instant,因为它受支持。
在幕后 Vertx
在 encode()
和 encodePrettily()
方法中使用 Jackson's ObjectMapper
。您需要做的是用这些 ObjectMappers.
注册 JavaTimeModule
将这些代码片段添加到您的应用程序的主要方法中。
ObjectMapper mapper = DatabindCodec.mapper();
mapper.registerModule(new JavaTimeModule());
ObjectMapper prettyMapper = DatabindCodec.prettyMapper();
prettyMapper.registerModule(new JavaTimeModule());
这是 DatabindCodec
class 的完整包:io.vertx.core.json.jackson.DatabindCodec
更新
public class MainVerticle extends AbstractVerticle {
// code already exists
@Override
public void start() {
ObjectMapper mapper = DatabindCodec.mapper();
mapper.registerModule(new JavaTimeModule());
ObjectMapper prettyMapper = DatabindCodec.prettyMapper();
prettyMapper.registerModule(new JavaTimeModule());
// code already exists
如果你可以得到 sql 日期作为 java.util.Date
,那么你可以将其转换为 unix 纪元时间(Unix 时间戳是自 1970 年 1 月 1 日以来经过的秒数),并将其作为长值传递给 eventBus。
当您在另一端收到 long 时,您可以轻松地将其转换为日期。
// Converting Date to timestamp and sending in Json
timestamp = Date().getTime()
new JsonObject().put("date", timestamp)
// Converting the timestamp to Date
Date(timestamp)
如果数据库日期只能作为 LocalDate 获取,您还可以将 LocalDate 转换为可以获取 unix 时间戳的形式,比如 Instant/Date.
主要思想是将日期转换为标准形式,传递给eventBus,从另一端获取并转换回Date。
我正在尝试通过创建一个小型 ReST API 来学习 Vert.x。在我添加数据库后端之前,一切都很顺利。我选择了 Postgres 作为数据库。当 java.time LocalDate 被解析为 JSON 时,我的问题就出现了。据我了解,我需要杰克逊后端来解析它。我通过 Maven 依赖项将它添加到我的类路径中。存在依赖性,但框架会抛出一个异常,因为它找不到名为 jackson-datatype-jsr310 的 jackson 插件。好吧,它就在那里,所以我有点卡住了...
我正在使用 Vert.x 4 和 java 16,我在 Windows 上开发10 个使用 IntelliJ IDEA。
openjdk 16.0.1 2021-04-20
OpenJDK Runtime Environment AdoptOpenJDK-16.0.1+9 (build 16.0.1+9)
OpenJDK 64-Bit Server VM AdoptOpenJDK-16.0.1+9 (build 16.0.1+9, mixed mode, sharing)
我的pom
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>myapi</artifactId>
<version>1.0.0-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven-compiler-plugin.version>3.8.1</maven-compiler-plugin.version>
<maven-shade-plugin.version>3.2.4</maven-shade-plugin.version>
<maven-surefire-plugin.version>2.22.2</maven-surefire-plugin.version>
<exec-maven-plugin.version>3.0.0</exec-maven-plugin.version>
<vertx.version>4.1.4</vertx.version>
<junit-jupiter.version>5.8.0</junit-jupiter.version>
<log4j.version>2.14.1</log4j.version>
<jackson.version>2.13.0-rc2</jackson.version>
<main.verticle>dev.schaw.myapi.MainVerticle</main.verticle>
<launcher.class>io.vertx.core.Launcher</launcher.class>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-stack-depchain</artifactId>
<version>${vertx.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-web</artifactId>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-junit5</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>${junit-jupiter.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>${junit-jupiter.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-config</artifactId>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-pg-client</artifactId>
<version>${vertx.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven-compiler-plugin.version}</version>
<configuration>
<release>11</release>
</configuration>
</plugin>
<plugin>
<artifactId>maven-shade-plugin</artifactId>
<version>${maven-shade-plugin.version}</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<manifestEntries>
<Main-Class>${launcher.class}</Main-Class>
<Main-Verticle>${main.verticle}</Main-Verticle>
</manifestEntries>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
</transformers>
<outputFile>${project.build.directory}/${project.artifactId}-${project.version}-fat.jar
</outputFile>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>${maven-surefire-plugin.version}</version>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>${exec-maven-plugin.version}</version>
<configuration>
<mainClass>io.vertx.core.Launcher</mainClass>
<arguments>
<argument>run</argument>
<argument>${main.verticle}</argument>
</arguments>
</configuration>
</plugin>
</plugins>
</build>
</project>
我的垂直
package dev.schaw.myapi;
import io.vertx.config.ConfigRetriever;
import io.vertx.config.ConfigRetrieverOptions;
import io.vertx.config.ConfigStoreOptions;
import io.vertx.core.AbstractVerticle;
import io.vertx.core.AsyncResult;
import io.vertx.core.http.HttpMethod;
import io.vertx.core.http.HttpServer;
import io.vertx.core.http.HttpServerResponse;
import io.vertx.core.json.JsonObject;
import io.vertx.ext.web.Router;
import io.vertx.pgclient.PgConnectOptions;
import io.vertx.pgclient.PgPool;
import io.vertx.sqlclient.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class MainVerticle extends AbstractVerticle {
private HttpServer server;
private Router router;
private Logger logger;
private SqlClient sqlClient;
@Override
public void start() {
server = vertx.createHttpServer();
router = Router.router(vertx);
logger = LoggerFactory.getLogger(MainVerticle.class);
ConfigRetriever retriever = ConfigRetriever.create(vertx, new ConfigRetrieverOptions()
.addStore(new ConfigStoreOptions()
.setType("file")
.setConfig(new JsonObject().put("path", "config.json"))));
retriever.getConfig(this::onConfigRetrieved);
}
public void onConfigRetrieved(AsyncResult<JsonObject> configAsyncResult){
JsonObject config = configAsyncResult.result();
JsonObject dataConnection = config.getJsonObject("myapi").getJsonObject("dataConnection");
PgConnectOptions connectOptions = new PgConnectOptions()
.setHost(dataConnection.getString("host"))
.setPort(dataConnection.getInteger("port"))
.setDatabase(dataConnection.getString("database"))
.setUser(dataConnection.getString("user"))
.setPassword(dataConnection.getString("password"));
PoolOptions poolOptions = new PoolOptions().setMaxSize(5);
sqlClient = PgPool.pool(vertx, connectOptions, poolOptions);
router.route(HttpMethod.GET, "/").handler(ctx -> {
logger.info("received a request");
HttpServerResponse response = ctx.response();
response.putHeader("content-type", "text/plain");
response.end("Hello World!\n");
});
router.get("/data").handler(ctx -> {
sqlClient.preparedQuery("SELECT * FROM sample_data WHERE id=")
.execute(Tuple.of(1), queryAsyncResult -> {
RowSet<Row> set = queryAsyncResult.result();
if(set.rowCount() != 1){
ctx.fail(404);
}
Row r = set.iterator().next();
JsonObject body = new JsonObject().put("id", r.getInteger("id"))
.put("name", r.getString("name"))
.put("date", r.getLocalDate("date"));
ctx.response().putHeader("content-type", "application/json").end(body.encode());
});
});
int port = config
.getJsonObject("myapi")
.getJsonObject("server")
.getInteger("port");
server.requestHandler(router).listen(port);
}
}
数据库初始化脚本
create table sample_data (
id serial primary key,
name varchar(80) not null,
date date not null
);
这里是个例外
您可以在此处检查类路径。
"C:\Program Files\AdoptOpenJDK\jdk-16.0.1.9-hotspot\bin\java.exe" -agentlib:jdwp=transport=dt_socket,address=127.0.0.1:53414,suspend=y,server=n -javaagent:C:\Users\willi\AppData\Local\JetBrains\Toolbox\apps\IDEA-U\ch-02.5284.40\plugins\java\lib\rt\debugger-agent.jar -Dfile.encoding=UTF-8 -classpath C:\Users\willi\Projects\myapi\target\classes;C:\Users\willi\.m2\repository\com\fasterxml\jackson\core\jackson-core.13.0-rc2\jackson-core-2.13.0-rc2.jar;C:\Users\willi\.m2\repository\com\fasterxml\jackson\core\jackson-databind.13.0-rc2\jackson-databind-2.13.0-rc2.jar;C:\Users\willi\.m2\repository\com\fasterxml\jackson\core\jackson-annotations.13.0-rc2\jackson-annotations-2.13.0-rc2.jar;C:\Users\willi\.m2\repository\com\fasterxml\jackson\datatype\jackson-datatype-jsr310.13.0-rc2\jackson-datatype-jsr310-2.13.0-rc2.jar;C:\Users\willi\.m2\repository\com\fasterxml\jackson\datatype\jackson-datatype-jdk8.13.0-rc2\jackson-datatype-jdk8-2.13.0-rc2.jar;C:\Users\willi\.m2\repository\io\vertx\vertx-web.1.4\vertx-web-4.1.4.jar;C:\Users\willi\.m2\repository\io\vertx\vertx-web-common.1.4\vertx-web-common-4.1.4.jar;C:\Users\willi\.m2\repository\io\vertx\vertx-auth-common.1.4\vertx-auth-common-4.1.4.jar;C:\Users\willi\.m2\repository\io\vertx\vertx-bridge-common.1.4\vertx-bridge-common-4.1.4.jar;C:\Users\willi\.m2\repository\io\vertx\vertx-core.1.4\vertx-core-4.1.4.jar;C:\Users\willi\.m2\repository\io\netty\netty-common.1.67.Final\netty-common-4.1.67.Final.jar;C:\Users\willi\.m2\repository\io\netty\netty-buffer.1.67.Final\netty-buffer-4.1.67.Final.jar;C:\Users\willi\.m2\repository\io\netty\netty-transport.1.67.Final\netty-transport-4.1.67.Final.jar;C:\Users\willi\.m2\repository\io\netty\netty-handler.1.67.Final\netty-handler-4.1.67.Final.jar;C:\Users\willi\.m2\repository\io\netty\netty-codec.1.67.Final\netty-codec-4.1.67.Final.jar;C:\Users\willi\.m2\repository\io\netty\netty-handler-proxy.1.67.Final\netty-handler-proxy-4.1.67.Final.jar;C:\Users\willi\.m2\repository\io\netty\netty-codec-socks.1.67.Final\netty-codec-socks-4.1.67.Final.jar;C:\Users\willi\.m2\repository\io\netty\netty-codec-http.1.67.Final\netty-codec-http-4.1.67.Final.jar;C:\Users\willi\.m2\repository\io\netty\netty-codec-http2.1.67.Final\netty-codec-http2-4.1.67.Final.jar;C:\Users\willi\.m2\repository\io\netty\netty-resolver.1.67.Final\netty-resolver-4.1.67.Final.jar;C:\Users\willi\.m2\repository\io\netty\netty-resolver-dns.1.67.Final\netty-resolver-dns-4.1.67.Final.jar;C:\Users\willi\.m2\repository\io\netty\netty-codec-dns.1.67.Final\netty-codec-dns-4.1.67.Final.jar;C:\Users\willi\.m2\repository\io\vertx\vertx-config.1.4\vertx-config-4.1.4.jar;C:\Users\willi\.m2\repository\org\apache\logging\log4j\log4j-api.14.1\log4j-api-2.14.1.jar;C:\Users\willi\.m2\repository\org\apache\logging\log4j\log4j-core.14.1\log4j-core-2.14.1.jar;C:\Users\willi\.m2\repository\org\apache\logging\log4j\log4j-slf4j-impl.14.1\log4j-slf4j-impl-2.14.1.jar;C:\Users\willi\.m2\repository\org\slf4j\slf4j-api.7.25\slf4j-api-1.7.25.jar;C:\Users\willi\.m2\repository\io\vertx\vertx-pg-client.1.4\vertx-pg-client-4.1.4.jar;C:\Users\willi\.m2\repository\io\vertx\vertx-sql-client.1.4\vertx-sql-client-4.1.4.jar;C:\Users\willi\AppData\Local\JetBrains\Toolbox\apps\IDEA-U\ch-02.5284.40\lib\idea_rt.jar io.vertx.core.Launcher run dev.schaw.myapi.MainVerticle
Connected to the target VM, address: '127.0.0.1:53414', transport: 'socket'
OpenJDK 64-Bit Server VM warning: Sharing is only supported for boot loader classes because bootstrap classpath has been appended
16:06:01.100 [vert.x-eventloop-thread-0] INFO io.vertx.core.impl.launcher.commands.VertxIsolatedDeployer - Succeeded in deploying verticle
16:06:03.393 [vert.x-eventloop-thread-1] ERROR io.vertx.core.impl.ContextImpl - Unhandled exception
io.vertx.core.json.EncodeException: Failed to encode as JSON: Java 8 date/time type `java.time.LocalDate` not supported by default: add Module "com.fasterxml.jackson.datatype:jackson-datatype-jsr310" to enable handling (through reference chain: java.util.LinkedHashMap["date"])
at io.vertx.core.json.jackson.DatabindCodec.toString(DatabindCodec.java:163) ~[vertx-core-4.1.4.jar:4.1.4]
at io.vertx.core.json.JsonObject.encode(JsonObject.java:728) ~[vertx-core-4.1.4.jar:4.1.4]
at dev.schaw.myapi.MainVerticle.lambda$onConfigRetrieved(MainVerticle.java:73) ~[classes/:?]
at io.vertx.core.impl.future.FutureImpl.onSuccess(FutureImpl.java:141) ~[vertx-core-4.1.4.jar:4.1.4]
at io.vertx.core.impl.future.FutureBase.emitSuccess(FutureBase.java:60) ~[vertx-core-4.1.4.jar:4.1.4]
at io.vertx.core.impl.future.FutureImpl.tryComplete(FutureImpl.java:211) ~[vertx-core-4.1.4.jar:4.1.4]
at io.vertx.core.impl.future.PromiseImpl.tryComplete(PromiseImpl.java:23) ~[vertx-core-4.1.4.jar:4.1.4]
at io.vertx.sqlclient.impl.QueryResultBuilder.tryComplete(QueryResultBuilder.java:102) ~[vertx-sql-client-4.1.4.jar:4.1.4]
at io.vertx.sqlclient.impl.QueryResultBuilder.tryComplete(QueryResultBuilder.java:35) ~[vertx-sql-client-4.1.4.jar:4.1.4]
at io.vertx.core.Promise.complete(Promise.java:66) ~[vertx-core-4.1.4.jar:4.1.4]
at io.vertx.core.Promise.handle(Promise.java:51) ~[vertx-core-4.1.4.jar:4.1.4]
at io.vertx.core.Promise.handle(Promise.java:29) ~[vertx-core-4.1.4.jar:4.1.4]
at io.vertx.core.impl.future.FutureImpl.onSuccess(FutureImpl.java:141) ~[vertx-core-4.1.4.jar:4.1.4]
at io.vertx.core.impl.future.FutureBase.emitSuccess(FutureBase.java:60) ~[vertx-core-4.1.4.jar:4.1.4]
at io.vertx.core.impl.future.FutureImpl.tryComplete(FutureImpl.java:211) ~[vertx-core-4.1.4.jar:4.1.4]
at io.vertx.core.impl.future.PromiseImpl.tryComplete(PromiseImpl.java:23) ~[vertx-core-4.1.4.jar:4.1.4]
at io.vertx.core.impl.future.PromiseImpl.onSuccess(PromiseImpl.java:49) ~[vertx-core-4.1.4.jar:4.1.4]
at io.vertx.core.impl.future.FutureImpl$ListenerArray.onSuccess(FutureImpl.java:262) ~[vertx-core-4.1.4.jar:4.1.4]
at io.vertx.core.impl.future.FutureBase.lambda$emitSuccess[=16=](FutureBase.java:54) ~[vertx-core-4.1.4.jar:4.1.4]
at io.vertx.core.impl.EventLoopContext.execute(EventLoopContext.java:81) ~[vertx-core-4.1.4.jar:4.1.4]
at io.vertx.core.impl.DuplicatedContext.execute(DuplicatedContext.java:173) ~[vertx-core-4.1.4.jar:4.1.4]
at io.vertx.core.impl.future.FutureBase.emitSuccess(FutureBase.java:51) ~[vertx-core-4.1.4.jar:4.1.4]
at io.vertx.core.impl.future.FutureImpl.tryComplete(FutureImpl.java:211) ~[vertx-core-4.1.4.jar:4.1.4]
at io.vertx.core.impl.future.PromiseImpl.tryComplete(PromiseImpl.java:23) ~[vertx-core-4.1.4.jar:4.1.4]
at io.vertx.core.impl.future.PromiseImpl.onSuccess(PromiseImpl.java:49) ~[vertx-core-4.1.4.jar:4.1.4]
at io.vertx.core.impl.future.PromiseImpl.handle(PromiseImpl.java:41) ~[vertx-core-4.1.4.jar:4.1.4]
at io.vertx.core.impl.future.PromiseImpl.handle(PromiseImpl.java:23) ~[vertx-core-4.1.4.jar:4.1.4]
at io.vertx.sqlclient.impl.command.CommandResponse.fire(CommandResponse.java:46) ~[vertx-sql-client-4.1.4.jar:4.1.4]
at io.vertx.sqlclient.impl.SocketConnectionBase.handleMessage(SocketConnectionBase.java:287) ~[vertx-sql-client-4.1.4.jar:4.1.4]
at io.vertx.pgclient.impl.PgSocketConnection.handleMessage(PgSocketConnection.java:96) ~[vertx-pg-client-4.1.4.jar:4.1.4]
at io.vertx.sqlclient.impl.SocketConnectionBase.lambda$init[=16=](SocketConnectionBase.java:99) ~[vertx-sql-client-4.1.4.jar:4.1.4]
at io.vertx.core.net.impl.NetSocketImpl.lambda$new(NetSocketImpl.java:97) ~[vertx-core-4.1.4.jar:4.1.4]
at io.vertx.core.streams.impl.InboundBuffer.handleEvent(InboundBuffer.java:240) ~[vertx-core-4.1.4.jar:4.1.4]
at io.vertx.core.streams.impl.InboundBuffer.write(InboundBuffer.java:130) ~[vertx-core-4.1.4.jar:4.1.4]
at io.vertx.core.net.impl.NetSocketImpl.lambda$handleMessage(NetSocketImpl.java:390) ~[vertx-core-4.1.4.jar:4.1.4]
at io.vertx.core.impl.EventLoopContext.emit(EventLoopContext.java:50) ~[vertx-core-4.1.4.jar:4.1.4]
at io.vertx.core.impl.ContextImpl.emit(ContextImpl.java:274) ~[vertx-core-4.1.4.jar:4.1.4]
at io.vertx.core.impl.EventLoopContext.emit(EventLoopContext.java:22) ~[vertx-core-4.1.4.jar:4.1.4]
at io.vertx.core.net.impl.NetSocketImpl.handleMessage(NetSocketImpl.java:389) ~[vertx-core-4.1.4.jar:4.1.4]
at io.vertx.core.net.impl.ConnectionBase.read(ConnectionBase.java:155) ~[vertx-core-4.1.4.jar:4.1.4]
at io.vertx.core.net.impl.VertxHandler.channelRead(VertxHandler.java:154) ~[vertx-core-4.1.4.jar:4.1.4]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) ~[netty-transport-4.1.67.Final.jar:4.1.67.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) ~[netty-transport-4.1.67.Final.jar:4.1.67.Final]
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357) ~[netty-transport-4.1.67.Final.jar:4.1.67.Final]
at io.netty.channel.CombinedChannelDuplexHandler$DelegatingChannelHandlerContext.fireChannelRead(CombinedChannelDuplexHandler.java:436) ~[netty-transport-4.1.67.Final.jar:4.1.67.Final]
at io.vertx.pgclient.impl.codec.PgEncoder.lambda$write[=16=](PgEncoder.java:87) ~[vertx-pg-client-4.1.4.jar:4.1.4]
at io.vertx.pgclient.impl.codec.PgCommandCodec.handleReadyForQuery(PgCommandCodec.java:139) [vertx-pg-client-4.1.4.jar:4.1.4]
at io.vertx.pgclient.impl.codec.PgDecoder.decodeReadyForQuery(PgDecoder.java:237) [vertx-pg-client-4.1.4.jar:4.1.4]
at io.vertx.pgclient.impl.codec.PgDecoder.channelRead(PgDecoder.java:96) [vertx-pg-client-4.1.4.jar:4.1.4]
at io.netty.channel.CombinedChannelDuplexHandler.channelRead(CombinedChannelDuplexHandler.java:251) [netty-transport-4.1.67.Final.jar:4.1.67.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) [netty-transport-4.1.67.Final.jar:4.1.67.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) [netty-transport-4.1.67.Final.jar:4.1.67.Final]
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357) [netty-transport-4.1.67.Final.jar:4.1.67.Final]
at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410) [netty-transport-4.1.67.Final.jar:4.1.67.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) [netty-transport-4.1.67.Final.jar:4.1.67.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) [netty-transport-4.1.67.Final.jar:4.1.67.Final]
at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919) [netty-transport-4.1.67.Final.jar:4.1.67.Final]
at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:166) [netty-transport-4.1.67.Final.jar:4.1.67.Final]
at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:719) [netty-transport-4.1.67.Final.jar:4.1.67.Final]
at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:655) [netty-transport-4.1.67.Final.jar:4.1.67.Final]
at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:581) [netty-transport-4.1.67.Final.jar:4.1.67.Final]
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:493) [netty-transport-4.1.67.Final.jar:4.1.67.Final]
at io.netty.util.concurrent.SingleThreadEventExecutor.run(SingleThreadEventExecutor.java:986) [netty-common-4.1.67.Final.jar:4.1.67.Final]
at io.netty.util.internal.ThreadExecutorMap.run(ThreadExecutorMap.java:74) [netty-common-4.1.67.Final.jar:4.1.67.Final]
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) [netty-common-4.1.67.Final.jar:4.1.67.Final]
at java.lang.Thread.run(Thread.java:831) [?:?]
我找到了这个迁移指南,其中介绍了一些关于 jackson 的内容:https://vert-x3.github.io/vertx-4-migration-guide/index.html 但它没有帮助。
我也在 github 上发现了这个问题:https://github.com/vert-x3/vertx-web/issues/1841 虽然我不确定它是否适用于我。
序列化一个日期应该是一个常见的任务,所以我猜错在我身上。有人知道我该如何解决这个问题吗?
Vertx 首先 class 支持 JSON 你不需要为此导入任何额外的东西,其次你为什么需要日期?只需使用 instant,因为它受支持。
在幕后 Vertx
在 encode()
和 encodePrettily()
方法中使用 Jackson's ObjectMapper
。您需要做的是用这些 ObjectMappers.
JavaTimeModule
将这些代码片段添加到您的应用程序的主要方法中。
ObjectMapper mapper = DatabindCodec.mapper();
mapper.registerModule(new JavaTimeModule());
ObjectMapper prettyMapper = DatabindCodec.prettyMapper();
prettyMapper.registerModule(new JavaTimeModule());
这是 DatabindCodec
class 的完整包:io.vertx.core.json.jackson.DatabindCodec
更新
public class MainVerticle extends AbstractVerticle {
// code already exists
@Override
public void start() {
ObjectMapper mapper = DatabindCodec.mapper();
mapper.registerModule(new JavaTimeModule());
ObjectMapper prettyMapper = DatabindCodec.prettyMapper();
prettyMapper.registerModule(new JavaTimeModule());
// code already exists
如果你可以得到 sql 日期作为 java.util.Date
,那么你可以将其转换为 unix 纪元时间(Unix 时间戳是自 1970 年 1 月 1 日以来经过的秒数),并将其作为长值传递给 eventBus。
当您在另一端收到 long 时,您可以轻松地将其转换为日期。
// Converting Date to timestamp and sending in Json
timestamp = Date().getTime()
new JsonObject().put("date", timestamp)
// Converting the timestamp to Date
Date(timestamp)
如果数据库日期只能作为 LocalDate 获取,您还可以将 LocalDate 转换为可以获取 unix 时间戳的形式,比如 Instant/Date.
主要思想是将日期转换为标准形式,传递给eventBus,从另一端获取并转换回Date。