【浅度渣文】Jackson之jackson-core

news/2024/11/6 21:27:51/

原文链接:http://www.dubby.cn/detail.html?id=9069

我们在这里使用jackson-core提供的JsonParserJsonGenerator来实现基本的序列化和反序列化。

1.数据和实体类

我们先定义出JSON字符串:

{"id":123456789,"text":"我是杨正,我在http://www.dubby.cn","fromUserId":123456, "toUserId":789,"languageCode":"zh"
}
复制代码

给出我们等会解析出来后承载数据的POJO:

public class TwitterEntry {long _id;String _text;int _fromUserId, _toUserId;String _languageCode;public TwitterEntry() {}public void setId(long id) {_id = id;}public void setText(String text) {_text = text;}public void setFromUserId(int id) {_fromUserId = id;}public void setToUserId(int id) {_toUserId = id;}public void setLanguageCode(String languageCode) {_languageCode = languageCode;}public long getId() {return _id;}public String getText() {return _text;}public int getFromUserId() {return _fromUserId;}public int getToUserId() {return _toUserId;}public String getLanguageCode() {return _languageCode;}public String toString() {return "[Tweet, id: " + _id + ", text: " + _text + "', from: " + _fromUserId + ", to: " + _toUserId + ", lang: " + _languageCode + "]";}
}
复制代码

2.反序列化Unmarshalling(JSON->POJO)

