jackson学习之三:常用API操作
欢迎访问我的GitHub
https://github.com/zq2599/blog_demos
内容:所有原创文章分类汇总及配套源码,涉及Java、Docker、Kubernetes、DevOPS等;
系列文章汇总
- jackson学习之一:基本信息
- jackson学习之二:jackson-core
- jackson学习之三:常用API操作
- jackson学习之四:WRAP_ROOT_VALUE(root对象)
- jackson学习之五:JsonInclude注解
- jackson学习之六:常用类注解
- jackson学习之七:常用Field注解
- jackson学习之八:常用方法注解
- jackson学习之九:springboot整合(配置文件)
- jackson学习之十(终篇):springboot整合(配置类)
源码下载
- 如果您不想编码,可以在GitHub下载所有源码,地址和链接信息如下表所示(https://github.com/zq2599/blog_demos):
| 名称 | 链接 | 备注 |
|---|---|---|
| 项目主页 | https://github.com/zq2599/blog_demos | 该项目在GitHub上的主页 |
| git仓库地址(https) | https://github.com/zq2599/blog_demos.git | 该项目源码的仓库地址,https协议 |
| git仓库地址(ssh) | git@github.com:zq2599/blog_demos.git | 该项目源码的仓库地址,ssh协议 |
- 这个git项目中有多个文件夹,本章的应用在jacksondemo文件夹下,如下图红框所示:

本篇概览
本文是《jackson学习》系列的第三篇,前面咱们学习了jackson的低阶API,知道了底层原理,本篇开始学习平时最常用的基本功能,涉及内容如下:
- 体验最常用的操作,内容如下图所示:

- 介绍常用的可配置属性,以便按需要来设置;
- 接下来进入快速浏览的环节,咱们一起先把各个API过一遍;
单个对象序列化
先看常用的序列化API:
- 对象转字符串:
String jsonStr = mapper.writeValueAsString(twitterEntry);
- 对象转文件:
mapper.writeValue(new File("twitter.json"), twitterEntry);
- 对象转byte数组:
byte[] array = mapper.writeValueAsBytes(twitterEntry);
单个对象反序列化
- 字符串转对象:
TwitterEntry tFromStr = mapper.readValue(objectJsonStr, TwitterEntry.class);
- 文件转对象:
TwitterEntry tFromFile = mapper.readValue(new File("twitter.json"), TwitterEntry.class);
- byte数组转对象:
TwitterEntry tFromBytes = mapper.readValue(array, TwitterEntry.class);
- 字符串网络地址转对象:
String testJsonDataUrl = "https://raw.githubusercontent.com/zq2599/blog_demos/master/files/twitteer_message.json";
TwitterEntry tFromUrl = mapper.readValue(new URL(testJsonDataUrl), TwitterEntry.class);
集合序列化
- HashMap转字符串:
String mapJsonStr = mapper.writeValueAsString(map);
集合反序列化
- 字符串转HashMap:
Map<String, Object> mapFromStr = mapper.readValue(mapJsonStr, new TypeReference<Map<String, Object>>() {});
JsonNode
- 如果您不想使用XXX.class来做反序列化,也能使用JsonNode来操作:
JsonNode jsonNode = mapper.readTree(mapJsonStr);
String name = jsonNode.get("name").asText();
int age = jsonNode.get("age").asInt();
String city = jsonNode.get("addr").get("city").asText();
String street = jsonNode.get("addr").get("street").asText();
时间字段格式化
- 对于Date字段,默认的反序列化是时间戳,可以修改配置:
mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"));
dateMapStr = mapper.writeValueAsString(dateMap);
JSON数组的反序列化
假设jsonArrayStr是个json数组格式的字符串:
- JSON数组转对象数组:
TwitterEntry[] twitterEntryArray = mapper.readValue(jsonArrayStr, TwitterEntry[].class);
- JSON数组转对象集合(ArrayList):
List<TwitterEntry> twitterEntryList = mapper.readValue(jsonArrayStr, new TypeReference<List<TwitterEntry>>() {});
完整代码
- 上述所有常用API用法的完整代码如下:
package com.bolingcavalry.jacksondemo.databind;
import com.bolingcavalry.jacksondemo.beans.TwitterEntry;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.*;
public class SimpleDemo {
private static final Logger logger = LoggerFactory.getLogger(SimpleDemo.class);
public static void main(String[] args) throws Exception {
ObjectMapper mapper = new ObjectMapper();
logger.info("以下是序列化操作");
// 对象 -> 字符串
TwitterEntry twitterEntry = new TwitterEntry();
twitterEntry.setId(123456L);
twitterEntry.setFromUserId(101);
twitterEntry.setToUserId(102);
twitterEntry.setText("this is a message for serializer test");
twitterEntry.setLanguageCode("zh");
String jsonStr = mapper.writeValueAsString(twitterEntry);
logger.info("序列化的字符串:{}", jsonStr);
// 对象 -> 文件
mapper.writeValue(new File("twitter.json"), twitterEntry);
// 对象 -> byte数组
byte[] array = mapper.writeValueAsBytes(twitterEntry);
logger.info("\n\n以下是反序列化操作");
// 字符串 -> 对象
String objectJsonStr = "{\n" +
" \"id\":1125687077,\n" +
" \"text\":\"@stroughtonsmith You need to add a \\\"Favourites\\\" tab to TC/iPhone. Like what TwitterFon did. I can't WAIT for your Twitter App!! :) Any ETA?\",\n" +
" \"fromUserId\":855523, \n" +
" \"toUserId\":815309,\n" +
" \"languageCode\":\"en\"\n" +
"}";
TwitterEntry tFromStr = mapper.readValue(objectJsonStr, TwitterEntry.class);
logger.info("从字符串反序列化的对象:{}", tFromStr);
// 文件 -> 对象
TwitterEntry tFromFile = mapper.readValue(new File("twitter.json"), TwitterEntry.class);
logger.info("从文件反序列化的对象:{}", tFromStr);
// byte数组 -> 对象
TwitterEntry tFromBytes = mapper.readValue(array, TwitterEntry.class);
logger.info("从byte数组反序列化的对象:{}", tFromBytes);
// 字符串网络地址 -> 对象
String testJsonDataUrl = "https://raw.githubusercontent.com/zq2599/blog_demos/master/files/twitteer_message.json";
TwitterEntry tFromUrl = mapper.readValue(new URL(testJsonDataUrl), TwitterEntry.class);
logger.info("从网络地址反序列化的对象:{}", tFromUrl);
logger.info("\n\n以下是集合序列化操作");
Map<String, Object> map = new HashMap<>();
map.put("name", "tom");
map.put("age", 11);
Map<String, String> addr = new HashMap<>();
addr.put("city","深圳");
addr.put("street", "粤海");
map.put("addr", addr);
String mapJsonStr = mapper.writeValueAsString(map);
logger.info("HashMap序列化的字符串:{}", mapJsonStr);
logger.info("\n\n以下是集合反序列化操作");
Map<String, Object> mapFromStr = mapper.readValue(mapJsonStr, new TypeReference<Map<String, Object>>() {});
logger.info("从字符串反序列化的HashMap对象:{}", mapFromStr);
// JsonNode类型操作
JsonNode jsonNode = mapper.readTree(mapJsonStr);
String name = jsonNode.get("name").asText();
int age = jsonNode.get("age").asInt();
String city = jsonNode.get("addr").get("city").asText();
String street = jsonNode.get("addr").get("street").asText();
logger.info("用JsonNode对象和API反序列化得到的数:name[{}]、age[{}]、city[{}]、street[{}]", name, age, city, street);
// 时间类型格式
Map<String, Object> dateMap = new HashMap<>();
dateMap.put("today", new Date());
String dateMapStr = mapper.writeValueAsString(dateMap);
logger.info("默认的时间序列化:{}", dateMapStr);
// 设置时间格式
mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"));
dateMapStr = mapper.writeValueAsString(dateMap);
logger.info("自定义的时间序列化:{}", dateMapStr);
System.out.println(objectJsonStr);
// json数组
String jsonArrayStr = "[{\n" +
" \"id\":1,\n" +
" \"text\":\"text1\",\n" +
" \"fromUserId\":11, \n" +
" \"toUserId\":111,\n" +
" \"languageCode\":\"en\"\n" +
"},\n" +
"{\n" +
" \"id\":2,\n" +
" \"text\":\"text2\",\n" +
" \"fromUserId\":22, \n" +
" \"toUserId\":222,\n" +
" \"languageCode\":\"zh\"\n" +
"},\n" +
"{\n" +
" \"id\":3,\n" +
" \"text\":\"text3\",\n" +
" \"fromUserId\":33, \n" +
" \"toUserId\":333,\n" +
" \"languageCode\":\"en\"\n" +
"}]";
// json数组 -> 对象数组
TwitterEntry[] twitterEntryArray = mapper.readValue(jsonArrayStr, TwitterEntry[].class);
logger.info("json数组反序列化成对象数组:{}", Arrays.toString(twitterEntryArray));
// json数组 -> 对象集合
List<TwitterEntry> twitterEntryList = mapper.readValue(jsonArrayStr, new TypeReference<List<TwitterEntry>>() {});
logger.info("json数组反序列化成对象集合:{}", twitterEntryList);
}
}
- 执行结果如下:
C:\jdk\bin\java.exe -javaagent:C:\sofware\JetBrains\IntelliJIDEA\lib\idea_rt.jar=64570:C:\sofware\JetBrains\IntelliJIDEA\bin -Dfile.encoding=UTF-8 -classpath C:\jdk\jre\lib\charsets.jar;C:\jdk\jre\lib\deploy.jar;C:\jdk\jre\lib\ext\access-bridge-64.jar;C:\jdk\jre\lib\ext\cldrdata.jar;C:\jdk\jre\lib\ext\dnsns.jar;C:\jdk\jre\lib\ext\jaccess.jar;C:\jdk\jre\lib\ext\jfxrt.jar;C:\jdk\jre\lib\ext\localedata.jar;C:\jdk\jre\lib\ext\nashorn.jar;C:\jdk\jre\lib\ext\sunec.jar;C:\jdk\jre\lib\ext\sunjce_provider.jar;C:\jdk\jre\lib\ext\sunmscapi.jar;C:\jdk\jre\lib\ext\sunpkcs11.jar;C:\jdk\jre\lib\ext\zipfs.jar;C:\jdk\jre\lib\javaws.jar;C:\jdk\jre\lib\jce.jar;C:\jdk\jre\lib\jfr.jar;C:\jdk\jre\lib\jfxswt.jar;C:\jdk\jre\lib\jsse.jar;C:\jdk\jre\lib\management-agent.jar;C:\jdk\jre\lib\plugin.jar;C:\jdk\jre\lib\resources.jar;C:\jdk\jre\lib\rt.jar;D:\github\blog_demos\jacksondemo\databind\target\classes;C:\Users\12167\.m2\repository\com\fasterxml\jackson\core\jackson-databind\2.11.0\jackson-databind-2.11.0.jar;C:\Users\12167\.m2\repository\com\fasterxml\jackson\core\jackson-annotations\2.11.0\jackson-annotations-2.11.0.jar;C:\Users\12167\.m2\repository\com\fasterxml\jackson\core\jackson-core\2.11.0\jackson-core-2.11.0.jar;C:\Users\12167\.m2\repository\org\slf4j\slf4j-log4j12\1.7.25\slf4j-log4j12-1.7.25.jar;C:\Users\12167\.m2\repository\org\slf4j\slf4j-api\1.7.25\slf4j-api-1.7.25.jar;C:\Users\12167\.m2\repository\log4j\log4j\1.2.17\log4j-1.2.17.jar;C:\Users\12167\.m2\repository\commons-io\commons-io\2.7\commons-io-2.7.jar;C:\Users\12167\.m2\repository\org\apache\commons\commons-lang3\3.10\commons-lang3-3.10.jar;D:\github\blog_demos\jacksondemo\beans\target\classes com.bolingcavalry.jacksondemo.databind.SimpleDemo
2020-08-28 07:53:01 INFO SimpleDemo:27 - 以下是序列化操作
2020-08-28 07:53:01 INFO SimpleDemo:38 - 序列化的字符串:{"id":123456,"text":"this is a message for serializer test","fromUserId":101,"toUserId":102,"languageCode":"zh"}
2020-08-28 07:53:01 INFO SimpleDemo:47 -
以下是反序列化操作
2020-08-28 07:53:01 INFO SimpleDemo:60 - 从字符串反序列化的对象:[Tweet, id: 1125687077, text='@stroughtonsmith You need to add a "Favourites" tab to TC/iPhone. Like what TwitterFon did. I can't WAIT for your Twitter App!! :) Any ETA?', from: 855523, to: 815309, lang: en]
2020-08-28 07:53:01 INFO SimpleDemo:64 - 从文件反序列化的对象:[Tweet, id: 1125687077, text='@stroughtonsmith You need to add a "Favourites" tab to TC/iPhone. Like what TwitterFon did. I can't WAIT for your Twitter App!! :) Any ETA?', from: 855523, to: 815309, lang: en]
2020-08-28 07:53:01 INFO SimpleDemo:68 - 从byte数组反序列化的对象:[Tweet, id: 123456, text='this is a message for serializer test', from: 101, to: 102, lang: zh]
2020-08-28 07:53:04 INFO SimpleDemo:74 - 从网络地址反序列化的对象:[Tweet, id: 112233445566, text='this is a message from zq2599's github', from: 201, to: 202, lang: en]
2020-08-28 07:53:04 INFO SimpleDemo:77 -
以下是集合序列化操作
2020-08-28 07:53:04 INFO SimpleDemo:90 - HashMap序列化的字符串:{"name":"tom","addr":{"city":"深圳","street":"粤海"},"age":11}
2020-08-28 07:53:04 INFO SimpleDemo:92 -
以下是集合反序列化操作
2020-08-28 07:53:04 INFO SimpleDemo:94 - 从字符串反序列化的HashMap对象:{name=tom, addr={city=深圳, street=粤海}, age=11}
2020-08-28 07:53:04 INFO SimpleDemo:103 - 用JsonNode对象和API反序列化得到的数:name[tom]、age[11]、city[深圳]、street[粤海]
2020-08-28 07:53:04 INFO SimpleDemo:111 - 默认的时间序列化:{"today":1598572384838}
2020-08-28 07:53:04 INFO SimpleDemo:116 - 自定义的时间序列化:{"today":"2020-08-28 07:53:04"}
{
"id":1125687077,
"text":"@stroughtonsmith You need to add a \"Favourites\" tab to TC/iPhone. Like what TwitterFon did. I can't WAIT for your Twitter App!! :) Any ETA?",
"fromUserId":855523,
"toUserId":815309,
"languageCode":"en"
}
2020-08-28 07:53:04 INFO SimpleDemo:145 - json数组反序列化成对象数组:[[Tweet, id: 1, text='text1', from: 11, to: 111, lang: en], [Tweet, id: 2, text='text2', from: 22, to: 222, lang: zh], [Tweet, id: 3, text='text3', from: 33, to: 333, lang: en]]
2020-08-28 07:53:04 INFO SimpleDemo:149 - json数组反序列化成对象集合:[[Tweet, id: 1, text='text1', from: 11, to: 111, lang: en], [Tweet, id: 2, text='text2', from: 22, to: 222, lang: zh], [Tweet, id: 3, text='text3', from: 33, to: 333, lang: en]]
Process finished with exit code 0
- 还会产生名为twitter.json的文件,内容如下:
{"id":123456,"text":"this is a message for serializer test","fromUserId":101,"toUserId":102,"languageCode":"zh"}
常用配置
下面是平时可能用到的自定义配置项目:
- 序列化结果格式化:
mapper.enable(SerializationFeature.INDENT_OUTPUT);
- 空对象不要抛出异常:
mapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
- Date、Calendar等序列化为时间格式的字符串(如果不执行以下设置,就会序列化成时间戳格式):
mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
- 反序列化时,遇到未知属性不要抛出异常:
mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
- 反序列化时,空字符串对于的实例属性为null:
mapper.enable(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT);
- 允许C和C++样式注释:
mapper.configure(JsonParser.Feature.ALLOW_COMMENTS, true);
- 允许字段名没有引号(可以进一步减小json体积):
mapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
- 允许单引号:
mapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);
特殊配置:在json对象最外层再包裹一层
- 最后要说的是个特殊配置,先来看看正常情况一个普通的序列化结果:
{
"id" : 1,
"text" : "aabbcc",
"fromUserId" : 456,
"toUserId" : 0,
"languageCode" : "zh"
}
- 接下来咱们做两件事,首先,是给上述json对应的实例类添加一个注解,如下图红框:

3. 其次,执行以下配置:
mapper.enable(SerializationFeature.WRAP_ROOT_VALUE);
- 然后再次执行TwitterEntry实例的序列化,得到的结果如下,可见和之前的序列化结果相比,之前的整个json都变成了一个value,此value对应的key就是注解JsonRootName的value属性:
{
"aaa" : {
"id" : 1,
"text" : "aabbcc",
"fromUserId" : 456,
"toUserId" : 0,
"languageCode" : "zh"
}
}
- 至此,开发中常用的API和配置都已经介绍完成,希望能给您带来一些参考,接下来的章节,咱们一起去了解另一个常用操作:jackson注解;
你不孤单,欣宸原创一路相伴
欢迎关注公众号:程序员欣宸
微信搜索「程序员欣宸」,我是欣宸,期待与您一同畅游Java世界...
https://github.com/zq2599/blog_demos
jackson学习之三:常用API操作的更多相关文章
- 大数据(5) - HDFS中的常用API操作
一.安装java 二.IntelliJ IDEA(2018)安装和破解与初期配置 参考链接 1.进入官网下载IntelliJ IDEA https://www.jetbrains.com/idea/d ...
- HDFS常用API操作 和 HDFS的I/O流操作
前置操作 创建maven工程,修改pom.xml文件: <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xs ...
- HBase学习笔记——Java API操作
1.1. 配置 HBaseConfiguration 包:org.apache.hadoop.hbase.HBaseConfiguration 作用:通过此类可以对HBase进行配置 用法实例: C ...
- Java学习随笔---常用API(二)
Object类的toString方法 将一个对象返回为字符串形式,但一般使用的时候会覆盖重写toString方法 Object类是所有类的父亲 // public class Person { pri ...
- vue学习之三常用命令
一.插值 1.1 +号运用 <!DOCTYPE html> <html lang="en"> <head> <meta charset=& ...
- 【转】通过python调用jenkins 常用api操作
原:https://www.cnblogs.com/L-O-N/p/11608220.html # -*- coding: utf- -*- import jenkins class TestJenk ...
- 通过python调用jenkins 常用api操作
# -*- coding: utf-8 -*- import jenkins class TestJenkins(object): def __new__(cls, *args, **kwargs): ...
- jackson学习之七:常用Field注解
欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...
- jackson学习之一:基本信息
欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...
随机推荐
- Centos8 Docker+Nginx部署Asp.Net Core Nginx正向代理与反向代理 负载均衡实现无状态更新
首先了解Nginx 相关介绍(正向代理和反向代理区别) 所谓代理就是一个代表.一个渠道: 此时就涉及到两个角色,一个是被代理角色,一个是目标角色,被代理角色通过这个代理访问目标角色完成一些任务的过程称 ...
- CSS系列 (03):CSS三大特性
层叠性 层叠性指的是样式的优先级,当产生冲突时以优先级高的为准,优先级相同时取后面定义的属性样式. 继承性 继承性指的是子孙元素可以继承父元素的属性. 记录一下开发中常用的继承属性: 字体系列 fon ...
- Demo分享丨看ModelArts与HiLens是如何让车自己跑起来的
摘要:基于HiLens Kit已经基本开发完成,可部署到HiLens Kit,模型的选择为基于DarkNet53的YOLOv3模型,权重为基于COCO2014训练的数据集,而车道线的检测是基于Open ...
- [LeetCode]662. Maximum Width of Binary Tree判断树的宽度
public int widthOfBinaryTree(TreeNode root) { /* 层序遍历+记录完全二叉树的坐标,左孩子2*i,右孩子2*i+1 而且要有两个变量,一个记录本层节点数, ...
- [leetcode]103. Binary Tree Zigzag Level Order Traversal二叉树Z字形层序遍历
相对于102题,稍微改变下方法就行 迭代方法: 在102题的基础上,加上一个变量来判断是不是需要反转 反转的话,当前list在for循环结束后用collection的反转方法就可以实现反转 递归方法: ...
- 配置 nginx 访问资源目录,nginx配置 root 与 alias 的区别
比如说想要把 /home/source 目录作为资源目录,那么需要如下配置: location /source/ { #识别url路径后,nginx会到/home/文件路径下,去匹配/source r ...
- 前端中的 IoC 理念
背景 前端应用在不断壮大的过程中,内部模块间的依赖可能也会随之越来越复杂,模块间的 低复用性 导致应用 难以维护,不过我们可以借助计算机领域的一些优秀的编程理念来一定程度上解决这些问题,接下来要讲述的 ...
- Liunx运维(九)-Liunx进程管理命令
文档目录: 一.ps:查看进程 二.pstree:查看进程状态树 三.pgrep:查找匹配条件的进程 四.kill:终止进程 五.killall:通过进程名终止进程 六.pkill:通过进程名种植进程 ...
- Xamarin.Form 5.0: 新功能和控件以及调试改进
上周在.NET Conf 2020,Scott Hunter(.NET),Maddy Leger(微软移动开发工具-Xamarin项目经理)和David Ortinau(首席项目经理,移动开发人员工具 ...
- 你一定需要知道的高阶JAVA枚举特性!
JAVA枚举,比你想象中还要有用! 我经常发现自己在Java中使用枚举来表示某个对象的一组潜在值. 在编译时确定类型可以具有什么值的能力是一种强大的能力,它为代码提供了结构和意义. 当我第一次了解枚举 ...