JSON处理——FastJson、Jackson、Gson详细使用
创始人
2024-04-21 09:10:54
0

文章目录

    • 一、基本介绍
    • 二、FastJson使用
      • 2.1 对象序列化为JSON字符串
      • 2.2 JSON字符串反序列化为对象
      • 2.3 JSON对象、JSON数组的其他操作
      • 2.4 JSONPath解析JSON
    • 三、Jackson使用
      • 3.1 ObjectMapper基本使用
      • 3.2 ObjectMapper相关配置及异常场景
      • 3.3 注解方式配置
    • 四、Gson使用

一、基本介绍

JSON:一种轻量级的数据交换格式。JSON的数据格式比较简单,易于读写,层级清晰分明。目前在前后端的交互中,几乎都是使用JSON实现的。例如如下数据

{"code": 200,"msg": "成功","list": [{"name": "张三","age": 18,"sex": "男"}, {"name": "李四","age": 19,"sex": "女"}]
}

解析JSON:目前解析JSON的方式有很多,例如阿里的FastJson、谷歌的Gson、Jackson等,下面就是几种解析JSON的方式。

二、FastJson使用

maven依赖:在pom.xml文件中引入依赖

com.alibabafastjson1.2.47

常用类:FastJson常用类有JSONJSONObjectJSONArray,它们的作用及常用方法如下:

类作用常用方法方法作用
JSON 1.将Java对象序列化为JSON字符串
2.将JSON字符串反序列化为Java对象
toJSONString将对象转换为JSON字符串(静态方法)
parseObject将JOSN字符串转换为JSON数组(静态方法)
parseArray将JOSN字符串转换为JSON对象(静态方法)
JSONObject 1.继承于JSON类、Map接口实现类
2.JSONObject对象中的数据都是以 key-value形式出行,使用起来和Map类似
parseObject直接继承JSON类同名方法 未重写
getString获取json对象key对应的value值,返回String类型
get获取json对象key对应的value值,返回Object类型
put添加key-value到json对象中
getJSONArray获取json对象key对应的value值,并将value值转换为JSONArray类型
getJSONObject获取json对象key对应的value值,并将value值转换为JSONObject类型
JSONArray 1.继承于JSON类、List接口实现类
2.代表JSON数组,数组中每个存储的就是JSON对象
parseArray直接继承JSON类同名方法 未重写
add添加对象到JSON数组
getJSONObject获取指定坐标下的JSON对象

2.1 对象序列化为JSON字符串

@Test
public void mapToJsonString(){Map map=new HashMap<>();map.put("key1","One");map.put("key2","Two");System.out.println(JSON.toJSONString(map));/* 输出{"key1":"One","key2":"Two"} */
}@Test
public void pojoListToJsonString(){List userList=new ArrayList<>();User user1=new User("admin1","12","男");User user2=new User("admin2","13","女");userList.add(user1);userList.add(user2);System.out.println(JSON.toJSONString(userList));/* 输出 [{"age":"12","name":"admin1","sex":"男"},{"age":"13","name":"admin2","sex":"女"}] */
}@Test
public void jsonObjectToJsonString(){/*JSONObject.toJSONString和 JSON.toJSONString * JSONObject继承于 JSON toJSONString也只在JSON类中 未在JSONObject中重写* */String jsonString="{\"key1\":\"One\",\"key2\":\"Two\"}";JSONObject object = JSONObject.parseObject(jsonString);String str1=JSONObject.toJSONString(object);String str2=JSON.toJSONString(object);System.out.println(str1);System.out.println(str2);/*输出 {"key1":"One","key2":"Two"}*/
}

2.2 JSON字符串反序列化为对象

