Jackson反序列化枚举类型解决方案
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;
}
}
实体类BaseMessage
的type
属性添加注解指定反序列转换器
/**
* @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
我还定义啥枚举啊
修改枚举类MessageType
的valueOf
方法
public static MessageType valueOf(int value) {
for (MessageType type : MessageType.values()){
if (type.getValue() == value){
return type;
}
}
return null;
}
舒服了.....
如果大家头更好的方法欢迎评论区讨论交流~
Jackson反序列化枚举类型解决方案的更多相关文章
- 由@Convert注解引出的jackson对枚举的反序列化规则
对于一些状态字段以前时兴用常量,现在时兴用枚举,虽然阅读体验极佳,但是传值的时候还是会有些麻烦,需要设置一下转换器.比如: class A{ @Convert(converter=TestTypeCo ...
- 自定义fastjson对枚举类型的序列化及反序列化过程
通常,fastjson在序列化及反序列化枚举时,一般以下几种策略: 1).根据枚举的name值序列化及反序列化(默认) 2).根据枚举的ordinal序列化及反序列化 3).根据枚举的toString ...
- spring-boot rest controller 使用枚举作为参数,重写反序列化实现任意值转枚举类型
目录 BaseEnum MyEnum StringToEnumConverterFactory FormatterConfig DTO RestController 参考 BaseEnum packa ...
- jackson 转换 enum 类型
REST API 接口要求 requster json 的 lifeCycle 域只能填 YOUNG, OLD,对于其他的 lifeCycle,都要给 requester 返回 bad request ...
- 【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" ...
- Python 中的枚举类型~转
Python 中的枚举类型 摘要: 枚举类型可以看作是一种标签或是一系列常量的集合,通常用于表示某些特定的有限集合,例如星期.月份.状态等. 枚举类型可以看作是一种标签或是一系列常量的集合,通常用于表 ...
- 【转】java枚举类型enum的使用
原文网址:http://blog.csdn.net/wgw335363240/article/details/6359614 java 枚举类型enum 的使用 最近跟同事讨论问题的时候,突然同事提到 ...
- 枚举类型的单例模式(java)
Inspired by Effective Java. Singleton模式是在编程实践中应用最广泛的几种设计模式之一.以前知道的,实现单例的方法有两种(下面的A.B).刚刚在读<Effect ...
- 第3条:用私有构造器或者枚举类型强化Singleton属性
Singleton是指仅仅被实例化一次的类.通过被用来代表那些本质上唯一的系统组件,比如窗口管理器或者文件系统. 在http://www.cnblogs.com/13jhzeng/p/5256424. ...
随机推荐
- JavaScript学习系列博客_38_JavaScript 事件
事件(Event) - 事件指的是用户和浏览器之间的交互行为.比如:点击按钮.关闭窗口.鼠标移动.... - 我们可以为事件来绑定回调函数来响应事件. - 绑定事件的方式: 1.可以在标签的事件属性中 ...
- 仿京东BOE官网图片链接
- latex:公式中的文字
公式环境中的说明文字应置于\mbox命令中.如果已经调用了数学工具宏包或者公式宏包,可改为选用一下3条功能更强的文本命令将简短文字插入公式中. \intertext{文本} 由amsmath宏包提供, ...
- MacOS上的效率设置--Windows转移过来的小白设置
1 Copy Path Mac上面的文件管理并不像Windows那么的直观,经常需要指定文件路径时,总是去右键-简介获取相当的费劲.Mac之所以称之为生产力工具,优势就在于此了.利用自动操作的功能就能 ...
- 使用Arcgis时,在sde空间库常用的相关函数
一.Oracle库中配置好sde空间库常见的场景 1.在sde库中创建表:community 创建表:community 字段:id(INTEGER), shape(ST_GEOMETRY) 2.往s ...
- c#值类型引用类型第一章
概要 本篇文章主要简单扼要的讲述值类型和引用类型更进阶的理解和使用.如果希望更多的了解和技术讨论请记得看文章末尾,望各位看官多多支持多多关注,关注和支持是我更新文章的最大动力.在这里谢谢大家.温馨提示 ...
- Codeforece E. Anton and Permutation
主席树算贡献l,r中交换位置,算出>=rank(h) 和 <=rank(h) a[l],a[r] 先不统计 a[l]比a[r]大的话交换后ans-1,a[l]比a[r]小的话交换后ans- ...
- 如何把一个一般的git库变成“裸库”?
语法: git clone --bare 「src」 「dest」 e.g. cd ~/Workspace/SourceRepo/ git clone --bare ./ ../Git/bareRep ...
- HDU - 1261-字串数 (排列组合+大数)
一个A和两个B一共可以组成三种字符串:"ABB","BAB","BBA". 给定若干字母和它们相应的个数,计算一共可以组成多少个不同的字符串 ...
- Vue文件模板
<template> <div> </div> </template> <script> export default { } </s ...