(翻译)jackson五分钟教程
来源:互联网 发布:成都市广电网络分公司 编辑:程序博客网 时间:2024/05/29 19:03
概述
jackson的架构和开发思路是从java平台的STAX、JAXB等XML工具获得的灵感,同样继承了他们的高质量和高灵活性。同样,XML操作的DOM方式和STAX方式在jackson里面也能看到,分别对应的是TreeModel和StreamingAPI。jackson的野心巨大,希望能够给开发者带来快速、正确、轻量、顺手的使用体验。
接下来我们一起简略看一下jackson的整体能力:
JSON的三种使用方式
jackson提供了三种处理JSON的方式,其中Data binding方式有两个变种:
Streaming API方式(使用事件方式读写JSON内容):
使用org.codehaus.jackson.JsonParser读,使用org.codehaus.jackson.JsonGenerator写;
该方式灵感来源于XML的STAX 方式。
Tree Model (使用生成JSON文档内存树的方式,将JSON内容一次读入内存):
使用org.codehaus.jackson.map.ObjectMapper构建树,树中是JsonNode;
树模型类似于XML的DOM模型。
Data Binding(使用属性方法或者注解实现JSON和POJOs之间的相互转换):
提供了两种方式,一种是完全对象(full data binding)绑定,一种是简单对象(simple data binding)绑定。
简单对象绑定用来在JSON和java的Maps, Lists, Strings, Numbers, Booleans, and null之间转换;
完全对象绑定用来在JSON和java bean对象之间的转换,同样适用于java内置对象。
总结一下三种方法:
Streaming API性能最好(最低的消耗、最快的读写速度、其他两种方法的基础)
Data Binding 好用、便利
Tree Model 灵活
Full Data Binding (POJO) Example
org.codehaus.jackson.map.ObjectMapper 用来实现JSON和POJOs之间的转换。
比如有如下内容的json文件user.json:
{ "name" : { "first" : "Joe", "last" : "Sixpack" }, "gender" : "MALE", "verified" : false, "userImage" : "Rm9vYmFyIQ=="}
只需要两行代码,就可以把上述json转成User示例:
ObjectMapper mapper = new ObjectMapper(); // can reuse, share globallyUser user = mapper.readValue(new File("user.json"), User.class);
User对象定义是这样的:
public class User { public enum Gender { MALE, FEMALE }; public static class Name { private String _first, _last; public String getFirst() { return _first; } public String getLast() { return _last; } public void setFirst(String s) { _first = s; } public void setLast(String s) { _last = s; } } private Gender _gender; private Name _name; private boolean _isVerified; private byte[] _userImage; public Name getName() { return _name; } public boolean isVerified() { return _isVerified; } public Gender getGender() { return _gender; } public byte[] getUserImage() { return _userImage; } public void setName(Name n) { _name = n; } public void setVerified(boolean b) { _isVerified = b; } public void setGender(Gender g) { _gender = g; } public void setUserImage(byte[] b) { _userImage = b; } }
把User实例转回成json如下:
mapper.writeValue(new File("user-modified.json"), user);
Simple Data Binding Example
如果我们没有或者不想创建一个单独的类来做JSON和POJO之间的转换,那么可以使用这种方式来做。这种方式和Full Data Binding的方式实质上是一样的,差别只在于指定的POJO类型是java的内置类型(Object.class,Map.class, List.class, String[].class等)。用法和上边一样,举个例子:
JSON转换成java对象实例的方法:
Map<String,Object> userData = mapper.readValue(new File("user.json"), Map.class);
java对象实例转换成JSON的方法:
Map<String,Object> userData = new HashMap<String,Object>();Map<String,String> nameStruct = new HashMap<String,String>();nameStruct.put("first", "Joe");nameStruct.put("last", "Sixpack");userData.put("name", nameStruct);userData.put("gender", "MALE");userData.put("verified", Boolean.FALSE);userData.put("userImage", "Rm9vYmFyIQ==");mapper.writeValue(new File("user-modified.json"), userData);
你会发现在JSON转成Map.class的过程中没有指定Map的泛型类型,但是jackson也能正确的转换。jackson有一个自己的转换关系,能够对json数据进行默认转换。默认转换关系如下:
JSON TypeJava TypeobjectLinkedHashMap
Data Binding with Generics(泛型类型)
在上一个例子中,我们用了Map.class指定目标类型,jackson使用默认的类型进行转换。这里如果我们想指定具体的Key和Value类型,也是可以的。比如,想转换成Map
Map<String,User> result = mapper.readValue(src, new TypeReference<Map<String,User>>() { });
是不是很牛逼!
此外,jackson的1.3版本又提供了一个TypeFactory指定Map
Tree Model Example
另外一种方式是使用树模型,树模型和XML的DOM方式类似。jackson会构建一课由JsonNode组成的树,里面的JsonNode暴露了一般需要用到的取值接口。当然,树里面的Node是JsonNode的子类,只有需要修改值的时候,你才有必要转换到子类型。
把json文本读取到一棵树:
ObjectMapper m = new ObjectMapper();// can either use mapper.readTree(source), or mapper.readValue(source, JsonNode.class);JsonNode rootNode = m.readTree(new File("user.json"));// ensure that "last name" isn't "Xmler"; if is, change to "Jsoner"JsonNode nameNode = rootNode.path("name");String lastName = nameNode.path("last").getTextValue().if ("xmler".equalsIgnoreCase(lastName)) { ((ObjectNode)nameNode).put("last", "Jsoner");}// and write it out:m.writeValue(new File("user-modified.json"), rootNode);
直接在内存创建一棵树:
TreeMapper treeMapper = new TreeMapper();ObjectNode userOb = treeMapper.objectNode();Object nameOb = userRoot.putObject("name");nameOb.put("first", "Joe");nameOb.put("last", "Sixpack");userOb.put("gender", User.Gender.MALE.toString());userOb.put("verified", false);byte[] imageData = getImageData(); // or wherever it comes fromuserOb.put("userImage", imageData);
Streaming API Example
由于基本不会用到这种方式,所以,这里就不翻译了,接下来说点别的。
jackson怎么线程安全的使用ObjectMapper
ObjectMapper是线程安全的,所以我们可以直接定义一个全局的静态变量就可以了,不需要特别处理,如下:
class YourClass{private static final ObjectMapper objectMapper = new ObjectMapper();//do something with this objectMapper instance}
ObjectMapper的常见属性设置
可能有时候我们需要对objectMapper做一些初始化设定,如下:
class YourClass{private static final ObjectMapper objectMapper = new ObjectMapper();static{objectMapper.setPropertyNamingStrategy(PropertyNamingStrategy.CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES)//指定属性字段转换成小写+下划线方式.SETDATEFORMAT(new SimpleDateFormat(DATETIME_FORMAT))//指定日期时间转换成的样式(线程安全吗?).setSerializationInclusion(Include.NON_NULL);//指定不输出值为空的属性}//do something with this objectMapper instance}
大家知道SimpleDateFormat是线程不安全的,那么这里直接设置了一个SimpleDateFormat,那么他安全吗?是安全的,内部有复制机制。
从gson更换到jackson让人不爽的一点
当POJO里面包含isXXX这样的字段的时候,gson转出来的结果是is_xxx,但是jackson转出来的是xxx,也就是自动抹掉了is。
解决办法有一个就是在对应属性上添加@JsonPropety(“is_xxx”)注解,指名属性名。就算如此,在一个些复杂的项目里面也会有其他的坑,所以尽量不要用isXXX来做属性名!!
- (翻译)jackson五分钟教程
- Git五分钟教程
- Git五分钟教程
- Git五分钟教程
- git 五分钟教程
- Git五分钟教程
- Lucene五分钟教程
- Lucene五分钟教程
- Git五分钟教程
- Git五分钟教程
- 五分钟Jackson入门 JSON数据与Java对象相互转换(附项目源码)
- 带你五分钟搞定Jackson JSON Processor
- git 之五分钟教程
- git 之五分钟教程
- git 之五分钟教程
- (翻译)解雇之前的五分钟
- 五分钟solr4.5教程(搭建、运行)
- 五分钟solr4.5教程(搭建、运行)
- Rxjava
- qcom平台qmdl转isf格式方法
- Bootstrap基础14——列表list-group
- 日志打印
- webpack+react+antd项目编写过程中遇到的问题
- (翻译)jackson五分钟教程
- 实时人脸比对DEMO源码及使用说明
- 虚拟机模拟搭建Redis集群环境
- tee命令用法
- 深入TCP(二)--可靠传输&流量控制&拥塞控制
- java 中的 static 关键字
- 如何将spring boot application.properties修改成为spring boot配置文件
- linux使用telnet自动发送mail.
- SpringBoot整合JPA操作数据库