放弃fastjson,拥抱Jackson
- json object操作
- 序列化操作
- 反序列化
- 日期类型反序列化
- 自定义反序列化
- 枚举类型反序列化
背景
最近由于阿里的fastjson频繁爆出安全漏洞,为了避免后续升级上线的烦恼,决定弃用fastjson,使用Jackson,把现有项目中的fastjson都换成了Jackson,由于很多写法上有些不同,所以在这里把这些改过的东西做一下笔记。
常用操作
首先引入相关的pom
<properties>
<jackson.version>2.11.0</jackson.version>
</properties>
<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>
</dependencies>
json object操作
当我们需要一个json对象和json数组的时候,我们可以使用下面的方法来构造ObjectNode和ArrayNode,类似fastjson中的JSONObject和JSONArray。
@Test
public void testJsonObject(){
ObjectMapper mapper = new ObjectMapper();
ObjectNode json = mapper.createObjectNode();
json.put("name", "Tom");
json.put("age", 1);
System.out.println(json);
ArrayNode jsonNodes = mapper.createArrayNode();
jsonNodes.add(json);
System.out.println(jsonNodes);
}
序列化操作
序列化操作就是将Java对象转化成json,简单的语法如下:
@Test
public void testSerialize() throws JsonProcessingException{
User user = new User();
user.setAge(1);
user.setName("zhangsan");
user.setGender(GENDER.MALE);
user.setBirthday(new Date());
ObjectMapper mapper = new ObjectMapper();
String s = mapper.writeValueAsString(user);
System.out.println(s);
}
普通的String和int类型没有什么疑问,我们这里涉及了两个特殊类型,一个是Date,还有一个是枚举。 日期类型我们是通过注解@JsonFormat对日期类型做了格式化,可以控制输出的日期格式。
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")
private Date birthday;
枚举类型,我们通过注解@JsonValue来控制输出哪个字段。
@JsonValue
public String getName(){
return name;
}
反序列化
反序列化就是将json转化成Java对象,语法如下:
@Test
public void testDeSerialize() throws JsonProcessingException{
String json = "{"name":"zhangsan","age":10}";
ObjectMapper mapper = new ObjectMapper();
User user = mapper.readValue(json, User.class);
System.out.println(user);
}
日期类型反序列化
对于Date类型,目前支持以下的格式:
- long类型的时间戳
- 通过@JsonFormat 注解指定类型格式:yyyy-MM-dd HH:mm:ss
@Test
public void testDeSerializeDate() throws JsonProcessingException{
String json = "{"name":"zhangsan","age":10,"birthday":1592800446397}";
ObjectMapper mapper = new ObjectMapper();
User user = mapper.readValue(json, User.class);
System.out.println(user);
String json1 = "{"name":"zhangsan","age":10,"birthday":"2020-01-01 12:13:14"}";
User user1 = mapper.readValue(json1, User.class);
System.out.println(user1);
}
自定义反序列化
有时候系统提供的反序列化方式不能满足我们的需求,我们可以自定义一些方法来满足我们个性化的需求,我们以一个日期为例,讲讲如何自定义反序列化。
首先我们在对应的字段上通过注解@JsonDeserialize来指定反序列化的类
@JsonDeserialize(using = CustomDeserializerDate.class)
private Date birthday_custom;
自定义的序列化类继承抽象类StdDeserializer,此外我们还要添加一个无参构造方法,否则会报错。 在deserialize方法里我们实现反序列化的逻辑.
public static class CustomDeserializerDate extends StdDeserializer<Date>{
private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
protected CustomDeserializerDate(Class<?> vc){
super(vc);
}
//需要一个无参构造方法,否则会报错
public CustomDeserializerDate(){
this(null);
}
@Override
public Date deserialize(
JsonParser p,
DeserializationContext ctxt) throws IOException{
String date = p.getText();
try {
return sdf.parse(date);
} catch (ParseException e){
e.printStackTrace();
}
return null;
}
}
枚举类型反序列化
最后我们讲一下枚举类型的反序列化
如下代码所示,我们通过注解@JsonCreator来处理枚举反序列化,该方法接收一个int类型的参数,也就是枚举的value值,返回枚举类型GENDER。如果没找到,则返回null.
public static enum GENDER{
MALE("男", 1), FEMALE("女", 0);
private String name;
private int value;
@JsonCreator
public static GENDER getGenderById(int value){
for (GENDER c: GENDER.values()){
if (c.getValue() == value){
return c;
}
}
return null;
}
..........
}
完整代码请参考:https://github.com/zhangjun0x01/bigdata-examples/blob/master/java/src/main/java/json/JacksonTest.java
- 树和二叉树的存储结构的实现(C/C++实现)
- Selenium3源码之异常模块篇
- 移位密码原理及算法实现
- 排序算法的实现(C/C++实现)
- [开源] 分享导出博客园文章成本地 Markdown 文件存储的工具
- 单表代替密码原理及算法实现
- 【Android开发学习笔记之一】5大布局方式详解
- Selenium3源码之common下action_chains.py模块分析
- 图的简单应用(C/C++实现)
- 一个很easy的脚本--php获取服务器端的相关信息
- Kubernetes网络解决方案的比较
- OSX 上初步尝试 asp.net 5
- 一个粗心的Bug,JSON格式不规范导致AJAX错误
- weiapi2.2 HelpPage自动生成接口说明文档和接口测试功能
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 前端踩坑系列《六》——让人又爱又恨的npm包
- docker运行Tomcat后访问首页报404(详细永久解决步骤)
- vue.js如何快速入门第1篇
- 3.列表-HTML基础
- 启动时间的一些分析
- 1.HTML基础知识-HTML进阶
- 浅析一个postgresql的死锁问题
- 你的第一个React App (二 ) - 应用组件开发
- 在Angular应用里使用Redux
- Elasticsearch 日志配置详解
- Cypress系列(52)- fixture() 命令详解
- Docker学习笔记---Dockerfile
- Java面试高频知识点汇总 JVM专题
- Java面试高频知识点汇总 网络协议专题
- 「Mysql优化大师一」mysql服务性能剖析工具