jackson java对象和json对象的互相转换
概述
Jackson框架是基于Java平台的一套数据处理工具,被称为“最好的Java Json解析器”。
Jackson框架包含了3个核心库:streaming,databind,annotations.Jackson还包含了其它数据处理类库,此外不作说明。
Jackson版本: 1.x (目前版本从1.1~1.9)与2.x。1.x与2.x从包的命名上可以看出来,1.x的类库中,包命名以:org.codehaus.jackson.xxx开头,而2.x类库中包命令:com.fastxml.jackson.xxx开头
Jackson Home Page:https://github.com/FasterXML/jackson
Jackson Wiki:http://wiki.fasterxml.com/JacksonHome
Jackson doc: https://github.com/FasterXML/jackson-docs
Jackson Download Page:http://wiki.fasterxml.com/JacksonDownload
准备工作
本文所有程序都基于JDK1.7,依赖jackon的三个核心类库:
jackson-core-2.5.3.jar
jackson-annotations-2.5.3.jar
jackson-databind-2.5.3.jar
Jackson处理Json
Jackson提供了三种可选的Json处理方法:流式API(Streaming API) 、树模型(Tree Model)、数据绑定(Data Binding)。从使用角度来看,比较一下这三种处理Json的方式的特性:
Streaming API:是效率最高的处理方式(开销低、读写速度快,但程序编写复杂度高)
Tree Model:是最灵活的处理方式
Data Binding:是最常用的处理方式
下面我们通过例子程序分别使用DataBinding,TreeModel,Streaming的方式来创建和解析Json字符串
1.DataBinding处理Json
- package com.jackson.json.databinding;
- public class Province {
- public String name;
- public int population;
- public String[] city;
- }
- package com.jackson.json.databinding;
- import java.util.ArrayList;
- import java.util.Arrays;
- import java.util.Date;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
- public class Country {
- // 注意:被序列化的bean的private属性字段需要创建getter方法或者属性字段应该为public
- private String country_id;
- private Date birthDate;
- private List<String> nation = new ArrayList<String>();
- private String[] lakes;
- private List<Province> provinces = new ArrayList<Province>();
- private Map<String, Integer> traffic = new HashMap<String, Integer>();
- public Country() {
- // TODO Auto-generated constructor stub
- }
- public Country(String countryId) {
- this.country_id = countryId;
- }
- public String getCountry_id() {
- return country_id;
- }
- public void setCountry_id(String country_id) {
- this.country_id = country_id;
- }
- public Date getBirthDate() {
- return birthDate;
- }
- public void setBirthDate(Date birthDate) {
- this.birthDate = birthDate;
- }
- public List<String> getNation() {
- return nation;
- }
- public void setNation(List<String> nation) {
- this.nation = nation;
- }
- public String[] getLakes() {
- return lakes;
- }
- public void setLakes(String[] lakes) {
- this.lakes = lakes;
- }
- public Integer get(String key) {
- return traffic.get(key);
- }
- public Map<String, Integer> getTraffic() {
- return traffic;
- }
- public void setTraffic(Map<String, Integer> traffic) {
- this.traffic = traffic;
- }
- public void addTraffic(String key, Integer value) {
- traffic.put(key, value);
- }
- public List<Province> getProvinces() {
- return provinces;
- }
- public void setProvinces(List<Province> provinces) {
- this.provinces = provinces;
- }
- @Override
- public String toString() {
- return "Country [country_id=" + country_id + ", birthDate=" + birthDate
- + ", nation=" + nation + ", lakes=" + Arrays.toString(lakes)
- + ", province=" + provinces + ", traffic=" + traffic + "]";
- }
- }
JavaBeanSerializeToJson.java
- package com.jackson.json.databinding;
- import java.io.File;
- import java.text.SimpleDateFormat;
- import java.util.ArrayList;
- import java.util.List;
- import com.fasterxml.jackson.annotation.JsonInclude.Include;
- import com.fasterxml.jackson.databind.ObjectMapper;
- import com.fasterxml.jackson.databind.SerializationFeature;
- public class JavaBeanSerializeToJson {
- public static void convert() throws Exception {
- // 使用ObjectMapper来转化对象为Json
- ObjectMapper mapper = new ObjectMapper();
- // 添加功能,让时间格式更具有可读性
- SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
- mapper.setDateFormat(dateFormat);
- Country country = new Country("China");
- country.setBirthDate(dateFormat.parse("1949-10-01"));
- country.setLakes(new String[] { "Qinghai Lake", "Poyang Lake",
- "Dongting Lake", "Taihu Lake" });
- List<String> nation = new ArrayList<String>();
- nation.add("Han");
- nation.add("Meng");
- nation.add("Hui");
- nation.add("WeiWuEr");
- nation.add("Zang");
- country.setNation(nation);
- Province province = new Province();
- province.name = "Shanxi";
- province.population = 37751200;
- Province province2 = new Province();
- province2.name = "ZheJiang";
- province2.population = 55080000;
- List<Province> provinces = new ArrayList<Province>();
- provinces.add(province);
- provinces.add(province2);
- country.setProvinces(provinces);
- country.addTraffic("Train(KM)", 112000);
- country.addTraffic("HighWay(KM)", 4240000);
- // 为了使JSON视觉上的可读性,增加一行如下代码,注意,在生产中不需要这样,因为这样会增大Json的内容
- mapper.configure(SerializationFeature.INDENT_OUTPUT, true);
- // 配置mapper忽略空属性
- mapper.setSerializationInclusion(Include.NON_EMPTY);
- // 默认情况,Jackson使用Java属性字段名称作为 Json的属性名称,也可以使用Jackson annotations(注解)改变Json属性名称
- mapper.writeValue(new File("country.json"), country);
- }
- public static void main(String[] args) throws Exception {
- convert();
- }
- }
- {
- "country_id" : "China",
- "birthDate" : "1949-10-01",
- "nation" : [ "Han", "Meng", "Hui", "WeiWuEr", "Zang" ],
- "lakes" : [ "Qinghai Lake", "Poyang Lake", "Dongting Lake", "Taihu Lake" ],
- "provinces" : [ {
- "name" : "Shanxi",
- "population" : 37751200
- }, {
- "name" : "ZheJiang",
- "population" : 55080000
- } ],
- "traffic" : {
- "HighWay(KM)" : 4240000,
- "Train(KM)" : 112000
- }
- }
- package com.jackson.json.databinding;
- import java.io.File;
- import java.io.IOException;
- import java.text.SimpleDateFormat;
- import java.util.Iterator;
- import java.util.List;
- import com.fasterxml.jackson.core.JsonParseException;
- import com.fasterxml.jackson.databind.DeserializationFeature;
- import com.fasterxml.jackson.databind.JsonMappingException;
- import com.fasterxml.jackson.databind.ObjectMapper;
- /**
- * 将Json字符串反序列化为Java对象
- */
- public class JsonDeserializeToJava {
- public static void main(String[] args) throws Exception {
- //ObjectMapper类用序列化与反序列化映射器
- ObjectMapper mapper = new ObjectMapper();
- File json = new File("country.json");
- //当反序列化json时,未知属性会引起的反序列化被打断,这里我们禁用未知属性打断反序列化功能,
- //因为,例如json里有10个属性,而我们的bean中只定义了2个属性,其它8个属性将被忽略
- mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
- //从json映射到java对象,得到country对象后就可以遍历查找,下面遍历部分内容,能说明问题就可以了
- Country country = mapper.readValue(json, Country.class);
- System.out.println("country_id:"+country.getCountry_id());
- //设置时间格式,便于阅读
- SimpleDateFormat dateformat = new SimpleDateFormat("yyyy-MM-dd");
- String birthDate = dateformat.format(country.getBirthDate());
- System.out.println("birthDate:"+birthDate);
- List<Province> provinces = country.getProvinces();
- for (Province province : provinces) {
- System.out.println("province:"+province.name + "\n" + "population:"+province.population);
- }
- }
- }
- country_id:China
- birthDate:1949-10-01
- province:Shanxi
- population:37751200
- province:ZheJiang
- population:55080000
2.Tree Model处理Json
(1)tree model生成json:
- package com.jackson.json.treemodel;
- import java.io.File;
- import java.io.FileWriter;
- import com.fasterxml.jackson.core.JsonFactory;
- import com.fasterxml.jackson.core.JsonGenerator;
- import com.fasterxml.jackson.databind.ObjectMapper;
- import com.fasterxml.jackson.databind.SerializationFeature;
- import com.fasterxml.jackson.databind.node.ArrayNode;
- import com.fasterxml.jackson.databind.node.JsonNodeFactory;
- import com.fasterxml.jackson.databind.node.ObjectNode;
- public class SerializationExampleTreeModel {
- public static void main(String[] args) throws Exception {
- //创建一个节点工厂,为我们提供所有节点
- JsonNodeFactory factory = new JsonNodeFactory(false);
- //创建一个json factory来写tree modle为json
- JsonFactory jsonFactory = new JsonFactory();
- //创建一个json生成器
- JsonGenerator generator = jsonFactory.createGenerator(new FileWriter(new File("country2.json")));
- //注意,默认情况下对象映射器不会指定根节点,下面设根节点为country
- ObjectMapper mapper = new ObjectMapper();
- ObjectNode country = factory.objectNode();
- country.put("country_id", "China");
- country.put("birthDate", "1949-10-01");
- //在Java中,List和Array转化为json后对应的格式符号都是"obj:[]"
- ArrayNode nation = factory.arrayNode();
- nation.add("Han").add("Meng").add("Hui").add("WeiWuEr").add("Zang");
- country.set("nation", nation);
- ArrayNode lakes = factory.arrayNode();
- lakes.add("QingHai Lake").add("Poyang Lake").add("Dongting Lake").add("Taihu Lake");
- country.set("lakes", lakes);
- ArrayNode provinces = factory.arrayNode();
- ObjectNode province = factory.objectNode();
- ObjectNode province2 = factory.objectNode();
- province.put("name","Shanxi");
- province.put("population", 37751200);
- province2.put("name","ZheJiang");
- province2.put("population", 55080000);
- provinces.add(province).add(province2);
- country.set("provinces", provinces);
- ObjectNode traffic = factory.objectNode();
- traffic.put("HighWay(KM)", 4240000);
- traffic.put("Train(KM)", 112000);
- country.set("traffic", traffic);
- mapper.configure(SerializationFeature.INDENT_OUTPUT, true);
- mapper.writeTree(generator, country);
- }
- }
程序运行生成country2.json,内容如下:
- {"country_id":"China","birthDate":"1949-10-01","nation":["Han","Meng","Hui","WeiWuEr","Zang"],"lakes":["QingHai Lake","Poyang Lake","Dongting Lake","Taihu Lake"],"provinces":[{"name":"Shanxi","population":37751200},{"name":"ZheJiang","population":55080000}],"traffic":{"HighWay(KM)":4240000,"Train(KM)":112000}}
(2) json字符串反序列化为tree mode
DeserializationExampleTreeModel1.java,请注意观察程序中不同的JsonNode的类型变化
- package com.jackson.json.treemodel;
- import java.io.File;
- import java.util.Iterator;
- import com.fasterxml.jackson.databind.JsonNode;
- import com.fasterxml.jackson.databind.ObjectMapper;
- public class DeserializationExampleTreeModel1 {
- public static void main(String[] args) throws Exception {
- ObjectMapper mapper = new ObjectMapper();
- // Jackson提供一个树节点被称为"JsonNode",ObjectMapper提供方法来读json作为树的JsonNode根节点
- JsonNode node = mapper.readTree(new File("country2.json"));
- // 看看根节点的类型
- System.out.println("node JsonNodeType:"+node.getNodeType());
- // 是不是一个容器
- System.out.println("node is container Node ? "+node.isContainerNode());
- // 得到所有node节点的子节点名称
- System.out.println("---------得到所有node节点的子节点名称-------------------------");
- Iterator<String> fieldNames = node.fieldNames();
- while (fieldNames.hasNext()) {
- String fieldName = fieldNames.next();
- System.out.print(fieldName+" ");
- }
- System.out.println("\n-----------------------------------------------------");
- // as.Text的作用是有值返回值,无值返回空字符串
- JsonNode country_id = node.get("country_id");
- System.out.println("country_id:"+country_id.asText() + " JsonNodeType:"+country_id.getNodeType());
- JsonNode birthDate = node.get("birthDate");
- System.out.println("birthDate:"+birthDate.asText()+" JsonNodeType:"+birthDate.getNodeType());
- JsonNode nation = node.get("nation");
- System.out.println("nation:"+ nation+ " JsonNodeType:"+nation.getNodeType());
- JsonNode lakes = node.get("lakes");
- System.out.println("lakes:"+lakes+" JsonNodeType:"+lakes.getNodeType());
- JsonNode provinces = node.get("provinces");
- System.out.println("provinces JsonNodeType:"+provinces.getNodeType());
- boolean flag = true;
- for (JsonNode provinceElements : provinces) {
- //为了避免provinceElements多次打印,用flag控制打印,能体现provinceElements的JsonNodeType就可以了
- if(flag){
- System.out.println("provinceElements JsonNodeType:"+provinceElements.getNodeType());
- System.out.println("provinceElements is container node? "+provinceElements.isContainerNode());
- flag = false;
- }
- Iterator<String> provinceElementFields = provinceElements.fieldNames();
- while (provinceElementFields.hasNext()) {
- String fieldName = (String) provinceElementFields.next();
- String province;
- if ("population".equals(fieldName)) {
- province = fieldName + ":" + provinceElements.get(fieldName).asInt();
- }else{
- province = fieldName + ":" + provinceElements.get(fieldName).asText();
- }
- System.out.println(province);
- }
- }
- }
- }
程序运行后打印结果如下:
- node JsonNodeType:OBJECT
- node is container Node ? true
- ---------得到所有node节点的子节点名称-------------------------
- country_id birthDate nation lakes provinces traffic
- -----------------------------------------------------
- country_id:China JsonNodeType:STRING
- birthDate:1949-10-01 JsonNodeType:STRING
- nation:["Han","Meng","Hui","WeiWuEr","Zang"] JsonNodeType:ARRAY
- lakes:["QingHai Lake","Poyang Lake","Dongting Lake","Taihu Lake"] JsonNodeType:ARRAY
- provinces JsonNodeType:ARRAY
- provinceElements JsonNodeType:OBJECT
- provinceElements is container node? true
- name:Shanxi
- population:37751200
- name:ZheJiang
- population:55080000
在来看一下DeserializationExampleTreeModel2.java,本例中使用JsonNode.path的方法,path方法类似于DeserializationExampleTreeModel1.java中使用的get方法,
但当node不存在时,get方法返回null,而path返回MISSING类型的JsonNode
- package com.jackson.json.treemodel;
- import java.io.File;
- import java.io.IOException;
- import java.util.Iterator;
- import com.fasterxml.jackson.core.JsonProcessingException;
- import com.fasterxml.jackson.databind.JsonNode;
- import com.fasterxml.jackson.databind.ObjectMapper;
- public class DeserializationExampleTreeModle2 {
- public static void main(String[] args) throws JsonProcessingException, IOException{
- ObjectMapper mapper = new ObjectMapper();
- JsonNode node = mapper.readTree(new File("country2.json"));
- //path方法获取JsonNode时,当对象不存在时,返回MISSING类型的JsonNode
- JsonNode missingNode = node.path("test");
- if(missingNode.isMissingNode()){
- System.out.println("JsonNodeType : " + missingNode.getNodeType());
- }
- System.out.println("country_id:"+node.path("country_id").asText());
- JsonNode provinces = node.path("provinces");
- for (JsonNode provinceElements : provinces) {
- Iterator<String> provincesFields = provinceElements.fieldNames();
- while (provincesFields.hasNext()) {
- String fieldName = (String) provincesFields.next();
- String province;
- if("name".equals(fieldName)){
- province = fieldName +":"+ provinceElements.path(fieldName).asText();
- }else{
- province = fieldName +":"+ provinceElements.path(fieldName).asInt();
- }
- System.out.println(province);
- }
- }
- }
- }
程序运行打印结果:
- JsonNodeType : MISSING
- country_id:China
- name:Shanxi
- population:37751200
- name:ZheJiang
- population:55080000
3.Stream处理Json
- package com.jackson.json.streaming;
- import java.io.File;
- import java.io.FileWriter;
- import java.io.Exception;
- import com.fasterxml.jackson.core.JsonFactory;
- import com.fasterxml.jackson.core.JsonGenerator;
- public class StreamGeneratorJson {
- public static void main(String[] args) throws Exception {
- JsonFactory factory = new JsonFactory();
- //从JsonFactory创建一个JsonGenerator生成器的实例
- JsonGenerator generator = factory.createGenerator(new FileWriter(new File("country3.json")));
- generator.writeStartObject();
- generator.writeFieldName("country_id");
- generator.writeString("China");
- generator.writeFieldName("provinces");
- generator.writeStartArray();
- generator.writeStartObject();
- generator.writeStringField("name", "Shanxi");
- generator.writeNumberField("population", 33750000);
- generator.writeEndObject();
- generator.writeEndArray();
- generator.writeEndObject();
- generator.close();
- }
- }
程序运行后生成country3.json文件内容:
- {"country_id":"China","provinces":[{"name":"Shanxi","population":33750000}]}
现在adgcountry3.json,我们用Streaming API的方式来解析上面的Json,并查找json中population的值。
- package com.jackson.json.streaming;
- import java.io.File;
- import java.io.IOException;
- import com.fasterxml.jackson.core.JsonFactory;
- import com.fasterxml.jackson.core.JsonParseException;
- import com.fasterxml.jackson.core.JsonParser;
- import com.fasterxml.jackson.core.JsonToken;
- /*Jackson API提供了token对每个Json对象,例如,Json开始符号“{”是token指向的第一个解析的对象,
- key:value键值对是另一个单独的对象。这个API很强大,但也需要编写大量代码。不推荐使用,平时更多的是使用DataBinding和TreeModel来处理json
- */
- public class StreamParserJson {
- public static void main(String[] args) throws JsonParseException,
- IOException {
- JsonFactory factory = new JsonFactory();
- // 从JsonFactory创建JsonParser解析器的实例
- JsonParser parser = factory.createParser(new File("country3.json"));
- while (!parser.isClosed()) {
- // 得到一个token,第一次遍历时,token指向json文件中第一个符号"{"
- JsonToken token = parser.nextToken();
- if (token == null) {
- break;
- }
- // 我们只查找 country3.json中的"population"字段的值,能体现解析的流程就可以了
- // 当key是provinces时,我们进入provinces,查找population
- if (JsonToken.FIELD_NAME.equals(token)
- && "provinces".equals(parser.getCurrentName())) {
- token = parser.nextToken();
- if (!JsonToken.START_ARRAY.equals(token)) {
- break;
- }
- // 此时,token指向的应该是"{"
- token = parser.nextToken();
- if (!JsonToken.START_OBJECT.equals(token)) {
- break;
- }
- while (true) {
- token = parser.nextToken();
- if (token == null) {
- break;
- }
- if (JsonToken.FIELD_NAME.equals(token)
- && "population".equals(parser.getCurrentName())) {
- token = parser.nextToken();
- System.out.println(parser.getCurrentName() + " : "
- + parser.getIntValue());
- }
- }
- }
- }
- }
- }
- population : 33750000
总结
jackson java对象和json对象的互相转换的更多相关文章
- java对象与json对象间的相互转换
工程中所需的jar包,因为在网上不太好找,所以我将它放到我的网盘里了,如有需要随便下载. 点击下载 1.简单的解析json字符串 首先将json字符串转换为json对象,然后再解析json对象,过程如 ...
- java对象和json对象之间互相转换
import java.util.ArrayList;import java.util.Collection;import java.util.Iterator;import java.util.Li ...
- java对象与json对象之间的转换
jar包:import net.sf.json.JSONObject; 1.解析json字符串 将json字符串转换为json对象,然后再解析json对象:.JSONObjectjsonObject ...
- <摘录>Gson对Java嵌套对象和JSON字符串之间的转换
JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式,具有良好的跨平台特性.近几年来已经和XML一样成为C/S架构中广泛采用的数据格式.有关JSON的更多知识, ...
- java对象与json字符串的互相转换
java对象与json字符串的互相转换 1.采用 net.sf.json.JSONObject maven依赖包: <dependency> <groupId>net.sf.j ...
- JavaScript对象、JSON对象、JSON字符串的区别
一.首先看下什么是JSON JSON:JavaScript Object Natation,JavaScript对象的表现形式,已经发展成一种轻量级的数据交换格式. JavaScript对象的表现形式 ...
- 使用Google的Gson实现对象和json字符串之间的转换
使用Google的Gson实现对象和json字符串之间的转换 需要gson.jar 1.JsonUtil.java package com.snail.json; import java.lang.r ...
- JSON对象与JSON字符串之间的转换
JSON引用包:import net.sf.json 1.JSON字符串转JSON对象(例子中的AgencyExpand是java对象) JSONObject json = JSONObject.f ...
- fastjson: json对象,json对象数组,javabean对象,json字符串之间的相互转化
fastjson: json对象,json对象数组,javabean对象,json字符串之间的相互转化 在开发过程中,经常需要和前端交互数据,数据交互的格式都是JSON,在此过程中免不了json字符串 ...
- 一种简单,轻量,灵活的C#对象转Json对象的方案(续)
本文参考资料 一种简单,轻量,灵活的C#对象转Json对象的方案 [源码]Literacy 快速反射读写对象属性,字段 一段废话 之前我已经介绍了这个方案的名称为JsonBuilder,这套方案最大的 ...
随机推荐
- nginx 和 php超时设置
nginx.conf --- http节: keepalive_timeout 600; #客户端浏览器超时时间fastcgi_connect_timeout 600; #php-fpm连接超时时间 ...
- 机器学习进阶-图像金字塔与轮廓检测-轮廓检测 1.cv2.cvtColor(图像颜色转换) 2.cv2.findContours(找出图像的轮廓) 3.cv2.drawContours(画出图像轮廓) 4.cv2.contourArea(轮廓面积) 5.cv2.arcLength(轮廓周长) 6.cv2.aprroxPloyDP(获得轮廓近似) 7.cv2.boudingrect(外接圆)..
1. cv2.cvtcolor(img, cv2.COLOR_BGR2GRAY) # 将彩色图转换为灰度图 参数说明: img表示输入的图片, cv2.COLOR_BGR2GRAY表示颜色的变换形式 ...
- mybatis初识
mybatis采用弱连接,在一定程度上集中管理了sql的语句编写,又实现了自动映射bean. 此处以最基础的mybatis连接为例: 引入jar包: mybatis-3.4.5.jar ojdbc-6 ...
- ssm框架之配置日志系统打印到控制台与指定文件
前提: 0:ssm框架已经搭建并且成功运行 1.maven环境配置成功 2.tomcat配置成功,并且配置本机的tomcat环境变量 内容: 0.导入所需要的jar包 <!-- 配置log4j日 ...
- 用waitpid函数回收进程
waitpid函数:作用同wait,但可指定pid进程清理,可以不阻塞. 原型:pid_t waitpid(pid_t pid, int *status, in options); 返回值:成功时返回 ...
- Dictionary,hashtable, stl:map有什么异同?
相同点:字典和map都是泛型,而hashtable不是泛型. 不同点:三者算法都不相同 Hashtable,看名字能想到,它是采用传统的哈希算法:探测散列算法,而字典则采用的是散列拉链算法,效率较高, ...
- byte类型的127+1=-128?
public class Test2 { public void add(Byte b) { b = b++; } public void test() { Byte a = 127; Byte ...
- mysql decimal
可能做程序的人都知道,float类型是可以存浮点数(即小数类型),但是float有个坏处,当你给定的数据是整数的时候,那么它就以整数给你处理. 这样我们在存取货币值的时候自然遇到问题,我的defaul ...
- Haskell语言学习笔记(78)fix
fix 函数 fix 是一个在 Data.Function 模块中定义的函数,它是对于递归的封装,可以用于定义不动点函数. fix :: (a -> a) -> a fix f = let ...
- 遍历DOM树,each()遍历
在<jQuery教程/理解选取更新范围>一节中,我们知道:当选择器返回了多个元素时,可以使用一个方法来更新所有的元素,不再需要使用循环. 然后有的时候需要遍历元素,怎么办? 使用each( ...