Json工具Demo(二)
上篇文章Json工具Demo(一) 说了一些Json和Jackson框架的基本知识,以及Demo中需要用到的基本类。这篇文章主要写下json和java对象之间相互转换的工具类JacksonUtil.java和测试类Main.java。
如果是List<User>
或者Map<String, User>
使用toJsonWithRoot方法转换成json串,当用jsonToBeanByTypeReferenceWithRoot方法转换成Java Bean时,会导致该Bean为null。因此,需要使用一个新的类,如UserList或者UserMap类来实现,就可以避免这个问题。
使用下面的代码需要的依赖是:
<dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-core</artifactId><version>2.8.5</version></dependency><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.8.5</version></dependency><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-annotations</artifactId><version>2.8.5</version></dependency>
JacksonUtil
JacksonUtil.java
package org.fan.learn.utils;import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;import java.io.IOException;
import java.util.Locale;
import java.util.Map;/*** Created by fan on 15-11-18.*/
public class JacksonUtil {private static final Logger LOGGER = LoggerFactory.getLogger(JacksonUtil.class);private static ObjectMapper mapper;public static synchronized ObjectMapper getMapperInstance(boolean createNew) {if (createNew) {return new ObjectMapper();} else if (mapper == null) {mapper = new ObjectMapper();//对象属性按字母顺序排列mapper.configure(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY, true);//在反序列化时,如果类中没有对应的属性,不抛出JsonMappingException异常mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);//序列化时,如果对象的某属性为null,生成Json字符串时不包含这个null属性mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);mapper.setLocale(Locale.CHINA);}return mapper;}/*** 将java对象转换为字符串* @param param java 对象* @return json字符串*/public static String toJson(Object param){try {ObjectMapper objectMapper = JacksonUtil.getMapperInstance(false);objectMapper.configure(SerializationFeature.WRAP_ROOT_VALUE, false);String dataJson = objectMapper.writeValueAsString(param);return dataJson;}catch (Exception e){LOGGER.warn("toJson",e);}return null;}/*** 将java对象为字符串 类名作为json的顶级属性* @param param java 对象* @returnjson字符串*/public static String toJsonWithRoot(Object param){try {ObjectMapper objectMapper = JacksonUtil.getMapperInstance(false);objectMapper.configure(SerializationFeature.WRAP_ROOT_VALUE, true);String dataJson = objectMapper.writeValueAsString(param);return dataJson;}catch (Exception e){LOGGER.warn("toJson",e);}return null;}/*** 将json字符串转换为java对象* @param json json字符串* @param cls java对象类型* @param <T>* @return*/public static <T> T jsonToBean(String json, Class<T> cls){try {ObjectMapper objectMapper = JacksonUtil.getMapperInstance(false);objectMapper.configure(DeserializationFeature.UNWRAP_ROOT_VALUE,false);return objectMapper.readValue(json, cls);} catch (Exception e) {LOGGER.warn("jsonToBean",e);return null;}}/*** 将json字符串转换为java对象 ,解析字符串时,将类的名字或者别名作为顶级属性来解析* @param json json字符串* @param cls java对象类型* @param <T>* @return*/public static <T> T jsonToBeanWithRoot(String json, Class<T> cls){try {ObjectMapper objectMapper = JacksonUtil.getMapperInstance(false);objectMapper.configure(DeserializationFeature.UNWRAP_ROOT_VALUE, true);return objectMapper.readValue(json, cls);} catch (Exception e) {LOGGER.warn("jsonToBean",e);return null;}}/*** 将json字符串转换为java对象* @param json json字符串* @param typeReference 复杂的java对象类型* @param <T>* @return*/public static <T> T jsonToBeanByTypeReference(String json, TypeReference typeReference){try {ObjectMapper objectMapper = JacksonUtil.getMapperInstance(false);objectMapper.configure(DeserializationFeature.UNWRAP_ROOT_VALUE,false);return objectMapper.readValue(json, typeReference);} catch (Exception e) {LOGGER.warn("jsonToBean",e);return null;}}/*** 将json字符串转换为java对象,解析字符串时,将类的名字或者别名作为顶级属性来解析* @param json json字符串* @param typeReference 复杂的java对象类型* @param <T>* @return*/public static <T> T jsonToBeanByTypeReferenceWithRoot(String json, TypeReference typeReference){try {ObjectMapper objectMapper = JacksonUtil.getMapperInstance(false);objectMapper.configure(DeserializationFeature.UNWRAP_ROOT_VALUE,true);return objectMapper.readValue(json, typeReference);} catch (Exception e) {LOGGER.warn("jsonToBean",e);return null;}}/*** 从json字符串中读取出指定的节点** @param json* @param key* @return* @throws JsonProcessingException* @throws IOException*/public static JsonNode getValueFromJson(String json, String key) {ObjectMapper objectMapper = JacksonUtil.getMapperInstance(false);objectMapper.configure(DeserializationFeature.UNWRAP_ROOT_VALUE,false);JsonNode node = null;try {node = objectMapper.readTree(json);return node.get(key);} catch (IOException e) {LOGGER.warn("getValueFromJson",e);return null;}}
}
Main测试
package org.fan.learn.json;import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonNode;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.fan.learn.utils.JacksonUtil;import java.util.List;
import java.util.Map;/*** Created by fan on 15-11-18.*/
public class Main {public static void main(String[] args) {List<User> userList = Lists.newArrayList();String[] phone = {"15888888888", "15222222222"};Birthday birthday = new Birthday(2000,8,8);User user = new User("宝宝", -26, phone, birthday, true);User user1 = new User("fan", 25, phone, birthday, false);
/* User user = new User();user.setName("fan");user.setAge(26);User user1 = new User();user1.setName("li");user1.setAge(25);*/userList.add(user);userList.add(user1);Map<String, User> userMap = Maps.newHashMap();userMap.put("user1", user);userMap.put("user2", user1);//会调用get方法String userString = JacksonUtil.toJson(user);//会调用无参构造函数,set方法User userJson = JacksonUtil.jsonToBean(userString, User.class);Map<String,String> userJsonMap = JacksonUtil.jsonToBean(userString, Map.class);System.out.println(userJsonMap);JsonNode name = JacksonUtil.getValueFromJson(userString, "NAME");JsonNode age = JacksonUtil.getValueFromJson(userString, "AGE");JsonNode phoneNode = JacksonUtil.getValueFromJson(userString, "PHONE");JsonNode birthdayNode = JacksonUtil.getValueFromJson(userString, "BIRTHDAY");JsonNode maleNode = JacksonUtil.getValueFromJson(userString, "MALE");String nameStr = name.toString();int ageInt = age.intValue();//List<String> phoneArr = phoneNode.findValuesAsText("PHONE");String[] phoneArr = new String[phoneNode.size()];for (int i = 0; i < phoneNode.size(); i++) {phoneArr[i] = phoneNode.get(i).toString();}Birthday birthdayObj = new Birthday();//会分别调用Birthday的3个setter方法birthdayObj.setYear(birthdayNode.get("year").intValue());birthdayObj.setMonth(birthdayNode.get("month").intValue());birthdayObj.setDay(birthdayNode.get("day").intValue());boolean male = maleNode.booleanValue();String userString2 = JacksonUtil.toJsonWithRoot(user);//使用这种内部数据将会是nullUser userJson2_1 = JacksonUtil.jsonToBean(userString2, User.class);User userJson2_2 = JacksonUtil.jsonToBeanWithRoot(userString2, User.class);String userListString = JacksonUtil.toJson(userList);List<User> userListJson = JacksonUtil.jsonToBeanByTypeReference(userListString,new TypeReference<List<User>>(){});String userListStringRoot = JacksonUtil.toJsonWithRoot(userList);//这种使用方法,得到的userListJsonRoot是nullList<User> userListJsonRoot = JacksonUtil.jsonToBeanByTypeReferenceWithRoot(userListStringRoot,new TypeReference<List<User>>(){});//使用UserList类UserList userListClass = new UserList();userListClass.setUserList(userList);String userListClassString = JacksonUtil.toJson(userListClass);UserList userListClassJason = JacksonUtil.jsonToBean(userListClassString, UserList.class);String userListClassStringRoot = JacksonUtil.toJsonWithRoot(userListClass);UserList userListClassJasonRoot = JacksonUtil.jsonToBeanWithRoot(userListClassStringRoot, UserList.class);String userMapString = JacksonUtil.toJson(userMap);Map<String, User> userMapJson = JacksonUtil.jsonToBeanByTypeReference(userMapString,new TypeReference<Map<String, User>>(){});String userMapStringRoot = JacksonUtil.toJsonWithRoot(userMap);//这种使用方法,得到的userMapJsonRoot是nullMap<String, User> userMapJsonRoot = JacksonUtil.jsonToBeanByTypeReferenceWithRoot(userMapStringRoot,new TypeReference<Map<String, User>>(){});//使用UserMap类UserMap userMapClass = new UserMap();userMapClass.setUserMap(userMap);String userMapClassString = JacksonUtil.toJson(userMapClass);UserMap userMapClassJson = JacksonUtil.jsonToBean(userMapClassString, UserMap.class);String userMapClassStringRoot = JacksonUtil.toJsonWithRoot(userMapClass);UserMap userMapClassJsonRoot = JacksonUtil.jsonToBeanWithRoot(userMapClassStringRoot, UserMap.class);}
}
代码分析及运行结果
1 关于Google guava
google guava所包含的内容远不止在Demo中使用的样子。由于本篇博文的重点在json,这里对guava不详细说明,给出链接资料:http://ifeve.com/google-guava/
在java 7之前,在构造新的泛型集合时要反复重新声明泛型。如下所示:
List<User> userList = new ArrayList<User>();
这样写太繁琐,因此guava推出了能够推断泛型的静态工厂方法:
List<User> userList = Lists.newArrayList();
2 json与java对象之间的转换
java对象转换成json,使用JacksonUtil.toJson
,这个方法调用过程中会调用java bean的get方法。如果java bean中不存在get方法也不影响转换的过程。
json转换成java对象,使用JacksonUtil.jsonToBean
, 这个方法调用过程中首先会调用java bean的默认构造函数。如果java bean没有其他构造函数的话,编译器会自动添加默认构造函数。总之,默认构造函数必须要有,否则会报错。由json转java bean时也会调用setter方法。如果java bean中不存在set方法也不影响转换的过程。
//会调用get方法String userString = JacksonUtil.toJson(user);//会调用无参构造函数,set方法User userJson = JacksonUtil.jsonToBean(userString, User.class);Map<String,String> userJsonMap = JacksonUtil.jsonToBean(userString, Map.class);
为了检验默认构造方法,setter,getter方法的调用,在POJO中有打印信息。
上面代码的执行结果,如下所示。
userString的内容:
{"AGE":-26,"BIRTHDAY":{"day":8,"month":8,"year":2000},"MALE":true,"NAME":"宝宝","PHONE":["15888888888","15222222222"]}
从上面可以看到,键值对的排序都是按照字母顺序排序的,而且还是大写的。原因如下:
mapper = new ObjectMapper();//对象属性按字母顺序排列mapper.configure(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY, true);
在创建POJO User.java时使用了注解。
@JsonProperty("NAME")private String name;@JsonProperty("AGE")private int age;@JsonProperty("PHONE")private String[] phone;@JsonProperty("BIRTHDAY")private Birthday birthday;@JsonProperty("MALE")private boolean male;
userJson对象的内容
userJsonMap的内容
3 从json字符串中直接得到某一属性的值
JsonNode name = JacksonUtil.getValueFromJson(userString, "NAME");JsonNode age = JacksonUtil.getValueFromJson(userString, "AGE");JsonNode phoneNode = JacksonUtil.getValueFromJson(userString, "PHONE");JsonNode birthdayNode = JacksonUtil.getValueFromJson(userString, "BIRTHDAY");JsonNode maleNode = JacksonUtil.getValueFromJson(userString, "MALE");String nameStr = name.toString();int ageInt = age.intValue();//List<String> phoneArr = phoneNode.findValuesAsText("PHONE");String[] phoneArr = new String[phoneNode.size()];for (int i = 0; i < phoneNode.size(); i++) {phoneArr[i] = phoneNode.get(i).toString();}Birthday birthdayObj = new Birthday();//会分别调用Birthday的3个setter方法birthdayObj.setYear(birthdayNode.get("year").intValue());birthdayObj.setMonth(birthdayNode.get("month").intValue());birthdayObj.setDay(birthdayNode.get("day").intValue());boolean male = maleNode.booleanValue();
4 在json字符串中显示根的名字
String userString2 = JacksonUtil.toJsonWithRoot(user);//使用这种内部数据将会是nullUser userJson2_1 = JacksonUtil.jsonToBean(userString2, User.class);User userJson2_2 = JacksonUtil.jsonToBeanWithRoot(userString2, User.class);
userString2的内容如下所示:
{"FAN":{"AGE":-26,"BIRTHDAY":{"day":8,"month":8,"year":2000},"MALE":true,"NAME":"宝宝","PHONE":["15888888888","15222222222"]}}
之所以会显示头时因为,有注解:
@JsonRootName(value = "FAN")
@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY)
public class User {
}
userJson2_1和userJson2_2的内容如下:
userJson2_1是null的,因为json串是有root的,重新解析时也要使用有root的。
5 关于集合List
String userListString = JacksonUtil.toJson(userList);List<User> userListJson = JacksonUtil.jsonToBeanByTypeReference(userListString,new TypeReference<List<User>>(){});String userListStringRoot = JacksonUtil.toJsonWithRoot(userList);//这种使用方法,得到的userListJsonRoot是nullList<User> userListJsonRoot = JacksonUtil.jsonToBeanByTypeReferenceWithRoot(userListStringRoot,new TypeReference<List<User>>(){});
userListString的内容如下:
[{"AGE":-26,"BIRTHDAY":{"day":8,"month":8,"year":2000},"MALE":true,"NAME":"宝宝","PHONE":["15888888888","15222222222"]},{"AGE":25,"BIRTHDAY":{"day":8,"month":8,"year":2000},"MALE":false,"NAME":"fan","PHONE":["15888888888","15222222222"]}]
userListJson的内容:
但是有了root之后就有问题了:
因此对于集合最好不要使用jsonToBeanByTypeReference这种方式来将json转换成java bean。当遇到集合时,最好能新建一个集合的类。
//使用UserList类UserList userListClass = new UserList();userListClass.setUserList(userList);String userListClassString = JacksonUtil.toJson(userListClass);UserList userListClassJason = JacksonUtil.jsonToBean(userListClassString, UserList.class);String userListClassStringRoot = JacksonUtil.toJsonWithRoot(userListClass);UserList userListClassJasonRoot = JacksonUtil.jsonToBeanWithRoot(userListClassStringRoot, UserList.class);
userListClassString的内容如下:
{"USERLIST":[{"AGE":-26,"BIRTHDAY":{"day":8,"month":8,"year":2000},"MALE":true,"NAME":"宝宝","PHONE":["15888888888","15222222222"]},{"AGE":25,"BIRTHDAY":{"day":8,"month":8,"year":2000},"MALE":false,"NAME":"fan","PHONE":["15888888888","15222222222"]}]}
userListClassStringRoot的内容如下:
{"AAAAA":{"USERLIST":[{"AGE":-26,"BIRTHDAY":{"day":8,"month":8,"year":2000},"MALE":true,"NAME":"宝宝","PHONE":["15888888888","15222222222"]},{"AGE":25,"BIRTHDAY":{"day":8,"month":8,"year":2000},"MALE":false,"NAME":"fan","PHONE":["15888888888","15222222222"]}]}}
6 (1)map的情况跟list类似
String userMapString = JacksonUtil.toJson(userMap);Map<String, User> userMapJson = JacksonUtil.jsonToBeanByTypeReference(userMapString,new TypeReference<Map<String, User>>(){});String userMapStringRoot = JacksonUtil.toJsonWithRoot(userMap);//这种使用方法,得到的userMapJsonRoot是nullMap<String, User> userMapJsonRoot = JacksonUtil.jsonToBeanByTypeReferenceWithRoot(userMapStringRoot,new TypeReference<Map<String, User>>(){});
userMapString的内容:
{"user2":{"AGE":25,"BIRTHDAY":{"day":8,"month":8,"year":2000},"MALE":false,"NAME":"fan","PHONE":["15888888888","15222222222"]},"user1":{"AGE":-26,"BIRTHDAY":{"day":8,"month":8,"year":2000},"MALE":true,"NAME":"宝宝","PHONE":["15888888888","15222222222"]}}
userMapStringRoot的内容:
{"HashMap":{"user2":{"AGE":25,"BIRTHDAY":{"day":8,"month":8,"year":2000},"MALE":false,"NAME":"fan","PHONE":["15888888888","15222222222"]},"user1":{"AGE":-26,"BIRTHDAY":{"day":8,"month":8,"year":2000},"MALE":true,"NAME":"宝宝","PHONE":["15888888888","15222222222"]}}}
(2)
//使用UserMap类UserMap userMapClass = new UserMap();userMapClass.setUserMap(userMap);String userMapClassString = JacksonUtil.toJson(userMapClass);UserMap userMapClassJson = JacksonUtil.jsonToBean(userMapClassString, UserMap.class);String userMapClassStringRoot = JacksonUtil.toJsonWithRoot(userMapClass);UserMap userMapClassJsonRoot = JacksonUtil.jsonToBeanWithRoot(userMapClassStringRoot, UserMap.class);
userMapClassString的内容:
{"USERMAP":{"user2":{"AGE":25,"BIRTHDAY":{"day":8,"month":8,"year":2000},"MALE":false,"NAME":"fan","PHONE":["15888888888","15222222222"]},"user1":{"AGE":-26,"BIRTHDAY":{"day":8,"month":8,"year":2000},"MALE":true,"NAME":"宝宝","PHONE":["15888888888","15222222222"]}}}
userMapClassStringRoot的内容:
{"BB":{"USERMAP":{"user2":{"AGE":25,"BIRTHDAY":{"day":8,"month":8,"year":2000},"MALE":false,"NAME":"fan","PHONE":["15888888888","15222222222"]},"user1":{"AGE":-26,"BIRTHDAY":{"day":8,"month":8,"year":2000},"MALE":true,"NAME":"宝宝","PHONE":["15888888888","15222222222"]}}}}
Json工具Demo(二)相关推荐
- DEMO程序连接到域控服务器( C#开发AD域控自动工具之二)
搭建一个开发环境( C#开发AD域控自动工具之一) DEMO程序连接到域控服务器( C#开发AD域控自动工具之二) DEMO程序 创建一个用户( C#开发AD域控自动工具之三) 第一个需求,登陆名称绑 ...
- Code片段 : .properties属性文件操作工具类 JSON工具类
摘要: 原创出处:www.bysocket.com 泥瓦匠BYSocket 希望转载,保留摘要,谢谢! "贵专" - 泥瓦匠 一.java.util.Properties API ...
- JS XML在线格式化、压缩、校验、XML转JSON工具-toolfk程序员工具网
本文要推荐的[ToolFk]是一款程序员经常使用的线上免费测试工具箱,ToolFk 特色是专注于程序员日常的开发工具,不用安装任何软件,只要把内容贴上按一个执行按钮,就能获取到想要的内容结果.Tool ...
- Unity实用小工具或脚本——读写Json工具
一.前言 在Unity中读写Json文件已经有非常好的工具,可以将Json文件和结构体数据进行相互转换,如图1所示,在Unity Asset Store中搜JSON.NET可以找到该插件, ...
- 9 个爱不释手的 JSON 工具
点击关注上方"视学算法",设为"置顶或星标",第一时间送达技术干货. 众所周知,JSON让开发人员易于使用,又让机器易于解析和生成. JSON吸引了工具构建者的 ...
- java实用工具类——java处理对象转json工具类
一.引言 json字符串现在是项目中很常用的了,尤其是在写接口返回数据一般都是json格式的.小编最近在看项目中,发现有多处地方用到了java对象转json,但是引用的jar包都是不统一的. 常见的有 ...
- Uber AVS 自动驾驶可视化工具(二)XVIZ之Overview
Uber AVS 自动驾驶可视化工具 (二)XVIZ之Overview Overview Introduction Main Features XVIZ Protocol Specification ...
- SpringBoot的JSON工具类(java),用于前后端分离
简介 JSON(JavaScript Object Notation, JS对象简谱)是一种轻量级的数据交换格式.它基于 ECMAScript(European Computer Manufactur ...
- JSON基础及Java的JSON工具类
一.JSON基础 定义:JSON(JavaScript Object Notation, JS 对象简谱) 是一种轻量级的数据交换格式.它基于 ECMAScript (欧洲计算机协会制定的js规范)的 ...
最新文章
- Java--语言基础
- 删除文件夹中包含的子文件夹及文件
- Struts2中的ActionContext
- linux crontab定时任务详解
- 求到所有房子距离和最小的新房子
- java重载中this的作用_Java2:构造方法、方法重载和this关键字
- 如何在通达信中展现漂亮的港资持股曲线
- 我是明晃晃的开端(2017/4/17)
- 如何写一个脚本(附送一个脚本)
- 运动耳机什么牌子好、这五款是最值得推荐的运动耳机
- Windows各版本官方原版系统下载
- 新型冠状病毒传染模型SI、SIS、SIR、SEIR
- 回头再说说音乐--江湖笑 周华健
- 2021起重机作业 (Q)Q3起重机械指挥模拟考试题库及软件
- 机器视觉照明技术Machine Vision Light Technique
- Grating Period and Grating Constant(光栅周期与光栅常数)
- 功能强大的发卡网源码+支付接口超多
- SecureCRT常用命令分享 SecureCRT命令大全
- XRD物相检索的过程
- java redis管道_Redis的Java客户端Jedis的八种调用方式(事务、管道、分布式)介绍
热门文章
- 最新版Nginx安装教程来了,快来看看
- Leetcode-1598. 文件夹操作日志搜集器
- 跳转到wps查看文件
- 将字符串“I am a student.”逆序输出为“student. a am I”
- php中的 notice,php中对于NOTICE的问题排查,该注意什么?
- Lora技术- 码片/码元/数据速率以及空中时间计算
- 基于python的狗屁不通观后感生成器 2.0
- 一封来自大佬的密信待查收
- Lr预设(手机+电脑):复古巧克力色电影灯室棕褐色摄影Lightroom滤镜调色预设
- 使用word文件制作ftl模板文件总结(靠谱)