当前位置:网站首页>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 方法有两个实现:
DatabindCodecJacksonCodec
目前运行的进程默认使用了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
边栏推荐
猜你喜欢
随机推荐
双链表(普通迭代器和常性迭代器)
shader入门精要2
shader 和 ray marching
CDH (computational Diffie-Hellman) problem and its differences with discrete logarithm and DDH problems
MySQL协议长什么样子
泰伯效应.
我的2021回忆录
OpenPose 运行指令 ([email protected])
Oauth2.0 认证服务器添加验证码登陆方式
tpproxy-tcp透明代理
LITESTAR 4D应用:室内植物照明模拟
Evaluate multipath BBR congestion control on ns3
TCP的三次握手和四次挥手
LeetCode 2344. 使数组可以被整除的最少删除次数 最大公约数
5款最好用的免费3D建模软件(附下载链接)
【进程间通信】信号量的使用/共享内存
第二十七章:时间复杂度与优化
Exotic curiosity-a solution looking - bit operations
EastWave:垂直腔表面激光器
光导布局设计工具









