Jackson——来自官网的翻译
2019独角兽企业重金招聘Python工程师标准>>>
在Java平台(StAX, JAXB等)XML处理质量和多样化的激励下,Jackson为多功能的Java JSON处理包其目标为集快捷、正确、轻量和符合人体工程学与一体。
本文将给出Jackson的功能概览。
JSON的三种处理方式
Jackson提供了三种可选的JSON处理方法(一种方式及其两个变型):
流式 API:(也称为"增量分析/生成") 读取和写入 JSON 内容作为离散事件。
org.codehaus.jackson.JsonParser 读, org.codehaus.jackson.JsonGenerator 写。
StAX API 的激励。
树模型 :提供一个 JSON 文档可变内存树的表示形式。
org.codehaus.jackson.map.ObjectMapper 生成树 ;树组成 JsonNode 节点集。
- 树模型类似于 XML DOM。
数据绑定: JSON和POJO相互转换,基于属性访问器规约或注解。
有 两种变体: 简单 和 完整 的数据绑定:
简单数据绑定: 是指从Java Map、List、String、Numbers、Boolean和空值进行转换
完整数据绑定 :是指从任何 Java bean 类型 (及上文所述的"简单"类型) 进行转换
org.codehaus.jackson.map.ObjectMapper 对两个变种,进行编组(marshalling )处理 (写入 JSON) 和反编组(unmarshalling ,读 JSON)。
JAXB激励下的基于注释的 (代码优先)变种。
从使用的角度来看,总结这些3 种方法的用法如下:
流 API: 性能最佳的方式 (最低开销、 速度最快的读/写; 其它二者基于它实现)。
数据绑定 :使用最方便的方式。
树模型: 最灵活的方式。
鉴于这些特性,让我们考虑以相反的顺序,以Java开发人员最自然和方便的方法开始使用: 杰Jackson数据绑定 API。
Jackson的 org.codehaus.jackson.map.ObjectMapper "只是"将JSON 数据映射为POJO 对象 。例如,给定 JSON 数据:
{
"name" : { "first" : "Joe", "last" : "Sixpack" },
"gender" : "MALE",
"verified" : false,
"userImage" : "Rm9vYmFyIQ=="
}
用两行代码把它变成一个用户实例:
1 ObjectMapper mapper = new ObjectMapper(); // can reuse, share globally
2 User user = mapper.readValue(new File("user.json"), User.class);
用户类大致如下(源自另一博客):
1 public class User {
2 public enum Gender { MALE, FEMALE };
3
4 public static class Name {
5 private String _first, _last;
6
7 public String getFirst() { return _first; }
8 public String getLast() { return _last; }
9
10 public void setFirst(String s) { _first = s; }
11 public void setLast(String s) { _last = s; }
12 }
13
14 private Gender _gender;
15 private Name _name;
16 private boolean _isVerified;
17 private byte[] _userImage;
18
19 public Name getName() { return _name; }
20 public boolean isVerified() { return _isVerified; }
21 public Gender getGender() { return _gender; }
22 public byte[] getUserImage() { return _userImage; }
23
24 public void setName(Name n) { _name = n; }
25 public void setVerified(boolean b) { _isVerified = b; }
26 public void setGender(Gender g) { _gender = g; }
27 public void setUserImage(byte[] b) { _userImage = b; }
28 }
编组为JSON同样简单:
mapper.writeValue(new File("user-modified.json"), user);
对于更复杂的数据绑定 (例如,反编排格式日期到 java.util.Date),Jackson提供注解来自定义编排和反编排的处理过程。
Map<String,Object> userData = mapper.readValue(new File("user.json"), Map.class);
userData 像一个的显式结构:
1 Map<String,Object> userData = new HashMap<String,Object>(); 2 Map<String,String> nameStruct = new HashMap<String,String>(); 3 nameStruct.put("first", "Joe"); 4 nameStruct.put("last", "Sixpack"); 5 userData.put("name", nameStruct); 6 userData.put("gender", "MALE"); 7 userData.put("verified", Boolean.FALSE); 8 userData.put("userImage", "Rm9vYmFyIQ==");
Map<String,Object> userData = mapper.readValue(new File("user.json"), Map.class);
JSON Type | Java Type |
object | LinkedHashMap<String,Object> |
array | ArrayList<Object> |
string | String |
number(no fraction) | Integer, Long or BigInteger (smallest applicable) |
number (fraction) | BigDecimal |
true|false | boolean |
null | null |
泛型的数据绑定
除绑定到POJO和简单类型外,还有一个额外的变型:绑定到泛型(类型)容器。此时,由于所谓的类型擦除(Java采用向后兼容的方式实现泛型),需要进行特殊处理,以防止使用类似 Collection<String>.class(不被编译)。
所以,热想绑定数据岛Map<String,User>,方式如下:
Map<String,User> result = mapper.readValue(src, new TypeReference<Map<String,User>>() { });
其中TypeReference只需传入泛型类型即可(此时需要匿名内部类):重要部分为<Map<String,User>>,定义要绑定的数据类型。
若不如此(仅定义Map.class),其调用等价于绑定到 Map<?,?>(亦即 “untyped” Map),如前所述。
更新:1.3版的Jackson允许利用TypeFactory实现构造类型。
树模式示例
另一种从JSON获取对象方式是构造“树”,类似于XML的DOM树。Jackson构造树的方法利用JsonNode基类,其中包含公开的通常所需的读取访问方法,实际所用的节点类型为其子类;但子类型仅在修改树时需要。
JSON树可通过流式API或ObjectMapper方式读、写。
利用 ObjectMapper,方法如下:
1 ObjectMapper m = new ObjectMapper();
2 // can either use mapper.readTree(JsonParser), or bind to JsonNode
3 JsonNode rootNode = m.readValue(new File("user.json"), JsonNode.class);
4 // ensure that "last name" isn't "Xmler"; if is, change to "Jsoner"
5 JsonNode nameNode = rootNode.path("name");
6 String lastName = nameNode.path("last").getTextValue().
7 if ("xmler".equalsIgnoreCase(lastName)) {
8 ((ObjectNode)nameNode).put("last", "Jsoner");
9 }
10 // and write it out:
11 m.writeValue(new File("user-modified.json"), rootNode);
或你想马上构造一棵树,方法如下:
1 TreeMapper treeMapper = new TreeMapper();
2 ObjectNode userOb = treeMapper.objectNode();
3 Object nameOb = userRoot.putObject("name");
4 nameOb.put("first", "Joe");
5 nameOb.put("last", "Sixpack");
6 userOb.put("gender", User.Gender.MALE.toString());
7 userOb.put("verified", false);
8 byte[] imageData = getImageData(); // or wherever it comes from
9 userOb.put("userImage", imageData);
(注意: Jackson 1.2可直接使用ObjectMapper:通过ObjectMapper.createObjectNode()创建userOb -- 上例工作于Jackson 1.0 和 1.1)。
流式 API 示例
最后,还有第三种方式: 涡轮增压、 高性能的方法称为流 API (或增量模式,因为内容是增量读取和写入的)。
只是为了好玩,让我们实现使用"原生"Stream API 的写入功能 (相当于前面示例): WriteJSON.java
1 JsonFactory f = new JsonFactory();
2 JsonGenerator g = f.createJsonGenerator(new File("user.json"));
3
4 g.writeStartObject();
5 g.writeObjectFieldStart("name");
6 g.writeStringField("first", "Joe");
7 g.writeStringField("last", "Sixpack");
8 g.writeEndObject(); // for field 'name'
9 g.writeStringField("gender", Gender.MALE);
10 g.writeBooleanField("verified", false);
11 g.writeFieldName("userImage"); // no 'writeBinaryField' (yet?)
12 byte[] binaryData = ...;
13 g.writeBinary(binaryData);
14 g.writeEndObject();
15 g.close(); // 重要:强制写入输出,并关闭输出流!
非常不错 (尤其是相对写入所需的工作量,亦即等效的 XML 内容),但肯定比基本对象映射更辛苦。
另一方面,必须完全控制每一个细节。开销很小: 这仍然快于使用 ObjectMapper;并非快很多 ,但还是要快些(一般快或许 20-30%)。也许最重要的是,以流方式输出: 除一些缓冲外,所有内容都将马上输出。这意味着该方式内存使用量也是最小的。
然后如何解析呢?代码可能看起来类似:
1 JsonFactory f = new JsonFactory();
2 JsonParser jp = f.createJsonParser(new File("user.json"));
3 User user = new User();
4 jp.nextToken(); // will return JsonToken.START_OBJECT (verify?)
5 while (jp.nextToken() != JsonToken.END_OBJECT) {
6 String fieldname = jp.getCurrentName();
7 jp.nextToken(); // move to value, or START_OBJECT/START_ARRAY
8 if ("name".equals(fieldname)) { // contains an object
9 Name name = new Name();
10 while (jp.nextToken() != JsonToken.END_OBJECT) {
11 String namefield = jp.getCurrentName();
12 jp.nextToken(); // move to value
13 if ("first".equals(namefield)) {
14 name.setFirst(jp.getText());
15 } else if ("last".equals(namefield)) {
16 name.setLast(jp.getText());
17 } else {
18 throw new IllegalStateException("Unrecognized field '"+fieldname+"'!");
19 }
20 }
21 user.setName(name);
22 } else if ("gender".equals(fieldname)) {
23 user.setGender(Gender.valueOf(jp.getText()));
24 } else if ("verified".equals(fieldname)) {
25 user.setVerified(jp.getCurrentToken() == JsonToken.VALUE_TRUE);
26 } else if ("userImage".equals(fieldname)) {
27 user.setUserImage(jp.getBinaryValue());
28 } else {
29 throw new IllegalStateException("Unrecognized field '"+fieldname+"'!");
30 }
31 }
32 jp.close(); // ensure resources get cleaned up timely and properly
这是不是您将更多使用的数据绑定方法。
最后提醒的一个窍门: 可可能通过JsonParser 和 JsonGeneratorit 直接实现数据绑定和树模式。请参阅如下方法:
- JsonParser.readValueAs()
- JsonParser.readValueAsTree()
- JsonGenerator.writeObject()
- JsonGenerator.writeTree()
将实现你期望的结果。
切记,确保所用的 org.codehaus.jackson.map.MappingJsonFactory是"适用数据绑定“的解析器和生成器实例(而非基本的org.codehaus.jackson.JsonFactory)。
转载于:https://my.oschina.net/swearyd7/blog/341034
Jackson——来自官网的翻译相关推荐
- NIFI Site to Site 安全模式资料学习整合(均来自官网翻译)
NIFI Site to Site 安全模式资料学习整合(均来自官网翻译) 官网连接:Apache NiFi 文档 概述-翻译官网 当发送数据从一个NIFI示例到另一个NIFI实例,此处可以使用很多不 ...
- Godot官网新闻翻译 - 2014年
本文是"Godot官网新闻翻译"系列的第1篇,该系列旨在翻译和汇总Godot官网所发布的所有新闻.让更多英文不好的童鞋可以领悟官方新闻中的重要信息和真谛. 官网新闻地址:https ...
- MS COCO数据集人体关键点评估(Keypoint Evaluation)(来自官网)
COCO系列文章: MS COCO数据集目标检测评估(Detection Evaluation)(来自官网) MS COCO数据集人体关键点评估(Keypoint Evaluation)(来自官网) ...
- Away3D 4.0官网教程(翻译)
使用Away3D 4.Stage3D 创建3D游戏和应用程序 (此帖每天都会更新,一定让大家完全的搞明白) 补充区: 'vase.awd' 可以使用 Prefab3D打开(在帖子后面回复 ...
- Scratch2Cards来自官网
scratch简单工程制作,来自MIT官网Getting Started Guide: Scratch2Cards 1. 改变颜色,敲击空格键改变颜色 2. 带鼓声移动
- ES官网reference翻译文章(19)—Scripted Metric Aggregation
对ES官网的reference的翻译,同时也是备忘,ES版本为7.5 下面是正文翻译,附上原文链接: https://www.elastic.co/guide/en/elasticsearch/ref ...
- SpringBoot快速入门——helloworld(来自官网)
SpringBoot官网快速入门指南 首先使用SpringBoot官网快速创建可以创建一个小项目 创建完以后点击下面的Generate可以下载一个zip文件,将文件解压到指定位置. 打开idea,新版 ...
- spark官网首页翻译
官网:http://spark.apache.org/ Download(下载) Libraries(SQL And DataFrame.Spark Streaming.MLlib.Third-P ...
- Python3数据分析——NumPy快速入门教程(官网教程翻译)
目录 一.基础篇 1.创建数组 2.打印数组 3.基本运算 4.通用函数(ufunc) 5.索引,切片和迭代 二.形状操作 1.更改数组的形状 2.组合(stack)不同的数组 3.将一个数组分割(s ...
最新文章
- 华为计算产品备件查询助手
- 支持向量机原理(一)线性支持向量机
- js 调用另一个类的方法_一个隐藏在方法集和方法调用中且易被忽略的小细节
- Cnblogs自定义皮肤css样式-星空观测者
- 【渝粤教育】国家开放大学2018年春季 0025-21T数据结构 参考试题
- AE物体表面跟踪特效合成高级插件:Lockdown for Mac
- java 多线程基础, 我觉得还是有必要看看的
- 计算机视觉CV中特征点方法相关函数的学习笔记~
- 德国政府证实警方使用了 Pegasus 间谍软件
- ruby+selenium-webdriver一步一步完成自动化测试(4)—–逻辑与数据分离
- 自动化Python+selenium 用这一篇学习就够了
- 性能测试流程和各阶段的工作
- cpp封装dll和so,cpp调用so
- 从零和到竞合 亚马逊为何联姻国美?
- 超级计算机 计算化学,计算化学软件使用经验-超算中心.PDF
- FFmpeg视频截取第一帧
- php qps是什么意思,QPS是什么意思
- FM立体声 matlab 左右,FM立体声收音机的制作
- Unity 一起看+弹幕 Socket通信
- ssh 免账号密码登录