一、Gson
Gson提供了十几个fromJson()和toJson()方法,前者实现反序列化,后者实现了序列化。尽量要2.4版本以上的,因为alternate需要2.4版本。下面会介绍alternate。
<!-- 这里需要引入Gson的依赖 -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.6</version>
</dependency>
1.json对象的处理
(1)json串中key名与实体类名称一致
此种情况为最简单的情况,代码如下
//一个没有层级关系的普通的json对象.
{
"name": "张三",
"age": "22",
"email": "1432299080@qq.com",
"sex": "男",
"height": "178"
}
//一个User实体类,名称与json串中的名称完全一样.
@Data
public class User {
private String name;
private String age;
private String email;
private String sex;
private String height;
}
//测试方法
public class gsonTest {
public static void main(String[] args) {
//定义一个json对象格式的字符串
String jsonStr = "{\n" +
" \"name\": \"张三\",\n" +
" \"age\": \"22\",\n" +
" \"email\": \"1432299080@qq.com\",\n" +
" \"sex\": \"男\",\n" +
" \"height\": \"178\"\n" +
"}";
//使用gson的fromJson方法将字符串转化成对象
Gson gson = new Gson();
User user = gson.fromJson(jsonStr, User.class);
//User(name=张三, age=22, email=1432299080@qq.com, sex=男, height=178)
System.out.println(user);
}
}
(2)json串中key名与实体类名称不一致
如果继续执行上面的测试代码会发现最终输出的结果为:User(name=null, age=null, email=null, sex=null, height=null) . 处理办法为:使用SerializedName注解的value属性来处理,value:别名
//准备json串
{
"t_name": "张三",
"t_age": "22",
"t_email": "1432299080@qq.com",
"t_sex": "男",
"t_height": "178"
}
//准备实体类
@Data
public class User {
@SerializedName(value = "t_name")
private String name;
@SerializedName(value = "t_age")
private String age;
@SerializedName(value = "t_email")
private String email;
@SerializedName(value = "t_sex")
private String sex;
@SerializedName(value = "t_height")
private String height;
}
//测试类
public class gsonTest {
public static void main(String[] args) {
//定义一个json对象格式的字符串
String jsonStr = "{\n" +
" \"t_name\": \"张三\",\n" +
" \"t_age\": \"22\",\n" +
" \"t_email\": \"1432299080@qq.com\",\n" +
" \"t_sex\": \"男\",\n" +
" \"t_height\": \"178\"\n" +
"}";
//使用gson的fromJson方法将字符串转化成对象
Gson gson = new Gson();
User user = gson.fromJson(jsonStr, User.class);
//User(name=张三, age=22, email=1432299080@qq.com, sex=男, height=178)
System.out.println(user);
}
}
(3)好多家接口同时传递过来不同名称的json串
现在想要程序可以同时识别s和t开头的key。
处理办法:只需要修改下实体类即可,使用@SerializedName的value和alternate 注解来处理,这里要注意value属性指定的就是类中的名字,而alternate 属性是接收一个String数组。
//json串
{
"s_name": "张三",
"s_age": "22",
"s_email": "1432299080@qq.com",
"s_sex": "男",
"s_height": "178"
}
{
"t_name": "张三",
"t_age": "22",
"t_email": "1432299080@qq.com",
"t_sex": "男",
"t_height": "178"
}
//实体类
@Data
public class User {
//alternate需要2.4版本
@SerializedName(value = "name",alternate = {"t_name","s_name"})
private String name;
@SerializedName(value = "age",alternate = {"t_age","s_age"})
private String age;
@SerializedName(value = "email",alternate = {"t_email","s_email"})
private String email;
@SerializedName(value = "sex",alternate = {"t_sex","s_sex"})
private String sex;
@SerializedName(value = "height",alternate = {"t_height","s_height"})
private String height;
}
//测试类
public class gsonTest {
public static void main(String[] args) {
//定义一个json对象格式的字符串
String jsonStr = "{\n" +
" \"t_name\": \"张三\",\n" +
" \"t_age\": \"22\",\n" +
" \"t_email\": \"1432299080@qq.com\",\n" +
" \"t_sex\": \"男\",\n" +
" \"t_height\": \"178\"\n" +
"}";
//使用gson的fromJson方法将字符串转化成对象
Gson gson = new Gson();
User user = gson.fromJson(jsonStr, User.class);
//User(name=张三, age=22, email=1432299080@qq.com, sex=男, height=178)
System.out.println(user);
//定义一个json对象格式的字符串
String jsonStr2 = "{\n" +
" \"s_name\": \"张三\",\n" +
" \"s_age\": \"22\",\n" +
" \"s_email\": \"1432299080@qq.com\",\n" +
" \"s_sex\": \"男\",\n" +
" \"s_height\": \"178\"\n" +
"}";
//使用gson的fromJson方法将字符串转化成对象
Gson gson2 = new Gson();
User user2 = gson.fromJson(jsonStr2, User.class);
//User(name=张三, age=22, email=1432299080@qq.com, sex=男, height=178)
System.out.println(user2);
}
}
2.json数组的处理
首先需要准备一个没有层级的json对象组成的json数组.
使用gson提供的数据类型转换器TypeToken来处理,这里要提一下,它可以支持各种数据集合类型转换.如果确定了数组中只有一个json对象,那么可以直接使用上面的fromJson方法并返回User对象
//json串
[
{
"t_name": "张三",
"t_age": "22",
"t_sex": "男",
"t_email": "12345677890@qq.com",
"t_height": "178"
},
{
"t_name": "小红",
"t_age": "22",
"t_sex": "女",
"t_email": "1987654321@qq.com",
"t_height": "165"
}
]
//实体类
@Data
public class User {
@SerializedName(value = "name",alternate = {"t_name","s_name"})
private String name;
@SerializedName(value = "age",alternate = {"t_age","s_age"})
private String age;
@SerializedName(value = "email",alternate = {"t_email","s_email"})
private String email;
@SerializedName(value = "sex",alternate = {"t_sex","s_sex"})
private String sex;
@SerializedName(value = "height",alternate = {"t_height","s_height"})
private String height;
}
//测试类
public class gsonTest {
public static void main(String[] args) {
String jsonStr = "[\n" +
" {\n" +
" \"t_name\": \"张三\",\n" +
" \"t_age\": \"22\",\n" +
" \"t_sex\": \"男\",\n" +
" \"t_email\": \"12345677890@qq.com\",\n" +
" \"t_height\": \"178\"\n" +
" },\n" +
" {\n" +
" \"t_name\": \"小红\",\n" +
" \"t_age\": \"22\",\n" +
" \"t_sex\": \"女\",\n" +
" \"t_email\": \"1987654321@qq.com\",\n" +
" \"t_height\": \"165\"\n" +
" }\n" +
"]";
Gson gson = new Gson();
Type type = new TypeToken<List<User>>() {}.getType();
List<User> userList = gson.fromJson(jsonStr, type);
//[User(name=张三, age=22, email=12345677890@qq.com, sex=男, height=178),
// User(name=小红, age=22, email=1987654321@qq.com, sex=女, height=165)]
System.out.println(userList);
}
}
3.json对象套json数组的处理
(1)json对象里带json数组的情况处理
一般我们在开发的过程中,数据往往都没有上面那么整齐,那么针对整体是一个json对象,里面有json数组的情况该如何处理呢?
//准备一个特殊的json串,json对象中包含json数组且有且仅有一个数据头
{
"user": [
{
"t_name": "张三",
"t_age": "22",
"t_sex": "男",
"t_email": "12345677890@qq.com",
"t_height": "178"
},
{
"t_name": "小红",
"t_age": "22",
"t_sex": "女",
"t_email": "1987654321@qq.com",
"t_height": "165"
}
]
}
//实体类
@Data
public class User {
@SerializedName(value = "name",alternate = {"t_name","s_name"})
private String name;
@SerializedName(value = "age",alternate = {"t_age","s_age"})
private String age;
@SerializedName(value = "email",alternate = {"t_email","s_email"})
private String email;
@SerializedName(value = "sex",alternate = {"t_sex","s_sex"})
private String sex;
@SerializedName(value = "height",alternate = {"t_height","s_height"})
private String height;
}
//测试类
public static void main(String[] args) {
String jsonStr = "{\n" +
" \"user\": [\n" +
" {\n" +
" \"t_name\": \"张三\",\n" +
" \"t_age\": \"22\",\n" +
" \"t_sex\": \"男\",\n" +
" \"t_email\": \"12345677890@qq.com\",\n" +
" \"t_height\": \"178\"\n" +
" },\n" +
" {\n" +
" \"t_name\": \"小红\",\n" +
" \"t_age\": \"22\",\n" +
" \"t_sex\": \"女\",\n" +
" \"t_email\": \"1987654321@qq.com\",\n" +
" \"t_height\": \"165\"\n" +
" }\n" +
" ]\n" +
"}";
//先转换成json对象
JsonObject jsonObject = new JsonParser().parse(jsonStr).getAsJsonObject();
//再获取数据头并转换成json数组
JsonArray jsonArray = jsonObject.getAsJsonArray("user");
//方法1 ------------------------------------------------------------------
Gson gson = new Gson();
Type type = new TypeToken<List<User>>() {}.getType();
List<User> userList = gson.fromJson(jsonArray.toString(), type);
//[User(name=张三, age=22, email=12345677890@qq.com, sex=男, height=178),
// User(name=小红, age=22, email=1987654321@qq.com, sex=女, height=165)]
System.out.println(userList);
//方法2 ------------------------------------------------------------------
Gson gson2 = new Gson();
ArrayList<User> userList2 = new ArrayList<>();
//循环遍历
for (JsonElement user : jsonArray) {
//通过反射 得到UserBean.class
User userTemp = gson.fromJson(user, new TypeToken<User>() {}.getType());
userList2.add(userTemp);
}
//[User(name=张三, age=22, email=12345677890@qq.com, sex=男, height=178),
// User(name=小红, age=22, email=1987654321@qq.com, sex=女, height=165)]
System.out.println(userList2);
}
(2)json对象中同时包含普通字符串和json数组
那么如果是json对象中同时包含普通字符串和json数组呢?解决办法:这里需要修改下实体类了,即按照json的格式来处理
//准备json
{
"roles": "学生",
"auth": "上课",
"user": [
{
"t_name": "张三",
"t_age": "22",
"t_sex": "男",
"t_email": "12345677890@qq.com",
"t_height": "178"
},
{
"t_name": "小红",
"t_age": "22",
"t_sex": "女",
"t_email": "1987654321@qq.com",
"t_height": "165"
}
]
}
//实体类
@Data
public class JsonTest {
private String roles;
private String auth;
private List<User> user;
}
@Data
public class User {
@SerializedName(value = "name",alternate = {"t_name","s_name"})
private String name;
@SerializedName(value = "age",alternate = {"t_age","s_age"})
private String age;
@SerializedName(value = "email",alternate = {"t_email","s_email"})
private String email;
@SerializedName(value = "sex",alternate = {"t_sex","s_sex"})
private String sex;
@SerializedName(value = "height",alternate = {"t_height","s_height"})
private String height;
}
//测试类
public class gsonTest {
public static void main(String[] args) {
String jsonStr = "{\n" +
" \"roles\": \"学生\",\n" +
" \"auth\": \"上课\",\n" +
" \"user\": [\n" +
" {\n" +
" \"t_name\": \"张三\",\n" +
" \"t_age\": \"22\",\n" +
" \"t_sex\": \"男\",\n" +
" \"t_email\": \"12345677890@qq.com\",\n" +
" \"t_height\": \"178\"\n" +
" },\n" +
" {\n" +
" \"t_name\": \"小红\",\n" +
" \"t_age\": \"22\",\n" +
" \"t_sex\": \"女\",\n" +
" \"t_email\": \"1987654321@qq.com\",\n" +
" \"t_height\": \"165\"\n" +
" }\n" +
" ]\n" +
"}";
JsonTest jsonTest = new Gson().fromJson(jsonStr, JsonTest.class);
//JsonTest(roles=学生, auth=上课,
//user=[User(name=张三, age=22, email=12345677890@qq.com, sex=男, height=178),
//User(name=小红, age=22, email=1987654321@qq.com, sex=女, height=165)])
System.out.println(jsonTest);
}
}
(3)json对象里面同时含有字符串、json对象、json数组
那么如果再复杂一点呢?比如说json对象里面同时含有字符串、json对象、json数组呢?
处理办法:仍然是修改实体类.
其实从这几种情况来看,如果json格式发生了变化,那么处理办法就是修改总的jsonTest类。
//准备json
{
"roles": "学生",
"auth": "上课",
"teacher": {
"name": "张老师",
"age": "40"
},
"user": [
{
"t_name": "张三",
"t_age": "22",
"t_sex": "男",
"t_email": "12345677890@qq.com",
"t_height": "178"
},
{
"t_name": "小红",
"t_age": "22",
"t_sex": "女",
"t_email": "1987654321@qq.com",
"t_height": "165"
}
]
}
//实体类
@Data
public class JsonTest {
private String roles;
private String auth;
private Course course;
private List<User> user;
}
@Data
public class Course {
private String name;
private String type;
}
@Data
public class User {
@SerializedName(value = "name",alternate = {"t_name","s_name"})
private String name;
@SerializedName(value = "age",alternate = {"t_age","s_age"})
private String age;
@SerializedName(value = "email",alternate = {"t_email","s_email"})
private String email;
@SerializedName(value = "sex",alternate = {"t_sex","s_sex"})
private String sex;
@SerializedName(value = "height",alternate = {"t_height","s_height"})
private String height;
}
//测试类
public static void main(String[] args) {
String jsonStr = "{\n" +
" \"roles\": \"学生\",\n" +
" \"auth\": \"上课\",\n" +
" \"course\": {\n" +
" \"name\": \"高数\",\n" +
" \"type\": \"数学\"\n" +
" },\n" +
" \"user\": [\n" +
" {\n" +
" \"t_name\": \"张三\",\n" +
" \"t_age\": \"22\",\n" +
" \"t_sex\": \"男\",\n" +
" \"t_email\": \"12345677890@qq.com\",\n" +
" \"t_height\": \"178\"\n" +
" },\n" +
" {\n" +
" \"t_name\": \"小红\",\n" +
" \"t_age\": \"22\",\n" +
" \"t_sex\": \"女\",\n" +
" \"t_email\": \"1987654321@qq.com\",\n" +
" \"t_height\": \"165\"\n" +
" }\n" +
" ]\n" +
"}";
JsonTest jsonTest = new Gson().fromJson(jsonStr, JsonTest.class);
//JsonTest(roles=学生, auth=上课, course=com.winterchen.model.Course@41975e01,
//user=[User(name=张三, age=22, email=12345677890@qq.com, sex=男, height=178),
//User(name=小红, age=22, email=1987654321@qq.com, sex=女, height=165)])
System.out.println(jsonTest);
}
(4)json对象中有json数组,json数组中还有json数组
下面补充一个特殊情况:json对象中有json数组,json数组中还有json数组
//准备json
{
"roles": "学生",
"auth": "上课",
"course": {
"name": "高数",
"type": "数学"
},
"user": [
{
"t_name": "张三",
"t_age": "22",
"t_sex": "男",
"t_email": "12345677890@qq.com",
"t_height": "178",
"family": [
{
"f_name": "张大三",
"f_relation": "父亲"
},
{
"f_name": "刘女士",
"f_relation": "母亲"
}
]
},
{
"t_name": "小红",
"t_age": "22",
"t_sex": "女",
"t_email": "1987654321@qq.com",
"t_height": "165"
}
]
}
//准备实体类
@Data
public class JsonTest {
private String roles;
private String auth;
private Course course;
private List<User> user;
}
@Data
public class Course {
private String name;
private String type;
}
@Data
public class Family {
private String f_name;
private String f_relation;
}
@Data
public class User {
@SerializedName(value = "name",alternate = {"t_name","s_name"})
private String name;
@SerializedName(value = "age",alternate = {"t_age","s_age"})
private String age;
@SerializedName(value = "email",alternate = {"t_email","s_email"})
private String email;
@SerializedName(value = "sex",alternate = {"t_sex","s_sex"})
private String sex;
@SerializedName(value = "height",alternate = {"t_height","s_height"})
private String height;
@SerializedName(value = "family",alternate = {"t_family","s_family"})
private List<Family> family;
}
//测试类
public static void main(String[] args) {
String jsonStr = "{\n" +
" \"roles\": \"学生\",\n" +
" \"auth\": \"上课\",\n" +
" \"course\": {\n" +
" \"name\": \"高数\",\n" +
" \"type\": \"数学\"\n" +
" },\n" +
" \"user\": [\n" +
" {\n" +
" \"t_name\": \"张三\",\n" +
" \"t_age\": \"22\",\n" +
" \"t_sex\": \"男\",\n" +
" \"t_email\": \"12345677890@qq.com\",\n" +
" \"t_height\": \"178\",\n" +
" \"t_family\": [\n" +
" {\n" +
" \"f_name\": \"张大三\",\n" +
" \"f_relation\": \"父亲\"\n" +
" },\n" +
" {\n" +
" \"f_name\": \"刘女士\",\n" +
" \"f_relation\": \"母亲\"\n" +
" }\n" +
" ]\n" +
" },\n" +
" {\n" +
" \"t_name\": \"小红\",\n" +
" \"t_age\": \"22\",\n" +
" \"t_sex\": \"女\",\n" +
" \"t_email\": \"1987654321@qq.com\",\n" +
" \"t_height\": \"165\"\n" +
" }\n" +
" ]\n" +
"}";
JsonTest jsonTest = new Gson().fromJson(jsonStr, JsonTest.class);
//JsonTest(roles=学生, auth=上课, course=Course(name=高数, type=数学),
// user=[User(name=张三, age=22, email=12345677890@qq.com, sex=男, height=178,
// family=[Family(f_name=张大三, f_relation=父亲), Family(f_name=刘女士, f_relation=母亲)]),
// User(name=小红, age=22, email=1987654321@qq.com, sex=女, height=165, family=null)])
System.out.println(jsonTest);
}
二、FastJson
首先先介绍一下几个容易混淆的概念:
1.json对象:用 { } 表示的
例:{ "id":"123", "name":"张三", "age":"11"}
2.json数组:由多个json对象组成,用 [ ] 表示的
例:[{ "id":"123", "name":"张三", "age":"11"},{ "id":"321", "name":"李四", "age":"21"}]
3.序列化:json对象转字符串
4.反序列化:字符串转json对象
<!-- fastjson的依赖 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.44</version>
</dependency>
1.JsonObject
(1)基本用法
字符串和json之间的转换
//定义一个json对象用来演示
String str = "{ \"id\":\"123\", \"name\":\"张三\", \"age\":\"11\"}";
//【字符串转json对象】
JSONObject jsonObject = JSONObject.parseObject(str);
//【json对象转字符串】
String strTemp = jsonObject.toJSONString();
//【json对象中是否包含某个key】
boolean isHasKey = jsonObject.containsKey("na");
//【json对象中是否包含某个值】
boolean isHasValue = jsonObject.containsValue("123");
//【获取json对象中某个键对应的值】
Object id = jsonObject.get("id");
//【json对象转set】
Set<Map.Entry<String, Object>> entries = jsonObject.entrySet();
//【json对象转Map】
Map<String, String> params = JSONObject.parseObject(jsonObject.toJSONString(), new TypeReference<Map<String, String>>(){});
//【Map转json对象】
String jsonStr_Map = JSONUtils.toJSONString(params);
JSONObject jsonObjectTemp = JSONObject.parseObject(jsonStr_Map);
//【遍历json对象中的所有键值对】
for (Map.Entry<String,Object> entry : jsonObject.entrySet()){
String key = entry.getKey();
Object value = entry.getValue();
System.out.println("key="+key+" value="+value);
}
(2)高级用法
1.实体类与json之间的转换
//实体类
@Data
@AllArgsConstructor
public class TestUser {
private String name;
private Integer age;
private Integer sex;
}
//测试类
//定义一个实体类对象用来演示
TestUser testUser = new TestUser("111",11,1);
//【实体类转json】
JSONObject jsonObj = (JSONObject)JSONObject.toJSON(testUser);
//结果:{"sex":1,"name":"111","age":11}
System.out.println(jsonObj);
//【json转实体类】 反序列化
TestUser testUserTemp = JSONObject.parseObject(jsonObj.toJSONString(), TestUser.class);
//结果:TestUser(name=111, age=11, sex=1)
System.out.println(testUserTemp);
//这里补充一个 list对象转json
//如果有值为null,会导致这个key都被默认去掉,需要加上SerializerFeature.WriteMapNullValue
List<User> list = new ArrayList<>();
JSONArray jsonArray = JSONArray.parseArray(JSON.toJSONString(list,SerializerFeature.WriteMapNullValue))
| 名称 | 含义 |
|---|---|
| QuoteFieldNames | 输出key时是否使用双引号,默认为true |
| UseSingleQuotes | 使用单引号而不是双引号,默认为false |
| WriteMapNullValue | 是否输出值为null的字段,默认为false |
| WriteEnumUsingToString | Enum输出name()或者original,默认为false |
| UseISO8601DateFormat | Date使用ISO8601格式输出,默认为false |
| WriteNullListAsEmpty | List字段如果为null,输出为[],而非null |
| WriteNullStringAsEmpty | 字符类型字段如果为null,输出为”“,而非null |
| WriteNullNumberAsZero | 数值字段如果为null,输出为0,而非null |
| WriteNullBooleanAsFalse | Boolean字段如果为null,输出为false,而非null |
| SkipTransientField | 如果是true,类中的Get方法对应的Field是transient,序列化时将会被忽略。默认为true |
| SortField | 按字段名称排序后输出。默认为false |
| WriteTabAsSpecial | 把\t做转义输出,默认为false 不推荐 |
| PrettyFormat | 结果是否格式化,默认为false |
| WriteClassName | 序列化时写入类型信息,默认为false。反序列化是需用到 |
| DisableCircularReferenceDetect | 消除对同一对象循环引用的问题,默认为false |
| WriteSlashAsSpecial | 对斜杠’/’进行转义 |
| BrowserCompatible | 将中文都会序列化为\uXXXX格式,字节数会多一些,但是能兼容IE6,默认为false |
| WriteDateUseDateFormat | 全局修改日期格式,默认为false。JSON.DEFFAULT_DATE_FORMAT = “yyyy-MM-dd”;JSON.toJSONString(obj,SerializerFeature.WriteDateUseDateFormat); |
| DisableCheckSpecialChar | 一个对象的字符串属性中如果有特殊字符如双引号,将会在转成json时带有反斜杠转移符。如果不需要转义,可以使用这个属性。默认为false |
| NotWriteRootClassName | 含义 |
| BeanToArray | 将对象转为array输出 |
| WriteNonStringKeyAsString | 含义 |
| NotWriteDefaultValue | 含义 |
| BrowserSecure | 含义 |
| IgnoreNonFieldGetter | 含义 |
| WriteEnumUsingName | 含义 |
2.JSONField注解
那么如果我想要在实体类转json的时候,排除掉某些字段该怎么做呢?
答案:使用@JSONField(serialize = false) 注解。(是否参与序列化,false代表该字段不输出,但是如果加了final,这个字段就无法被过滤).
修改后的效果如下:
@Data
@AllArgsConstructor
public class TestUser {
@JSONField(serialize = false)
private String name;
private Integer age;
private Integer sex;
}
//定义一个实体类对象用来演示
TestUser testUser = new TestUser("111",11,1);
//【实体类转json】
JSONObject jsonObj = (JSONObject)JSONObject.toJSON(testUser);
//结果:{"sex":1,"age":11}
System.out.println(jsonObj);
//【json转实体类】 反序列化
TestUser testUserTemp = JSONObject.parseObject(jsonObj.toJSONString(), TestUser.class);
//结果:TestUser(name=null, age=11, sex=1)
System.out.println(testUserTemp);
那么如果我想要在实体类转json的时候,不使用实体类中的名称该如何做呢?
答案:使用@JSONField(name = "别名") 注解。
使用字段别名,效果如下:
@Data
@AllArgsConstructor
public class TestUser {
@JSONField(name = "t_name")
private String name;
private Integer age;
private Integer sex;
}
//定义一个实体类对象用来演示
TestUser testUser = new TestUser("111",11,1);
//【实体类转json】
JSONObject jsonObj = (JSONObject)JSONObject.toJSON(testUser);
//结果:{"t_name":"111","sex":1,"age":11}
System.out.println(jsonObj);
//【json转实体类】 反序列化
TestUser testUserTemp = JSONObject.parseObject(jsonObj.toJSONString(), TestUser.class);
//结果:TestUser(name=111, age=11, sex=1)
System.out.println(testUserTemp);
那么如果现在有个时间类型的字段,我想要以固定的格式输出,该怎么办呢?
答案:使用@JSONField(format="yyyy-MM-dd HH:mm:ss") 注解。
下面先添加一个时间字段date,看看添加前后的效果:
@Data
@AllArgsConstructor
public class TestUser {
private String name;
private Integer age;
private Integer sex;
@JSONField(format="yyyy-MM-dd HH:mm:ss")
private Date date;
}
//定义一个实体类对象用来演示
TestUser testUser = new TestUser("111",11,1,new Date());
//【实体类转json】
JSONObject jsonObj = (JSONObject)JSONObject.toJSON(testUser);
//添加前结果:{"date":1600485884579,"sex":1,"name":"111","age":11}
//添加后结果:{"date":"2020-09-19 11:25:46","sex":1,"name":"111","age":11}
System.out.println(jsonObj);
//【json转实体类】 反序列化
TestUser testUserTemp = JSONObject.parseObject(jsonObj.toJSONString(), TestUser.class);
//添加前结果:TestUser(name=111, age=11, sex=1, date=Sat Sep 19 11:24:44 CST 2020)
//添加后结果:TestUser(name=111, age=11, sex=1, date=Sat Sep 19 11:25:46 CST 2020)
System.out.println(testUserTemp);
那么如果某个字段的值是null,在序列化的时候,可以看到生成的字符串中没有对应的key,那么我想要实现,如果值为空,给其一个默认值:
这里要提及一个知识:**SerializerFeature**属性,下面列举几个,详细的可以去查api
参考:<https://www.cnblogs.com/wbxk/p/10064737.html>
1.字符类型字段如果为null,输出为"",而非null WriteNullStringAsEmpty
2.数值字段如果为null,输出为0,而非null WriteNullNumberAsZero
3.Boolean字段如果为null,输出为false,而非null WriteNullBooleanAsFalse
4.List字段如果为null,输出为[],而非null WriteNullListAsEmpty
@Data
@AllArgsConstructor
public class TestUser {
@JSONField(serialzeFeatures=SerializerFeature.WriteNullStringAsEmpty)
private String name;
private Integer age;
private Integer sex;
@JSONField(format="yyyy-MM-dd HH:mm:ss")
private Date date;
}
//定义一个实体类对象用来演示
TestUser testUser = new TestUser(null,11,1,new Date());
String jsonStr = JSON.toJSONString(testUser);
//加注解前:{"age":11,"date":"2020-09-19 12:49:07","sex":1}
//加注解后:{"age":11,"date":"2020-09-19 12:48:28","name":"","sex":1}
System.out.println(jsonStr);
现在想要将json对象转换成实体类对象,方法如下:
@Data
public class TestUser {
private String name;
private Integer age;
private Integer sex;
private Date date;
}
//定义一个实体类对象用来演示
TestUser testUser = new TestUser();
testUser.setName("11");
testUser.setAge(11);
testUser.setSex(1);
String jsonStr = JSON.toJSONString(testUser);
//实体类转成json对象
JSONObject jsonObject = JSONObject.parseObject(jsonStr);
//【json对象转成实体类】
TestUser testUserTemp = JSON.toJavaObject(jsonObject, TestUser.class);
//结果:TestUser(name=11, age=11, sex=1, date=null)
System.out.println(testUserTemp);
这里要注意:上面的例子里我都是用的@AllArgsConstructor来方便我创建实体类数据,但是我发现如果加上了这个注解,在使用toJavaObject方法的时候会报错。不使用这个注解没有问题。报错信息如下:
网上搜的结果为:
实体类中存在内嵌的其它类,将内部类修改为静态内部类即可,但是我这里也没有发现有内部类的字段,于是我尝试将Date类型的屏蔽,结果成功了,暂时还没有想清楚是什么问题
//报错代码如下
@Data
@AllArgsConstructor
public class TestUser {
private String name;
private Integer age;
private Integer sex;
private Date date;
}
//定义一个实体类对象用来演示
TestUser testUser = new TestUser("111",11,1,new Date());
String jsonStr = JSON.toJSONString(testUser);
JSONObject jsonObject = JSONObject.parseObject(jsonStr);
TestUser testUserTemp = JSON.toJavaObject(jsonObject, TestUser.class);
2.JsonArray
JsonArray:即json数组,由多个json对象(jsonObject)组成
//定义一个json数组类型的字符串用来演示
String jsonstr = "[{\"sex\":\"1\",\"name\":\"111\",\"age\":\"11\"},{\"sex\":\"0\", \"name\":\"222\",\"age\":\"21\"}]";
//【String转jsonArray】
JSONArray jsonArray = JSONArray.parseArray(jsonstr);
//【jsonArray转String】
String jsonstrTemp = JSON.toJSONString(jsonArray);
//【jsonArray转list】
List list = JSONObject.parseArray(jsonArray.toJSONString());
//【jsonArray转list-->对象】
List<TestUser> testUsers = JSONObject.parseArray(jsonArray.toJSONString(), TestUser.class);
//【list转jsonArray】
List listTemp = new ArrayList();
JSONArray array = JSONArray.parseArray(JSON.toJSONString(listTemp));
//【list转jsonArray--->对象】
List<TestUser> testUserList = new ArrayList<>();
JSONArray array1 = JSONArray.parseArray(JSON.toJSONString(listTemp));
//【String转List】
List<TestUser> testUserList1 = JSONObject.parseArray(jsonstr, TestUser.class);
//【循环获取jsonArray中所有的jsonObject】
for (int i = 0; i < jsonArray.size(); i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
String id = jsonObject.getString("sex");
String name = jsonObject.getString("name");
//这里要注意:age字段也可以用getString方法来获取
Integer age = jsonObject.getInteger("age");
}
3.JsonObject+JsonArray
如何判断一个不确定格式的json串,每个key对应的类型呢?
//【判断json类型】
String text0 = "11";
String text2 = "{ \"sex\":\"1\", \"name\":\"张三\", \"age\":\"11\"}";
String text3 = "[{ \"sex\":\"1\", \"name\":\"张三\", \"age\":\"11\"},{ \"sex\":\"0\", \"name\":\"李四\", \"age\":\"21\"}]";
Object parse0 = JSON.parse(text0);
System.out.println(parse0 instanceof java.lang.Integer);//true
Object parse2 = JSON.parse(text2);
System.out.println(parse2 instanceof JSONObject);//true
Object parse3 = JSON.parse(text3);
System.out.println(parse3 instanceof JSONArray);//true
三、Jackson
下面主要通过几个方面来介绍jackson:
1. jackson的一些常用方法
2. jackson的一些常用注解
3. JsonNode && ArrayNode && ObjectNode
4. jackson处理文件的导入导出
首先需要引入依赖
jackson-databind 依赖 jackson-core 和 jackson-annotations,当添加 jackson-databind 之后, jackson-core 和 jackson-annotations 也随之添加到 Java 项目工程中。在添加相关依赖包之后,就可以使用 Jackson。
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.11.0</version>
</dependency>
1.jackson的一些常用方法
一些概念和方法的介绍:
ObjectMapper是JSON操作的核心,Jackson的所有JSON操作都是在ObjectMapper中实现。
ObjectMapper有多个JSON序列化的方法,可以把JSON字符串保存File、OutputStream等不同的介质中。
writeValue(File arg0, Object arg1)把arg1转成json序列,并保存到arg0文件中。
writeValue(OutputStream arg0, Object arg1)把arg1转成json序列,并保存到arg0输出流中。
writeValueAsBytes(Object arg0)把arg0转成json序列,并把结果输出成字节数组。
writeValueAsString(Object arg0)把arg0转成json序列,并把结果输出成字符串。
//实体类
@Data
@AllArgsConstructor
public class TestUser {
private String name;
private Integer age;
private Integer sex;
private Date date;
}
//测试类
//定义一个对象用于测试
TestUser testUser = new TestUser("1",11,1,new Date());
TestUser testUser2 = new TestUser("2",22,2,new Date());
ObjectMapper mapper = new ObjectMapper();
//【对象转String】
String str = mapper.writeValueAsString(testUser);
//结果:{"name":"1","age":11,"sex":1,"date":1600595735478}
System.out.println(str);
//【String转对象】这里要注意,版本号2.10.1以上readValue方法就会报错,2.9.5就可以
//报错信息:java.lang.ClassNotFoundException: com.fasterxml.jackson.core.exc.InputCoercionException
TestUser testUserTemp = mapper.readValue(str, TestUser.class);
//结果:TestUser(name=1, age=11, sex=1, date=Sun Sep 20 18:07:43 CST 2020)
System.out.println(testUserTemp);
//list转json-string
List<TestUser> testUserList = new ArrayList<>();
testUserList.add(testUser);
testUserList.add(testUser2);
String json = mapper.writeValueAsString(testUserList);
//结果:[{"name":"1","age":11,"sex":1,"date":1600910383747},{"name":"2","age":22,"sex":2,"date":1600910383747}]
System.out.println(json);
2.jackson的一些常用注解
@JsonIgnore
此注解用于属性上,作用是进行JSON操作时忽略该属性。
@JsonIgnoreProperties
此注解用于类上,作用是忽略多个属性,如:@JsonIgnoreProperties({"userName", "userAge"})
@JsonFormat
此注解用于属性上,作用是把Date类型直接转化为想要的格式,如@JsonFormat(pattern = "yyyy-MM-dd HH-mm-ss")。
@JsonProperty
此注解用于属性上,作用是把该属性的名称序列化为另外一个名称,如把trueName属性序列化为name, @JsonProperty("name")。
@JsonInclude
此注解可用于属性和类上,作用是排除值为null的属性,如:
@JsonInclude(JsonInclude.Include.NON_NULL)-->属性为null不参与序列化。
@JsonInclude(JsonInclude.Include.NON_EMPTY)-->属性为空或者null都不参与序列化。
@JsonUnwrapped
此注解用于属性上,作用:
1. 是去掉外包装\
2. 把成员对象中的属性提升到其容器类,并添加给定的前缀,如:@JsonUnwrapped(prefix = "user_")
@JsonAppend
此注解用于类上,为json添加虚拟属性,如:@JsonAppend(attrs = {@JsonAppend.Attr(value = "version")})
@JsonNaming
此注解用于类上,作用是将驼峰式改成下划线,如:
@JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class)
此外还有:
- KEBAB_CASE: 属性名单词用短线分隔连接, 比如*hello-world*
- LOWER_CASE: 属性名用小写字母而且没有分隔符, 比如*helloworld*
- SNAKE_CASE: 属性名用小写字母而且用下划线做分隔符, 比如*hello_world*
- UPPER_CAMEL_CASE: 属性名所有单词用大写开头而且没有分隔符, 比如*HelloWorld*
MapperFeature.USE_ANNOTATIONS
禁用所有jackson注解的功能
@JsonPropertyOrder
此注解用于类上,作用是给序列化之后的json排序,如:
@JsonPropertyOrder(value = {"userSex","userAge","userName"})
(1)JsonIgnore && JsonIgnoreProperties
@Data
@AllArgsConstructor
public class TestUser {
@JsonIgnore
private String name;
private Integer age;
private Integer sex;
private Date date;
}
//定义一个对象用于测试
TestUser testUser = new TestUser("1",11,1,new Date());
ObjectMapper mapper = new ObjectMapper();
//【对象转String】
String str = mapper.writeValueAsString(testUser);
//加上注解前:{"name":"1","age":11,"sex":1,"date":1600913752059}
//加上注解后:{"age":11,"sex":1,"date":1600913711465}
System.out.println(str);
--------------------------------------------------------------------------------------------
@Data
@AllArgsConstructor
@JsonIgnoreProperties({"userName", "userAge"})
public class TestUser {
private String userName;
private Integer userAge;
private Integer userSex;
}
//定义一个对象用于测试
TestUser testUser = new TestUser("111",11,1);
ObjectMapper mapper = new ObjectMapper();
//【对象转String】
String str = mapper.writeValueAsString(testUser);
//加上注解前:{"userName":"111","userAge":11,"userSex":1}
//加上注解后:{"userSex":1}
System.out.println(str);
(2)JsonFormat
@Data
@AllArgsConstructor
public class TestUser {
private String name;
private Integer age;
private Integer sex;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date date;
}
//定义一个对象用于测试
TestUser testUser = new TestUser("1",11,1,new Date());
ObjectMapper mapper = new ObjectMapper();
//【对象转String】
String str = mapper.writeValueAsString(testUser);
//加上注解前:{"name":"1","age":11,"sex":1,"date":1600913893613}
//加上注解后:{"name":"1","age":11,"sex":1,"date":"2020-09-24 02:17:56"}
System.out.println(str);
(3)JsonProperty
@Data
@AllArgsConstructor
public class TestUser {
@JsonProperty("t_name")
private String name;
private Integer age;
private Integer sex;
private Date date;
}
//定义一个对象用于测试
TestUser testUser = new TestUser("1",11,1,new Date());
ObjectMapper mapper = new ObjectMapper();
//【对象转String】
String str = mapper.writeValueAsString(testUser);
//加上注解前:{"name":"1","age":11,"sex":1,"date":1600913893613}
//加上注解后:{"t_name":"1","age":11,"sex":1,"date":1600913990057}
System.out.println(str);
(4)JsonInclued
@Data
@AllArgsConstructor
public class TestUser {
@JsonInclude(JsonInclude.Include.NON_NULL)
private String name;
private Integer age;
private Integer sex;
private Date date;
}
@Data
@AllArgsConstructor
@JsonInclude(JsonInclude.Include.NON_NULL)
public class TestUser {
private String name;
private Integer age;
private Integer sex;
private Date date;
}
//定义一个对象用于测试
TestUser testUser = new TestUser(null,11,1,new Date());
ObjectMapper mapper = new ObjectMapper();
//【对象转String】
String str = mapper.writeValueAsString(testUser);
//加上注解前:{"name":null,"age":11,"sex":1,"date":1600914468252}
//加上注解后:{"age":11,"sex":1,"date":1600914452682}
System.out.println(str);
(5)JsonUnwrapped
@Data
@AllArgsConstructor
public class TestUser {
private String name;
private Integer age;
private Integer sex;
@JsonUnwrapped
private Teacher teacher;
}
@Data
@AllArgsConstructor
public class Teacher {
private String tel;
private String email;
}
//定义一个对象用于测试
TestUser testUser = new TestUser("111",11,1,new Teacher("13718999090","12345@qq.com"));
ObjectMapper mapper = new ObjectMapper();
//【对象转String】
String str = mapper.writeValueAsString(testUser);
//加上注解前:{"name":"111","age":11,"sex":1,"teacher":{"tel":"13718999090","email":"12345@qq.com"}}
//加上注解后:{"name":"111","age":11,"sex":1,"tel":"13718999090","email":"12345@qq.com"}
System.out.println(str);
----------------------------------------------------------------------------------------------
@Data
@AllArgsConstructor
public class TestUser {
private String userName;
private Integer userAge;
private Integer userSex;
@JsonUnwrapped(prefix = "user_")
private Teacher teacher;
}
//定义一个对象用于测试
TestUser testUser = new TestUser("111",11,1,new Teacher("11111","11111@qq.com"));
ObjectMapper mapper = new ObjectMapper();
//【对象转String】
String str = mapper.writeValueAsString(testUser);
//加上注解前:{"userName":"111","userAge":11,"userSex":1,"teacher":{"tel":"11111","email":"11111@qq.com"}}
//加上注解后:{"userName":"111","userAge":11,"userSex":1,"user_tel":"11111","user_email":"11111@qq.com"}
System.out.println(str);
(6)JsonAppend
@Data
@AllArgsConstructor
@JsonAppend(attrs = {@JsonAppend.Attr(value = "version")})
public class TestUser {
private String name;
private Integer age;
private Integer sex;
}
//定义一个对象用于测试
TestUser testUser = new TestUser("111",11,1);
ObjectMapper mapper = new ObjectMapper();
//为虚拟属性添加值
ObjectWriter writer = mapper.writerFor(TestUser.class).withAttribute("version", "1.0");
//【对象转String】
String str = writer.writeValueAsString(testUser);
//加上注解前:{"name":"111","age":11,"sex":1}
//加上注解后:{"name":"111","age":11,"sex":1,"version":"1.0"}
System.out.println(str);
(7)JsonNaming
@Data
@AllArgsConstructor
@JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class)
public class TestUser {
private String userName;
private Integer userAge;
private Integer userSex;
}
//定义一个对象用于测试
TestUser testUser = new TestUser("111",11,1);
ObjectMapper mapper = new ObjectMapper();
//【对象转String】
String str = mapper.writeValueAsString(testUser);
//加上注解前:{"userName":"111","userAge":11,"userSex":1}
//加上注解后:{"user_name":"111","user_age":11,"user_sex":1}
System.out.println(str);
(8)MapperFeature.USE_ANNOTATIONS
@Data
@AllArgsConstructor
@JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class)
public class TestUser {
private String userName;
private Integer userAge;
private Integer userSex;
}
//定义一个对象用于测试
TestUser testUser = new TestUser("111",11,1);
ObjectMapper mapper = new ObjectMapper();
//禁用jackson注解
mapper.disable(MapperFeature.USE_ANNOTATIONS);
//【对象转String】
String str = mapper.writeValueAsString(testUser);
//加上注解前:{"userName":"111","userAge":11,"userSex":1}
//加上注解后:{"userName":"111","userAge":11,"userSex":1}
System.out.println(str);
(9)JsonPropertyOrder
@Data
@AllArgsConstructor
@JsonPropertyOrder(value = {"userSex","userAge","userName"})
public class TestUser {
private String userName;
private Integer userAge;
private Integer userSex;
}
//定义一个对象用于测试
TestUser testUser = new TestUser("111",11,1);
ObjectMapper mapper = new ObjectMapper();
//【对象转String】
String str = mapper.writeValueAsString(testUser);
//加上注解前:{"userName":"111","userAge":11,"userSex":1}
//加上注解后:{"userSex":1,"userAge":11,"userName":"111"}
System.out.println(str);
3.JsonNode && ArrayNode && ObjectNode
ObjectNode
是对象结点,可以存入对象属性。如 { "name":"Lilei", "age":"18", "school":"HNU" }
ArrayNode
是数组结点,用于存放JsonNode数据。如[ "Lilei", "XiaoHong", {"nm1": "Jay", "nm2": "Kong"} ]
JsonNode
是ObjectNode和ArrayNode的父接口。想要生成JsonNode对象都要先生成ObjectMapper类对象,它是产生Json结点的工厂。
(1)JsonNode
String jsonStr = "{\"userName\":\"111\",\"userAge\":11,\"userSex\":1}";
ObjectMapper mapper = new ObjectMapper();
//【JsonNode】
JsonNode jsonNode = mapper.readTree(jsonStr);
//结果:{"userName":"111","userAge":11,"userSex":1}
System.out.println(jsonNode);
//【判断值类型】
String nodeType = jsonNode.get("userName").getNodeType().toString()+"***"+jsonNode.get("userAge").getNodeType().toString();
//结果:STRING***NUMBER
System.out.println(nodeType);
//【遍历key】
Iterator<String> fieldNames = jsonNode.fieldNames();
while (fieldNames.hasNext()) {
//结果:userName userAge userSex
System.out.println(fieldNames.next());
}
//【遍历value】
Iterator<JsonNode> elements = jsonNode.elements();
while (elements.hasNext()) {
//结果:"111" 11 1
System.out.println(elements.next());
}
//【单独获取某个key的值】
JsonNode path = jsonNode.get("userName");
//结果:"111"
System.out.println(path);
//结果:true
System.out.println(jsonNode instanceof ObjectNode);
获取属性、子节点有以下两个方法:
1.path:
路径访问安全,当访问的结点不存在时返回“MissingNode”,我将其理解为没有任何属性值的结点,也可以通过asText()转换为String类型,值为空字串;当访问的属性无效时同样返回空字串""。
优势是不知道多层子节点的值是否一定存在时**可以连续使用**path,若不存在一律返回"";但不能判断结点是否存在。
2.get:
路径访问不安全,其访问结点路径或属性无效时返回null,故使用连续使用get访问时,**若路径不存在会出现空指针异常**。
优势是可以用是否为null判断结点是否存在。
3.访问技巧:
不知道节点路径上是否所有节点都存在,可以使用
JsonNode temp = xxxNode.path("prop1").path("prop2").....get("propN");
if (null != temp) { do something... } 这样的方式安全得到不一定存在的节点
String jsonStr = "{\"userName\":\"111\",\"userAge\":11,\"userSex\":1}";
ObjectMapper mapper = new ObjectMapper();
//【JsonNode】
JsonNode jsonNode = mapper.readTree(jsonStr);
//【path】
JsonNode path = jsonNode.path("userName");
//结果:"111"
System.out.println(path);
JsonNode kkk = jsonNode.path("kkk");
//结果:空
System.out.println(kkk);
//【连续path】
JsonNode paths = jsonNode.path("a").path("b").path("c");
//结果:空
System.out.println(paths);
//【get】
JsonNode get1 = jsonNode.get("userName");
//结果:"111"
System.out.println(get1);
//结果:null
JsonNode get2 = jsonNode.get("kkk");
System.out.println(get2);
//【连续get】
JsonNode get3 = jsonNode.get("userName").get("kkk");
//结果:null
System.out.println(get3);
//【连续get-->如果get的结果为null之后继续get就会报错】
JsonNode get4 = jsonNode.get("userName").get("kkk").get("kkk");
//结果:java.lang.NullPointerException
System.out.println(get4);
//【asText && asInt】
String userName_userAgeText_userAgeInt = jsonNode.path("userName").asText()+"_"+jsonNode.path("userAge").asText()+"_"+jsonNode.path("userSex").asInt();
//结果:111_11_1
System.out.println(userName_userAgeText_userAgeInt);
(2)ObjectNode
ObjectMapper mapper = new ObjectMapper();
//生成对象结点
ObjectNode objNode = mapper.createObjectNode();
//【put方法--在jdk1.8中,简单值用put设置】
objNode.put("name","111");
objNode.put("age",11);
//结果:{"name":"111","age":11}
System.out.println(objNode);
//【set方法--在jdk1.8中,子节点用set设置】
ObjectNode objectNode = mapper.createObjectNode();
objectNode.put("innername", "222");
objectNode.put("innerage", 22);
objNode.set("inner", objectNode);
//结果:{"name":"111","age":11,"inner":{"innername":"222","innerage":22}}
System.out.println(objNode);
(3)ArrayNode
ObjectMapper mapper = new ObjectMapper();
//【生成数组结点】-->注意:数组结点添加元素不做简单值和结点类的区分
ArrayNode arrNode = mapper.createArrayNode();
arrNode.add("111");
//结果:["111"]
System.out.println(arrNode);
//生成对象结点
ObjectNode objNode = mapper.createObjectNode();
objNode.put("name","111");
objNode.put("age",11);
ArrayNode addObj = arrNode.add(objNode);
//结果:["111",{"name":"111","age":11}]
System.out.println(addObj);
4.Jackson处理文件的导入导出
(1)txt文件的导出
ObjectMapper mapper = new ObjectMapper();
//生成对象结点
ObjectNode objNode = mapper.createObjectNode();
objNode.put("name","111");
objNode.put("age",11);
//【写入txt文件】
OutputStream outputStream= new FileOutputStream(new File("d:/11.txt"));
mapper.writeValue(outputStream, objNode);
(2)txt文件的导入
ObjectMapper mapper = new ObjectMapper();
//【导入txt文件数据】
JsonNode jsonNode = mapper.readTree(new File("d:/11.txt"));
//结果:{"name":"111","age":11}
System.out.println(jsonNode);
(3)导入导出案例
要求:
根据实体类对象的类型生成相应的json并导出
导入json数据
映射到对象
@Data
@AllArgsConstructor
public class TestUser {
private String userName;
private Integer userAge;
private Integer userSex;
private Integer[] test;
}
ObjectMapper mapper = new ObjectMapper();
//生成数组节点
ArrayNode arrayNode = mapper.createArrayNode();
arrayNode.add(1);
arrayNode.add(2);
arrayNode.add(3);
//生成对象结点
ObjectNode objNode = mapper.createObjectNode();
objNode.put("userName","111");
objNode.put("userAge",11);
objNode.put("userSex",1);
objNode.put("test",arrayNode);
//【导出】
OutputStream outputStream= new FileOutputStream(new File("d:/test.txt"));
mapper.writeValue(outputStream, objNode);
//【导入】
JsonNode jsonNode = mapper.readTree(new File("d:/test.txt"));
TestUser testUser = mapper.treeToValue(jsonNode, TestUser.class);
//结果:TestUser(userName=111, userAge=11, userSex=1, test=[1, 2, 3])
System.out.println(testUser);
四、Json-flattener
github地址:<https://github.com/wnameless/json-flattener>
前言
下面主要通过几个方面来介绍json-flattener:
1. 扁平化处理
2. 去扁平化
<!--依赖 -->
<dependency>
<groupId>com.github.wnameless.json</groupId>
<artifactId>json-flattener</artifactId>
<version>0.8.1</version>
</dependency>
1.扁平化处理
//json
{
"ip":"192.168.100.100",
"type":"0",
"index":"3",
"timestamp":"1555317936",
"value":
[
{
"cpuIndex":"0",
"cpuName":"Intel(R) Xeon(R) CPUE5-2620 v4",
"cpuCores":"8",
"cpuFreq":"2.10GHz",
"cpuRate":"0.85"
},
{
"cpuIndex":"1",
"cpuName":"Intel(R) Xeon(R) CPUE5-2620 v4",
"cpuCores":"8",
"cpuFreq":"2.10GHz",
"cpuRate":"2.05"
}
]
}
//测试类
String jsonStr = "上面的json";
JSONObject jsonObj = JSONObject.parseObject(jsonStr);
Map<String, Object> flatMap = JsonFlattener.flattenAsMap(jsonObj.toString());
//将 . 改成 ,
//Map<String, Object> flatMap = new JsonFlattener(jsonObj.toString()).withSeparator(',').flattenAsMap();
for (Map.Entry<String, Object> entry : flatMap.entrySet()) {
System.out.println(entry.getKey() + " : " + entry.getValue());
}
//效果
ip : 192.168.100.100
index : 3
type : 0
value[0].cpuCores : 8
value[0].cpuIndex : 0
value[0].cpuRate : 0.85
value[0].cpuFreq : 2.10GHz
value[0].cpuName : Intel(R) Xeon(R) CPUE5-2620 v4
value[1].cpuCores : 8
value[1].cpuIndex : 1
value[1].cpuRate : 2.05
value[1].cpuFreq : 2.10GHz
value[1].cpuName : Intel(R) Xeon(R) CPUE5-2620 v4
timestamp : 1555317936
#--------------------------------------------------------------------------------
ip : 192.168.100.100
index : 3
type : 0
value[0],cpuCores : 8
value[0],cpuIndex : 0
value[0],cpuRate : 0.85
value[0],cpuFreq : 2.10GHz
value[0],cpuName : Intel(R) Xeon(R) CPUE5-2620 v4
value[1],cpuCores : 8
value[1],cpuIndex : 1
value[1],cpuRate : 2.05
value[1],cpuFreq : 2.10GHz
value[1],cpuName : Intel(R) Xeon(R) CPUE5-2620 v4
timestamp : 1555317936
2.去扁平化
//json
{
"registro.status": "1",
"registro.nome": "SUELI",
"registro.sobrenome": "BERNARDO BRITO",
"registro.telefone": "1100128500",
"registro.endereco": "RUA SIVI",
"registro.numero": "20",
"registro.complemento": "CS FR",
"registro.bairro": "CIDADE INDUSTRIAL SATELITE DE SAO PAULO",
"registro.cep": "07222190",
"registro.cidade": "GUARULHOS",
"registro.uf": "SP",
"registro.cpfcnpj": "12345678900",
"registro.mae": "TERESINHA",
"registro.sobrenomemae": "DE FATIMA BERNARDO",
"registro.nasc": "1995-08-05",
"registro.protocolo": "320978777"
}
//测试代码
String unflattenJson = JsonUnflattener.unflatten(jsonStr);
//结果
{
"registro": {
"status": "1",
"nome": "SUELI",
"sobrenome": "BERNARDO BRITO",
"telefone": "1100128500",
"endereco": "RUA SIVI",
"numero": "20",
"complemento": "CS FR",
"bairro": "CIDADE INDUSTRIAL SATELITE DE SAO PAULO",
"cep": "07222190",
"cidade": "GUARULHOS",
"uf": "SP",
"cpfcnpj": "12345678900",
"mae": "TERESINHA",
"sobrenomemae": "DE FATIMA BERNARDO",
"nasc": "1995-08-05",
"protocolo": "320978777"
}
}
参考文章
1. www.cnblogs.com/jpfss/p/905… 2. blog.csdn.net/wang_snake/… 3. blog.csdn.net/blwinner/ar… 4. blog.csdn.net/u012510831/… 5. blog.csdn.net/jx2956/arti…