BUG描述

在使用SpringBoot自带的jackson处理客户端提交的消息体反序列化时,遇到一个非常棘手的情况

客户端发送如下json

{"content":"6545566","type":"1","to":"xxx"}

Java对应实体类

abstract class BaseMessage implements Message{

    @JsonIgnore
protected String from;
@JsonIgnore
protected String address;
@JsonIgnore
protected Date sendTime; protected MessageType type; /**
* 客户端信息的处理方法
* @return netty socket回复对象
*/
@Override
public abstract BaseResult handle();
}

MessageType枚举类

/**
* @author Evan
*/
public enum MessageType {
/**
*
*/
TEXT(1),
/**
*
*/
IMAGE(2); private int index; MessageType(int index) {
this.index = index;
} public int getValue() {
return index;
}
}

在反序列化的时候出现以下错误

com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "type"



报错信息说明的很清楚,枚举属性type在反序列化的时候无法识别.其实也可以理解,枚举本身就是一个很特殊的数据类型Jackson无法正常的序列化也正常

解决思路

其实这个问题一开始真是难到我了,按之前的项目经验来说,在处理前端数据对应的实体类的属性一般是不会使用枚举类型的一般这种类似的属性我们都要求客户端以整数值提交后台,后台实体类也按integer类型保存.此类问题真的少见

面向Google编程,得到最靠谱最简单的方案是在枚举类使用@JsonCreator注解标识一个工厂方法创建正确的枚举值,但是不知道为什么在我这里毫无效果

查阅资料后了解到Jackson是允许为单独属性定义转换器的

实现如下代码

/**
* @author Evan
*/
public class MessageTypeConverter implements Converter<String, MessageType> { @Override
public MessageType convert(String value) {
return MessageType.valueOf(Integer.parseInt(value));
} /**
* 输入值类型
* @param typeFactory
* @return
*/
@Override
public JavaType getInputType(TypeFactory typeFactory) {
return typeFactory.constructType(String.class);
} /**
* 转换器输出值类型
* @param typeFactory
* @return
*/
@Override
public JavaType getOutputType(TypeFactory typeFactory) {
return typeFactory.constructType(MessageType.class);
}
}

其中关键就在于convert方法,我们要求前台提交一个String类型的数值给我们,我们在根据这个数值给转换器该属性准确的值

枚举类MessageTpe添加valueOf方法

 public static MessageType valueOf(int value) {
switch (value) {
case 1:
return TEXT; case 2:
return IMAGE;
default:
return null;
}
}

实体类BaseMessagetype属性添加注解指定反序列转换器

/**
* @author Evan
*/
abstract class BaseMessage implements Message{ @JsonIgnore
protected String from;
@JsonIgnore
protected String address;
@JsonIgnore
protected Date sendTime;
@JsonDeserialize(converter = MessageTypeConverter.class)
protected MessageType type; /**
* 客户端信息的处理方法
* @return netty socket回复对象
*/
@Override
public abstract BaseResult handle();
}

那么就可以从一个数值得到正确的对应的枚举类型了

emmmmmmmmmmm.........问题是解决了.....

好像哪里不对劲

他喵的要switch我还定义啥枚举啊

修改枚举类MessageTypevalueOf方法

    public static MessageType valueOf(int value) {
for (MessageType type : MessageType.values()){
if (type.getValue() == value){
return type;
}
}
return null;
}

舒服了.....

如果大家头更好的方法欢迎评论区讨论交流~

