当前位置:网站首页>Vert.x web 接收请求时反序列化对象 Failed to decode 如何解决?
Vert.x web 接收请求时反序列化对象 Failed to decode 如何解决?
2022-08-02 14:14:00 【[email prote】
最近在尝试用 Vert.x 进行 web 开发,发现接口在接收请求体后,反序列化报错,跟进一下原因。
解决方案
引入 jackson-databind
我是用的是 Vert.x 4.3.1,所以引入 jackson-databind 2.13.2.* 版本:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.13.2.2</version>
</dependency>
排查过程
构造接口
编写一个 Post 接口,将请求体转换为一个对象 NewOrderRequest
(对象是个 DTO,只有一些基本的字段定义):
import io.vertx.core.Future;
import io.vertx.core.Vertx;
import io.vertx.core.json.JsonObject;
import io.vertx.ext.web.Router;
import io.vertx.ext.web.RoutingContext;
import io.vertx.ext.web.handler.BodyHandler;
import io.vertx.sqlclient.Pool;
public class OrderRestAPI {
private final OrderService orderService;
public OrderRestAPI(Vertx vertx, Router router, Pool pool, JsonObject orderConfig) {
orderService = new OrderService(vertx, pool, orderConfig);
router.post("/order").handler(BodyHandler.create().setBodyLimit(256)).respond(this::newOrder);
}
private Future<ResponseDTO<NewOrderResponse>> newOrder(RoutingContext ctx) {
NewOrderRequest newOrderRequest = ctx.body().asPojo(NewOrderRequest.class);
return orderService.newOrder(newOrderRequest).map(result -> new ResponseDTO<>("OK", result));
}
}
发现问题
但是在反序列化的时候报错 Failed to decode
:
22:25:50.048 [vert.x-eventloop-thread-1] ERROR io.vertx.ext.web.RoutingContext - Unhandled exception in router
io.vertx.core.json.DecodeException: Failed to decode
at io.vertx.core.json.jackson.JacksonCodec.cast(JacksonCodec.java:350) ~[vertx-core-4.3.1.jar:4.3.1]
at io.vertx.core.json.jackson.JacksonCodec.fromParser(JacksonCodec.java:187) ~[vertx-core-4.3.1.jar:4.3.1]
at io.vertx.core.json.jackson.JacksonCodec.fromBuffer(JacksonCodec.java:74) ~[vertx-core-4.3.1.jar:4.3.1]
at io.vertx.core.json.Json.decodeValue(Json.java:119) ~[vertx-core-4.3.1.jar:4.3.1]
at io.vertx.ext.web.impl.RequestBodyImpl.asPojo(RequestBodyImpl.java:126) ~[vertx-web-4.3.1.jar:4.3.1]
at io.vertx.ext.web.RequestBody.asPojo(RequestBody.java:115) ~[vertx-web-4.3.1.jar:4.3.1]
at icu.wwj.web.handler.OrderRestAPI.newOrder(OrderRestAPI.java:25) ~[classes/:?]
跟进代码
查看 Vert.x JacksonCodec 发现,请求体被正常反序列化为了 LinkedHashMap,但是代码中判断,如果反序列化的目标不是 Map 或着 Map 的派生,就抛出 Failed to decode
的错误:
看到上面的代码首先感到的是奇怪:
- 为什么非常简单的对象反序列化也无法进行?
- 是不是我是用
asPojo
的方式不对?
往上层看了下,Vert.x 不出所料地使用了流行的 Jackson,但是 JsonCodec
方法有两个实现:
DatabindCodec
JacksonCodec
目前运行的进程默认使用了JacksonCodec
,是不是可以切换到DatabindCodec
试试?
如何切换 Databind 实现?
Vert.x 通过 JacksonFactory
创建 JsonCodec
的实现,先尝试创建 DatabindCodec
,如果抛出异常(也就是缺少 databind 相关的类)则创建 JacksonCodec
:
public class JacksonFactory implements io.vertx.core.spi.JsonFactory {
public static final JacksonFactory INSTANCE = new JacksonFactory();
public static final JacksonCodec CODEC;
static {
JacksonCodec codec;
try {
codec = new DatabindCodec();
} catch (Throwable ignore) {
// No databind
codec = new JacksonCodec();
}
CODEC = codec;
}
@Override
public JsonCodec codec() {
return CODEC;
}
}
vertx-core
在引入 jackson-databind
的时候声明了 optional
:
<!-- Jackson -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<optional>true</optional>
</dependency>
由此可以理解:Vert.x Core 引入了 jackson-core
以提供基本的 Json 编解码能力,但对于 Json 与对象映射这类更高级的操作,需要借助 jackson-databind
实现。
那只需要引入 jackson-databind
就能解决问题了。
版权声明
本文为[[email protected]]所创,转载请带上原文链接,感谢
https://blog.csdn.net/wu_weijie/article/details/125510504
边栏推荐
猜你喜欢
随机推荐
指针/【类型】对指针加一能力的影响(&*ip ,*&ipd)
光导布局设计工具
OpenPose 基本理念
mininet hosts talk to real internet
Google AdSense注册流程
企业的电子签名、私钥签名
Doubly linked list (normal iterators and const iterators)
Run ns3 with multiple processes
How does ns3 solve cross reference issue
Qt | 显示网络图片 QNetworkAccessManager
C#高级教程
Unity-Post Processing
【线程】线程创建 | 理解线程并发 (1)
开源一个golang写的游戏服务器框架
第二十九章:树的基本概念和性质
锥形相位掩模的Talbot图像
EastWave应用:光场与石墨烯和特异介质相互作用的研究
audio console无法连接到RPC服务
Project: combing the database table
面试汇总