jackson学习之三:常用API操作

Wesley13
• 阅读 487

欢迎访问我的GitHub

https://github.com/zq2599/blog_demos

内容:所有原创文章分类汇总及配套源码,涉及Java、Docker、Kubernetes、DevOPS等;

系列文章汇总

源码下载

  1. 如果您不想编码,可以在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协议

  1. 这个git项目中有多个文件夹,本章的应用在jacksondemo文件夹下,如下图红框所示:

jackson学习之三:常用API操作

本篇概览

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

  1. 体验最常用的操作,内容如下图所示:

jackson学习之三:常用API操作

  1. 介绍常用的可配置属性,以便按需要来设置;
  2. 接下来进入快速浏览的环节,咱们一起先把各个API过一遍;

单个对象序列化

先看常用的序列化API:

  1. 对象转字符串:

    String jsonStr = mapper.writeValueAsString(twitterEntry);

  2. 对象转文件:

    mapper.writeValue(new File("twitter.json"), twitterEntry);

  3. 对象转byte数组:

    byte[] array = mapper.writeValueAsBytes(twitterEntry);

单个对象反序列化

  1. 字符串转对象:

    TwitterEntry tFromStr = mapper.readValue(objectJsonStr, TwitterEntry.class);

  2. 文件转对象:

    TwitterEntry tFromFile = mapper.readValue(new File("twitter.json"), TwitterEntry.class);

  3. byte数组转对象:

    TwitterEntry tFromBytes = mapper.readValue(array, TwitterEntry.class);

  4. 字符串网络地址转对象:

    String testJsonDataUrl = "https://raw.githubusercontent.com/zq2599/blog_demos/master/files/twitteer_message.json";

    TwitterEntry tFromUrl = mapper.readValue(new URL(testJsonDataUrl), TwitterEntry.class);

集合序列化

  1. HashMap转字符串:

    String mapJsonStr = mapper.writeValueAsString(map);

集合反序列化

  1. 字符串转HashMap:

    Map<String, Object> mapFromStr = mapper.readValue(mapJsonStr, new TypeReference<Map<String, Object>>() {});

JsonNode

  1. 如果您不想使用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();

时间字段格式化

  1. 对于Date字段,默认的反序列化是时间戳,可以修改配置:

    mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd hh:mm:ss")); dateMapStr = mapper.writeValueAsString(dateMap);

JSON数组的反序列化

假设jsonArrayStr是个json数组格式的字符串:

  1. JSON数组转对象数组:

    TwitterEntry[] twitterEntryArray = mapper.readValue(jsonArrayStr, TwitterEntry[].class);

  2. JSON数组转对象集合(ArrayList):

    List twitterEntryList = mapper.readValue(jsonArrayStr, new TypeReference<List>() {});

完整代码

  1. 上述所有常用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);
    }
    

    }

  2. 执行结果如下:

    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

  3. 还会产生名为twitter.json的文件,内容如下:

    {"id":123456,"text":"this is a message for serializer test","fromUserId":101,"toUserId":102,"languageCode":"zh"}

常用配置

下面是平时可能用到的自定义配置项目:

  1. 序列化结果格式化:

    mapper.enable(SerializationFeature.INDENT_OUTPUT);

  2. 空对象不要抛出异常:

    mapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);

  3. Date、Calendar等序列化为时间格式的字符串(如果不执行以下设置,就会序列化成时间戳格式):

    mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);

  4. 反序列化时,遇到未知属性不要抛出异常:

    mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);

  5. 反序列化时,空字符串对于的实例属性为null:

    mapper.enable(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT);

  6. 允许C和C++样式注释:

    mapper.configure(JsonParser.Feature.ALLOW_COMMENTS, true);

  7. 允许字段名没有引号(可以进一步减小json体积):

    mapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);

  8. 允许单引号:

    mapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);

特殊配置:在json对象最外层再包裹一层

  1. 最后要说的是个特殊配置,先来看看正常情况一个普通的序列化结果:

    { "id" : 1, "text" : "aabbcc", "fromUserId" : 456, "toUserId" : 0, "languageCode" : "zh" }

  2. 接下来咱们做两件事,首先,是给上述json对应的实例类添加一个注解,如下图红框:

jackson学习之三:常用API操作 3. 其次,执行以下配置:

mapper.enable(SerializationFeature.WRAP_ROOT_VALUE);
  1. 然后再次执行TwitterEntry实例的序列化,得到的结果如下,可见和之前的序列化结果相比,之前的整个json都变成了一个value,此value对应的key就是注解JsonRootName的value属性:

    { "aaa" : { "id" : 1, "text" : "aabbcc", "fromUserId" : 456, "toUserId" : 0, "languageCode" : "zh" } }

  • 至此,开发中常用的API和配置都已经介绍完成,希望能给您带来一些参考,接下来的章节,咱们一起去了解另一个常用操作:jackson注解

你不孤单,欣宸原创一路相伴

  1. Java系列
  2. Spring系列
  3. Docker系列
  4. kubernetes系列
  5. 数据库+中间件系列
  6. DevOps系列

欢迎关注公众号:程序员欣宸

微信搜索「程序员欣宸」,我是欣宸,期待与您一同畅游Java世界... https://github.com/zq2599/blog_demos

点赞
收藏
评论区
推荐文章
blmius blmius
2年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Jacquelyn38 Jacquelyn38
2年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Wesley13 Wesley13
2年前
Java获得今日零时零分零秒的时间(Date型)
publicDatezeroTime()throwsParseException{    DatetimenewDate();    SimpleDateFormatsimpnewSimpleDateFormat("yyyyMMdd00:00:00");    SimpleDateFormatsimp2newS
Stella981 Stella981
2年前
KVM调整cpu和内存
一.修改kvm虚拟机的配置1、virsheditcentos7找到“memory”和“vcpu”标签,将<namecentos7</name<uuid2220a6d1a36a4fbb8523e078b3dfe795</uuid
Wesley13 Wesley13
2年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
2年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
2年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Stella981 Stella981
2年前
Docker 部署SpringBoot项目不香吗?
  公众号改版后文章乱序推荐,希望你可以点击上方“Java进阶架构师”,点击右上角,将我们设为★“星标”!这样才不会错过每日进阶架构文章呀。  !(http://dingyue.ws.126.net/2020/0920/b00fbfc7j00qgy5xy002kd200qo00hsg00it00cj.jpg)  2
Wesley13 Wesley13
2年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
3个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这