private static TwitterEntry read(JsonParser jp) throws IOException {// 检查是否是JSONif (jp.nextToken() != JsonToken.START_OBJECT) {throw new IOException("Expected data to start with an Object");}TwitterEntry result = new TwitterEntry();// 遍历属性,并一个一个的赋值while (jp.nextToken() != JsonToken.END_OBJECT) {String fieldName = jp.getCurrentName();jp.nextToken();switch (fieldName) {case "id":result.setId(jp.getLongValue());break;case "text":result.setText(jp.getText());break;case "fromUserId":result.setFromUserId(jp.getIntValue());break;case "toUserId":result.setToUserId(jp.getIntValue());break;case "languageCode":result.setLanguageCode(jp.getText());break;default:throw new IOException("Unrecognized field '" + fieldName + "'");}}//关闭 parserjp.close();return result;}
复制代码

调用地方如下:

JsonFactory jsonF = new JsonFactory();String jsonStr = "{\n" +"  \"id\":123456789,\n" + "  \"text\":\"我是杨正,我在http://www.dubby.cn\",\n" +"  \"fromUserId\":123456, \n" +"  \"toUserId\":789,\n" +"  \"languageCode\":\"zh\"\n" +"}";System.out.println(jsonStr);JsonParser jp = jsonF.createParser(jsonStr);TwitterEntry entry = read(jp);System.out.println(entry.toString());
复制代码

3.序列化Marshalling(POJO -> JSON)

private static void write(JsonGenerator jg, TwitterEntry entry) throws IOException {jg.writeStartObject();jg.writeNumberField("id", entry.getId());jg.writeStringField("text", entry.getText());jg.writeNumberField("fromUserId", entry.getFromUserId());jg.writeNumberField("toUserId", entry.getToUserId());jg.writeStringField("langugeCode", entry.getLanguageCode());jg.writeEndObject();jg.close();}
复制代码

调用如下:

ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();JsonGenerator jg = jsonF.createGenerator(byteArrayOutputStream, JsonEncoding.UTF8);jg.useDefaultPrettyPrinter();write(jg, entry);System.out.println(byteArrayOutputStream.toString());
复制代码

4.更多的选项

4.1 JsonFactory的选项(命名规范化)

只针对属性名

JsonFactory f = new JsonFactory();
f.disable(JsonFactory.Feature.CANONICALIZE_FIELD_NAMES);
复制代码
选项名默认值意义
CANONICALIZE_FIELD_NAMEStrue意思是一旦名字字符串从输入(字节或字符流)被解码,它将被添加到一个符号表中,以减少在下次看到同一名字时被解码的开销(由同一工厂构造的任何解析器)
INTERN_FIELD_NAMEStrue1、如果canonicalization被启用,这个特性决定了是否被解码的字符串是否会使用String.intern()——这个在很多时候可以提高反序列化的性能。 这样做可以进一步提高反序列化的性能,因为可以使用标识比较。2、如果字符串不会重复,或者不同的字符串数量太多(成千上万),那可能要考虑关闭这个选项,不然会占用太多的内存。
FAIL_ON_SYMBOL_HASH_OVERFLOW(2.4支持)true由于规范化使用基于散列的方法将字节/字符序列解析为名称,所以理论上可以构造具有非常高的冲突率的名称集合。 如果是这样,哈希查找的性能可能会严重降低。 为了防止这种可能性,符号表使用启发式来基于异常高的碰撞次数来检测可能的攻击。
USE_THREAD_LOCAL_FOR_BUFFER_RECYCLING(2.6支持)true由于分配char []和byte []缓冲区用于内容读取/写入具有显着的影响,尤其是在处理相对较小的文档时,默认情况下JsonFactory使用SoftReference的ThreadLocal来引用BufferRecycler:这允许在多个读取/写操作。一般情况下这个选项打开对性能室友帮助的,但是在Android平台上,SoftReferences的处理是次要的,导致回收没有帮助,甚至可能只是增加了一些开销,所以可以考虑关闭。但是在关闭前请保证(a)你知道你在干什么,(b)获得可测量的性能提升。

4.2 JsonGenerator的选项

JsonFactory f = new JsonFactory();
f.enable(JsonGenerator.Feature.ESCAPE_NON_ASCII);
f.disable(JsonGenerator.Feature.AUTO_CLOSE_TARGET);
JsonGenerator g = f.createGenerator(destination);
g.enable(JsonGenerator.Feature.STRICT_DUPLICATE_DETECTION);
复制代码
选项名默认值意义
AUTO_CLOSE_TARGETtrue当generator.close()调用,决定目标资源(OutputStream, Writer)是否会被自动关闭(就算这个资源不是generator创建的)
FLUSH_PASSED_TO_STREAMtrue确定对JsonGenerator.flush()的调用是否也将调用基础目标上的flush(); 如果禁用,flush()将仅写入未刷新的内容; 如果启用,也会调用flush()。
AUTO_CLOSE_JSON_CONTENTtrue
QUOTE_FIELD_NAMEStrue
QUOTE_NON_NUMERIC_NUMBERStrue
WRITE_NUMBERS_AS_STRINGSfalse
WRITE_BIGDECIMAL_AS_PLAIN(2.3支持)false
ESCAPE_NON_ASCIIfalse
STRICT_DUPLICATE_DETECTION(2.3支持)false
IGNORE_UNKNOWN(2.5支持)false

4.3 JsonParser的选项

JsonFactory f = new JsonFactory();
f.enable(JsonParser.Feature.ALLOW_COMMENTS);
f.disable(JsonParser.Feature.ALLOW_SINGLE_QUOTES);
JsonParser p = f.createParser(jsonSource);
p.enable(JsonParser.Feature.STRICT_DUPLICATE_DETECTION);
复制代码
选项名默认值意义
AUTO_CLOSE_SOURCEtrue
ALLOW_COMMENTSfalse对于JSON来说,支持\\\**\风格的注释
ALLOW_YAML_COMMENTSfalse
ALLOW_UNQUOTED_FIELD_NAMESfalse
ALLOW_SINGLE_QUOTESfalse
ALLOW_UNQUOTED_CONTROL_CHARSfalse
ALLOW_BACKSLASH_ESCAPING_ANY_CHARACTERfalse
ALLOW_NUMERIC_LEADING_ZEROSfalse
ALLOW_NON_NUMERIC_NUMBERSfalse
ALLOW_MISSING_VALUES(2.8支持)false
STRICT_DUPLICATE_DETECTION(2.3支持)false
IGNORE_UNDEFINED2.6支持false

这里给出一个示例:

JsonFactory jsonF = new JsonFactory();String jsonStr = "{\n" +"  \"id\":123456789,\n" + "//注释1\n" + "/*注释1*/\n" +"  \"text\":\"我是杨正,我在http://www.dubby.cn\",\n" +"  \"fromUserId\":123456, \n" +"  \"toUserId\":789,\n" +"  \"languageCode\":\"zh\"\n" +"}";System.out.println(jsonStr);JsonParser jp = jsonF.createParser(jsonStr);//特意在上面的JSON字符串种加入一些注释,如果在此处不开启允许注释,会报错jp.enable(JsonParser.Feature.ALLOW_COMMENTS);TwitterEntry entry = read(jp);System.out.println(entry.toString());
复制代码

结果:

{"id":123456789,
//注释1
/*注释1*/"text":"我是杨正,我在http://www.dubby.cn","fromUserId":123456, "toUserId":789,"languageCode":"zh"
}
[Tweet, id: 123456789, text: 我是杨正,我在http://www.dubby.cn', from: 123456, to: 789, lang: zh]
复制代码

转载于:https://juejin.im/post/5bc6d461e51d450e99438148


http://www.ppmy.cn/news/623349.html

相关文章

银河麒麟高级服务器操作系统V10上.NET Core与Java相同类型MySQL(MariaDB) WebApi简单性能对比

目录 前言 一、系统信息 1. 操作系统 2. CPU(虚拟机内) 3. 内存 二、编译wrk 1.什么时wrk 2.下载编译wrk 三、部署MariaDB 1. 安装MariaDB 2. 启动MariaDB服务 3. 修改root密码 4. 创建sbtest数据库、导入结构及数据 四、压测.NET Core 3.1…

TMS WEB CORE 标准控件

TMS WEB CORE 标准控件 继承自Delphi标准VCL可视控件,所以我们只需要想开发Delphi程序那样开发并控制Web程序就可以了。 下面我们来看看TMS WEB CORE 标准控件的样子 首先我们把控件都拖入IDE编辑器 编译,运行后效果,现在的样子还很丑,Web程序,我们需要样式,后…

coredump

coredump 2014-01-11 12:28:58 分类: Android平台 http://blog.sina.com.cn/s/blog_5674d1880101617n.html http://blog.csdn.net/tenfyguo/article/details/8159176 一,什么是coredump 我们经常听到大家说到程序core掉了,需要定位解决&…

coredump在Android上的应用

之前整理过一篇linux core dump的文章,一直想把这个特性在手机上应用起来,帮助排查错误,今天终于如愿以偿,记录如下。 【1】概述 在Android系统上,java应用程序出错时很容易通过logcat获取出错信息,一般会有…

Core Technologies

更新于三月三十一号 21:01 原文 This part of the reference documentation covers all the technologies that are absolutely integral to the Spring Framework. Foremost amongst these is the Spring Framework’s Inversion of Control (IoC) container. A thorough trea…

CoreDNS篇8-健康检查

本文主要讲解介绍CoreDNS内置的两个健康检查插件health和ready的使用方式和适用场景。 1、health插件 health插件默认情况下会在8080端口的/health路径下提供健康状态查询服务,当CoreDNS服务正常的时候,会返回200的http状态码并附带一个OK的内容。 [ro…

linux生成java core_【转载】Linux core dump在Android上的应用

之前整理过一篇linux core dump的文章,一直想把这个特性在手机上应用起来,帮助排查错误,今天终于如愿以偿,记录如下。 【1】概述 在Android系统上,java应用程序出错时很容易通过logcat获取出错信息,一般会有…

k8s coredns显示0/1 Running问题排查

问题现象: 发现k8s-node1节点的coredns出现0/1 Running状态; 查看详细信息:kubectl describe pod coredns-57d4cbf879-xgk2f -n kube-system [rootk8s-master kubernetes]# kubectl describe pod coredns-57d4cbf879-xgk2f -n kube-system N…