须知少年凌云志,曾许人间第一流。这篇文章主要讲述jackson学习之三:常用API操作相关的知识,希望能为你提供帮助。
欢迎访问我的GitHub
源码下载
- 如果您不想编码,可以在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";
### 集合序列化
1. HashMap转字符串:
```java
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.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 cant 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);
2. 执行结果如下:
```shell
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 INFOSimpleDemo:27 - 以下是序列化操作
2020-08-28 07:53:01 INFOSimpleDemo:38 - 序列化的字符串:"id":123456,"text":"this is a message for serializer test","fromUserId":101,"toUserId":102,"languageCode":"zh"
2020-08-28 07:53:01 INFOSimpleDemo:47 - 以下是反序列化操作
2020-08-28 07:53:01 INFOSimpleDemo:60 - 从字符串反序列化的对象:[Tweet, id: 1125687077, text=@stroughtonsmith You need to add a "Favourites" tab to TC/iPhone. Like what TwitterFon did. I cant WAIT for your Twitter App!! :) Any ETA?, from: 855523, to: 815309, lang: en]
2020-08-28 07:53:01 INFOSimpleDemo:64 - 从文件反序列化的对象:[Tweet, id: 1125687077, text=@stroughtonsmith You need to add a "Favourites" tab to TC/iPhone. Like what TwitterFon did. I cant WAIT for your Twitter App!! :) Any ETA?, from: 855523, to: 815309, lang: en]
2020-08-28 07:53:01 INFOSimpleDemo: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 INFOSimpleDemo:74 - 从网络地址反序列化的对象:[Tweet, id: 112233445566, text=this is a message from zq2599s github, from: 201, to: 202, lang: en]
2020-08-28 07:53:04 INFOSimpleDemo:77 - 以下是集合序列化操作
2020-08-28 07:53:04 INFOSimpleDemo:90 - HashMap序列化的字符串:"name":"tom","addr":"city":"深圳","street":"粤海","age":11
2020-08-28 07:53:04 INFOSimpleDemo:92 - 以下是集合反序列化操作
2020-08-28 07:53:04 INFOSimpleDemo:94 - 从字符串反序列化的HashMap对象:name=tom, addr=city=深圳, street=粤海, age=11
2020-08-28 07:53:04 INFOSimpleDemo:103 - 用JsonNode对象和API反序列化得到的数:name[tom]、age[11]、city[深圳]、street[粤海]
2020-08-28 07:53:04 INFOSimpleDemo:111 - 默认的时间序列化:"today":1598572384838
2020-08-28 07:53:04 INFOSimpleDemo: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 cant WAIT for your Twitter App!! :) Any ETA?",
"fromUserId":855523,
"toUserId":815309,
"languageCode":"en"2020-08-28 07:53:04 INFOSimpleDemo: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 INFOSimpleDemo: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"
常用配置
【jackson学习之三(常用API操作)】下面是平时可能用到的自定义配置项目:
- 序列化结果格式化:
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对应的实例类添加一个注解,如下图红框:
文章图片
- 其次,执行以下配置:
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注解==;
推荐阅读
- 7个复制锁定或使用中文件的工具
- Centos7下设置MySql自动启动
- 微服务架构 | *2.5 Nacos 长轮询定时机制的源码分析
- 普通开发者,如何成为Apache顶级项目的commiter ()
- 如何使用Tkinter创建启动画面()
- 如何使用HTML和CSS创建具有悬停效果的动画导航栏()
- 如何使用Django Forms创建表单()
- 如何创建GUI显示COVID19数据()
- 如何使用HTML,CSS和JavaScript创建二进制计算器()