Jackson反序列化枚举类型解决方案的更多相关文章

  1. 由@Convert注解引出的jackson对枚举的反序列化规则

    对于一些状态字段以前时兴用常量,现在时兴用枚举,虽然阅读体验极佳,但是传值的时候还是会有些麻烦,需要设置一下转换器.比如: class A{ @Convert(converter=TestTypeCo ...

  2. 自定义fastjson对枚举类型的序列化及反序列化过程

    通常,fastjson在序列化及反序列化枚举时,一般以下几种策略: 1).根据枚举的name值序列化及反序列化(默认) 2).根据枚举的ordinal序列化及反序列化 3).根据枚举的toString ...

  3. spring-boot rest controller 使用枚举作为参数,重写反序列化实现任意值转枚举类型

    目录 BaseEnum MyEnum StringToEnumConverterFactory FormatterConfig DTO RestController 参考 BaseEnum packa ...

  4. jackson 转换 enum 类型

    REST API 接口要求 requster json 的 lifeCycle 域只能填 YOUNG, OLD,对于其他的 lifeCycle,都要给 requester 返回 bad request ...

  5. 【hibernate postgresql】注解@TypeDef/@Enumerated/数据库字段gender为枚举类型,从前台接受到实体后进行保存报错:org.postgresql.util.PSQLException: ERROR: column "gender" is of type gender but expression is of type character varying

    数据库字段gender为枚举类型,从前台接受到实体后进行保存报错:org.postgresql.util.PSQLException: ERROR: column "gender" ...

  6. Python 中的枚举类型~转

    Python 中的枚举类型 摘要: 枚举类型可以看作是一种标签或是一系列常量的集合,通常用于表示某些特定的有限集合,例如星期.月份.状态等. 枚举类型可以看作是一种标签或是一系列常量的集合,通常用于表 ...

  7. 【转】java枚举类型enum的使用

    原文网址:http://blog.csdn.net/wgw335363240/article/details/6359614 java 枚举类型enum 的使用 最近跟同事讨论问题的时候,突然同事提到 ...

  8. 枚举类型的单例模式(java)

    Inspired by Effective Java. Singleton模式是在编程实践中应用最广泛的几种设计模式之一.以前知道的,实现单例的方法有两种(下面的A.B).刚刚在读<Effect ...

  9. 第3条:用私有构造器或者枚举类型强化Singleton属性

    Singleton是指仅仅被实例化一次的类.通过被用来代表那些本质上唯一的系统组件,比如窗口管理器或者文件系统. 在http://www.cnblogs.com/13jhzeng/p/5256424. ...

随机推荐

  1. RSA加密算法和SSH远程连接服务器

    服务器端与客户端的密钥系统不一样,称为非对称式密钥系统 RSA算法的基础是模运算x mod n,事实上: [(a mod n) + (b mod n)] mod n = (a+b) mod n [(a ...

  2. SPSSAU数据分析思维培养系列2:方法选择篇

    大家好!在上篇文章中,我们一起学习了如何[掌握正确的数据处理思维].在完成数据准备和清理工作后,就要进入到正式分析阶段,而选择什么样的数据分析方法进行分析是关键. 想要进行科学和系统化的数据分析,分析 ...

  3. 区块链入门到实战(12)之区块链 – 默克尔树(Merkle Tree)

    目的:解决由于区块链过长,导致节点硬盘存不下的问题. 方法:只需保留交易的哈希值. 区块链作为分布式账本,原则上网络中的每个节点都应包含整个区块链中全部区块,随着区块链越来越长,节点的硬盘有可能放不下 ...

  4. CF1349A Orac and LCM 题解

    题意分析 给出$n$个数,求这$n$个数两两的最小公倍数的最大公约数 思路分析 通过分析样例可以发现,如果要成为这$n$个数两两的最小公倍数的公约数,至少要是这$n$个数中$n-1$个数的约数,否则就 ...

  5. 使用 Python破解大众点评字体加密(SVG反扒)

    前言 大众点评拥有大量高质量评论信息.种草信息,同时也有非常严格的反扒机制. 今天我们一起使用 Python破解大众点评字体加密,获取极具商业价值的信息. 本文知识点: requests 的使用 xp ...

  6. Node.js调试相关

    如何进行Nodejs性能分析? nodejs性能最重要的两个部分:CPU耗时查看和内存泄漏排查 一,CPU相关 主要思路是两个:借助第三方的工具,以及借助v8自带的性能分析工具 借助第三方的工具 主要 ...

  7. Android开发之开源框架OKHTTP的Get请求代码,得到json字符串方法

      <span style="white-space:pre"> </span><pre name="code" class=&q ...

  8. SplashImage

    关于Unity启动时间过长(启动黑屏时间长)的问题 https://blog.csdn.net/h5q8n2e7/article/details/50484458 Unity3D游戏开发之“重写Uni ...

  9. Avtiviti工作流规范 BPM与BPMN

    进过长时间的轮转,重拾Activiti,因为最近在智联上看到多家公司的需求上写的,都要熟悉工作流引擎,也就是activiti所以重拾 之前看的视屏是activiti5,我觉得版本有点低,所以打算看一下 ...

  10. basicInterpreter1.02 增加对for循环的支持

    源码下载:https://files.cnblogs.com/files/heyang78/basicInterpreter102-20200531-2.rar 输入: for x= to print ...