@Test
public void jsonStringToJsonObject(){/*JSONObject是一个继承自JSON的类,当调用JSONObject.parseObject(result)时,会直接调用父类的parseObject(String text)*/String jsonString="{\"key1\":\"One\",\"key2\":\"Two\"}";JSONObject object = JSONObject.parseObject(jsonString);System.out.println(object.get("key1"));//输出 OneJSONObject jsonObject=JSON.parseObject(jsonString);System.out.println(jsonObject.get("key1"));//输出 One
}@Test
public void jsonArrayStringToJsonArray(){String jsonArrayString="[{\"name\":\"张三\",\"age\":25},{\"name\":\"李四\",\"age\":28}]";JSONArray jsonArray=JSONArray.parseArray(jsonArrayString);for(Object object:jsonArray){JSONObject jsonObject=(JSONObject)object;System.out.println(jsonObject.get("name")); // 输出张三  李四}
}@Test
public void JsonStringToMapOrPo(){String listStr="[{\"age\":\"12\",\"name\":\"admin1\",\"sex\":\"男\"},{\"age\":\"13\",\"name\":\"admin2\",\"sex\":\"女\"}]";String str="{\"age\":\"12\",\"name\":\"admin1\",\"sex\":\"男\"}";List userList=JSONArray.parseArray(listStr,User.class);userList.stream().forEach(user->System.out.println(user));User user=JSONObject.parseObject(str,User.class);System.out.println(user);
}

2.3 JSON对象、JSON数组的其他操作

@Test
public void test1(){String goodsData = "{\"code\":0,\"kind\":\"Electronics\",\"list\":[{\"name\":\"computer\",\"price\":4500,\"size\":60},{\"name\":\"iphone\",\"price\":6000,\"size\":55},{\"name\":\"watch\",\"price\":500,\"size\":35}]}";JSONObject jsonObject=JSON.parseObject(goodsData);System.out.println(jsonObject.getJSONArray("list"));String list=jsonObject.getString("list");System.out.println(JSON.parseArray(list));
}@Testpublic void pojoListTOJsonArray(){List userList=new ArrayList<>();User user1=new User("admin1","12","男");User user2=new User("admin2","13","女");userList.add(user1);userList.add(user2);System.out.println(JSON.toJSONString(userList));JSONArray jsonArray=JSONArray.parseArray(JSON.toJSONString(userList));JSONObject jsonObject=(JSONObject)jsonArray.get(0);System.out.println(jsonObject.get("name"));JSONArray jsonArray1=(JSONArray)JSONArray.toJSON(userList);JSONObject jsonObject1=(JSONObject)jsonArray1.get(0);System.out.println(jsonObject1.get("name"));}

2.4 JSONPath解析JSON

简介:JsonPath参照Xpath解析xml的方式来解析Json。

运算符含义
$根元素
.子元素
*通配符 任何元素
[]下标运算符
@Test
public void test(){String string = "{\"code\":0,\"data\":{\"kind\":\"Electronics\",\"list\":" +"[{\"name\":\"computer\",\"price\":4500,\"size\":55}," +"{\"name\":\"iphone\",\"price\":6000,\"size\":60}," +"{\"name\":\"watch\",\"price\":8000,\"size\":30}]}}";JSONObject jsonObject = JSON.parseObject(string);System.out.println(JSONPath.eval(jsonObject,"$.data.list[0].name"));//第一个对象的nameSystem.out.println(JSONPath.eval(jsonObject,"$.data.list.name"));//全部对象的nameSystem.out.println(JSONPath.eval(jsonObject,"$.data.list[0,2].name"));//只取第一个和第三个的nameSystem.out.println(JSONPath.eval(jsonObject,"$.data.list[0:2].name"));//取1-3个的name
}

三、Jackson使用

介绍:一种JSON处理的开源工具库,Spring框架中默认使用的Jackson处理JSON
Spring版本兼容问题:jackson-databind 2.11.0及以上版本与spring-boot版本兼容,推荐使用2.11.0及以上版本
maven依赖:在pom.xml文件中引入依赖

com.fasterxml.jackson.corejackson-databind2.11.2

com.fasterxml.jackson.corejackson-core2.11.2

com.fasterxml.jackson.corejackson-annotations2.11.2

核心类:ObjectMapper作为Jackson中最常用的类,提供了Java对象和JSON字符串相互转换的方法

常用方法方法作用
ObjectMapperwriteValueAsStringJSON序列化操作 将Java对象转换为JSON字符串
readValueJSON反序列化操作 将JSON字符串、文件流等转换为Jav对象

3.1 ObjectMapper基本使用

序列化操作:将其他对象转换为JSON字符串

@Test
public void test1() throws JsonProcessingException {ObjectMapper mapper=new ObjectMapper();User user=new User("admin","12","男");System.out.println(mapper.writeValueAsString(user));//输出 {"name":"admin","age":"12","sex":"男"}Map map=new HashMap();map.put("name","admin");map.put("age","12");map.put("sex","男");System.out.println(mapper.writeValueAsString(map));//输出 {"sex":"男","name":"admin","age":"12"}Map dateMap=new HashMap<>();dateMap.put("date",new Date());//默认情况下时间输出时间戳,这里设置时间类型为如下格式mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));System.out.println(mapper.writeValueAsString(dateMap));//输出 {"date":"2022-12-11 13:00:35"}List userList=new ArrayList<>();userList.add(new User("admin","12","男"));userList.add(new User("admin1","13","女"));System.out.println(mapper.writeValueAsString(userList));//输出 [{"name":"admin","age":"12","sex":"男"},{"name":"admin1","age":"13","sex":"女"}]
}

反序列化:将JSON字符串转化为Java对象

@Test
public void test2() throws JsonProcessingException {ObjectMapper mapper=new ObjectMapper();String str="{\"name\":\"admin\",\"age\":\"12\",\"sex\":\"男\"}";User user=mapper.readValue(str, User.class);System.out.println(user);Map map=mapper.readValue(str,Map.class);System.out.println(map);String jsonListString="[{\"name\":\"admin\",\"age\":\"12\",\"sex\":\"男\"},{\"name\":\"admin1\",\"age\":\"13\",\"sex\":\"女\"}]";List userList=mapper.readValue(jsonListString, new TypeReference>() {});System.out.println(userList);
}

3.2 ObjectMapper相关配置及异常场景

常用配置汇总:

ObjectMapper mapper=new ObjectMapper();
/*1.====序列化===*/
mapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);//序列化不为空的值
mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);//如果对象为空不抛出异常
mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));/*3.====反序列化象===*/
//遇到未知属性不报错  设置为false,表示:json中字段多了,不会影响json转Object
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
//为空对象不抛异常    设置为ture时,可以将一个空字符串“”转成一个null。如{“student”:””},其中“student”在反序列化时对应类Student,此时Student的值会被设置为null。
mapper.configure(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT, true);/*解析json时,过滤JSON注释符*/
mapper.configure(JsonParser.Feature.ALLOW_COMMENTS, true);
/*解析JSON时,可以解析属性值为单引号的属性名*/
mapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);
/*解析JSON时,可以解析 属性名没有双引号的非标准json字符串*/
mapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);

场景一:序列化对象属性为空,默认会抛出异常

@Test
public void testConfig1() throws JsonProcessingException {NoUser user=new NoUser();//NoUser类中无任何属性ObjectMapper mapper=new ObjectMapper();System.out.println(mapper.writeValueAsString(user));//抛出异常 com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for....
}@Test
public void testConfig2() throws JsonProcessingException {NoUser user=new NoUser();//NoUser类中无任何属性ObjectMapper mapper=new ObjectMapper();mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS,false);System.out.println(mapper.writeValueAsString(user));//输出{}
}

场景二:序列化对象时,只序列化属性值不为空的属性

@Test
public void testConfig3() throws JsonProcessingException {User user=new User("admin","12",null);ObjectMapper mapper=new ObjectMapper();System.out.println(mapper.writeValueAsString(user));//输出 {"name":"admin","age":"12","sex":null}ObjectMapper objectMapper=new ObjectMapper();objectMapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);System.out.println(objectMapper.writeValueAsString(user));//输出 {"name":"admin","age":"12"}}

场景三:序列化时,时间格式化问题

@Test
public void testConfig6() throws JsonProcessingException {Map dateMap=new HashMap<>();dateMap.put("date",new Date());ObjectMapper objectMapper=new ObjectMapper();System.out.println(objectMapper.writeValueAsString(dateMap));//输出 {"date":1670740657007}ObjectMapper mapper=new ObjectMapper();mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS,false);mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));System.out.println(mapper.writeValueAsString(dateMap));//输出 {"date":"2022-12-11 14:37:37"}
}

场景四:反序列化时,字符串中字段与Java实体类字段不是一一对应

@Test
public void testConfig4() throws JsonProcessingException {String str="{\"name\":\"admin\",\"age\":\"12\",\"sex\":\"男\",\"other\":\"111\"}";ObjectMapper objectMapper=new ObjectMapper();User user=objectMapper.readValue(str,User.class);System.out.println(user);//抛出异常 com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field
}
@Test
public void testConfig5() throws JsonProcessingException {String str="{\"name\":\"admin\",\"age\":\"12\",\"sex\":\"男\",\"other\":\"111\"}";ObjectMapper objectMapper=new ObjectMapper();objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES,false);User user=objectMapper.readValue(str,User.class);System.out.println(user);//输出 User(name=admin, age=12, sex=男)
}

3.3 注解方式配置

注解:除去使用ObjectMapper属性配置化解析json外,还可以通过Jackson的注解来实现配置化解析。

注解注解作用
@JsonProperty字段序列化和反序列化时,转换为另一个名称
@JsonProperty("birth_date")
含义:birthDate字段解析时用birth_date
@JsonFormatDate类型字段序列化和反序列化时 指定类型 例如:
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
@JsonIgnore字段在序列化和反序列化时会被忽略掉
@JsonIgnoreProperties对象序列化和反序列化时,忽略对象的多个属性
@JsonInclude注解放在类上,则决定解析什么字段
@JsonInclude(JsonInclude.Include.NON_EMPTY)
类下所有字段属性为 空("") 或者为 NULL 都不序列化

四、Gson使用

maven依赖:在pom.xml文件中引入依赖

com.google.code.gsongson2.8.2

序列化操作

@Test
public void toJsonTest(){Gson gson=new Gson();User user=new User("admin","12","男");System.out.println(gson.toJson(user));//输出 {"name":"admin","age":"12","sex":"男"}Map map=new HashMap();map.put("name","admin");map.put("age","12");map.put("sex","男");System.out.println(gson.toJson(map));//输出 {"sex":"男","name":"admin","age":"12"}Map dateMap=new HashMap<>();dateMap.put("date",new Date());System.out.println(gson.toJson(dateMap));//输出 {"date":"Dec 11, 2022 3:13:57 PM"}List userList=new ArrayList<>();userList.add(new User("admin","12","男"));userList.add(new User("admin1","13","女"));System.out.println(gson.toJson(userList));//输出 [{"name":"admin","age":"12","sex":"男"},{"name":"admin1","age":"13","sex":"女"}]
}

反序列化操作

@Test
public void fromJsonTest() {Gson gson=new Gson();String str="{\"name\":\"admin\",\"age\":\"12\",\"sex\":\"男\"}";User user=gson.fromJson(str, User.class);System.out.println(user);//输出 User(name=admin, age=12, sex=男)Map map=gson.fromJson(str,Map.class);System.out.println(map);//输出 {name=admin, age=12, sex=男}String jsonListString="[{\"name\":\"admin\",\"age\":\"12\",\"sex\":\"男\"},{\"name\":\"admin1\",\"age\":\"13\",\"sex\":\"女\"}]";//TypeToken是Gson类库提供的一个对象,可以把将要被反序列化的集合的泛型作为TypeToken的参数指定到TypeToken里面List userList=gson.fromJson(jsonListString, new TypeToken>(){}.getType());System.out.println(userList);//输出 [User(name=admin, age=12, sex=男), User(name=admin1, age=13, sex=女)]User[] userArray=gson.fromJson(jsonListString,User[].class);System.out.println(userArray[0].getName());//输出 admin
}

相关内容

热门资讯

监控摄像头接入GB28181平... 流程简介将监控摄像头的视频在网站和APP中直播,要解决的几个问题是:1&...
Windows10添加群晖磁盘... 在使用群晖NAS时,我们需要通过本地映射的方式把NAS映射成本地的一块磁盘使用。 通过...
protocol buffer... 目录 目录 什么是protocol buffer 1.protobuf 1.1安装  1.2使用...
在Word、WPS中插入AxM... 引言 我最近需要写一些文章,在排版时发现AxMath插入的公式竟然会导致行间距异常&#...
【PdgCntEditor】解... 一、问题背景 大部分的图书对应的PDF,目录中的页码并非PDF中直接索引的页码...
Fluent中创建监测点 1 概述某些仿真问题,需要创建监测点,用于获取空间定点的数据࿰...
educoder数据结构与算法...                                                   ...
MySQL下载和安装(Wind... 前言:刚换了一台电脑,里面所有东西都需要重新配置,习惯了所...
修复 爱普生 EPSON L4... L4151 L4153 L4156 L4158 L4163 L4165 L4166 L4168 L4...
MFC文件操作  MFC提供了一个文件操作的基类CFile,这个类提供了一个没有缓存的二进制格式的磁盘...