json精讲

本文介绍json的规范及javascript和java对数据的交换读取

  • 1. json介绍
    • 1.1 json简介
    • 1.2为什么使用 JSON?
  • 2. json规范
    • 2.1基础规范
    • 2.2 key值为-字符串、数字、布尔值
    • 2.3 key值为对象Object
    • 2.4 key值为数组
    • 2.5 json本身就是一个数组
  • 3.javascript操作json
    • 3.1 javascript操作json对象
    • 3.2 js操作json字符串,把字符串转化为json对象
    • 3.3 键值为null或者键不存在判断
    • 3.4json对象转字符串
  • 4.java操作json
    • 4.1准备两个比较全面的VO类
    • 4.1 FastJson介绍
      • 4.1.1引入依赖
      • 4.1.2 vo基础解析
      • 4.1.3 把null的字段全部传递过来,值显示为null
      • 4.1.4 字符串类型的null处理成""
      • 4.1.5 数字、布尔、数组/list、日期null处理
      • 4.1.5 把null全部转化成""
      • 4.1.6日期转换
      • 4.1.7 map处理
      • 4.1.8 list处理
      • 4.1.9 总结
      • 4.1.10 json转java对象
    • 4.2 Gson介绍
      • 4.2.1引入依赖
      • 4.2.2 vo基础解析
      • 4.2.3 把值为null的传递出去
      • 4.2.4 toJson支持对象所有属性转化
      • 4.2.5处理null-空值
      • 4.2.6 日期处理
      • 4.2.7 list和 map处理
      • 4.2.8 JSON转java对象
    • 4.3 Jackson介绍
      • 4.3.1引入依赖
      • 4.3.2 vo基础解析
      • 4.3.3全局配置
      • 4.3.4 支持vo里所有复杂属性的转化
      • 4.4.5 把null全部转化成""
      • 4.4.6日期处理
      • 4.4.7 list处理
      • 4.4.8 map处理
      • 4.3.9 json转vo
    • 4.4解析总结
    • 4.5调调用第三方接口json解析

1. json介绍

1.1 json简介

JSON(JavaScript Object Notation, JS对象简谱)是一种轻量级的数据交换格式。
它基于 ECMAScript(European Computer Manufacturers Association, 欧洲计算机协会制定的js规范)的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。
简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。
易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。

1.2为什么使用 JSON?

对于 AJAX 应用程序来说,JSON 比 XML 更快更易使用:
使用 XML

  • 读取 XML 文档
  • 使用 XML DOM 来循环遍历文档
  • 读取值并存储在变量中

使用 JSON

  • 读取 JSON 字符串
  • 用 eval() 处理 JSON 字符串

2. json规范

2.1基础规范

eg:

{
"name":"蒋增奎","address":"天府大道","age":30, "isMoney":true
}

规范说明:

  • json内容需要用花括号{}包裹起来
  • 键值对用:间隔,多个键,中间用逗号隔离,最后一个键不需要逗号
  • 键key如果没有特殊符号,可以不用双引号包围。
  • 值的类型,包括字符串、数字、布尔值、对象、数组五种类型,前三种最常见

key可以不需要双引号如:

2.2 key值为-字符串、数字、布尔值

{
name:"蒋增奎",address:"天府大道",age:30, isMoney:true
}

2.3 key值为对象Object

嵌套就是json对象里面又包含对象,key对应的值,除了括字符串、数字、布尔值三种类型外,还可以是一个对象,其规范是
key:{对象属性}

  var obj4 = {name: "雪邦科技",boss: {name: "蒋增奎--",age: 40,},};

2.4 key值为数组

数组用方括号包围一起来[x1,x2,x3],分组之间用逗号隔离
数组值有两种类型:
1.基本类型:如[1,2,3]
2.json对象,json对象要用{}包裹

//---------------------------------------------var obj2={wifes: ["冰冰", "雅致"],  //基础类型,对应后端是一个基础类型的数组或者list"user":[ //是一个对象,对应后都是一个对象的数组或者List{"name":"jzk","sex":20},{"name":"jj","sex":30},],"address":[{"shen":"云南","city":"昆明"},{"shen":"四川","city":"雅安"},]};
//---------------------------------------------var obj3={"name":"雪邦科技","address":"天府大道",
"employees": [{ "firstName":"Bill" , "lastName":"Gates" },{ "firstName":"George" , "lastName":"Bush" },{ "firstName":"Thomas" , "lastName":"Carter" }
]
}

2.5 json本身就是一个数组

有两种类型:
1.基本类型数组:[3,2,1]
2.对象的数组:[{x1},{x2},{x3},] 对象要用{}包括

var obj1=[{"name":"蒋增奎","address":"天府大道","sex":30},{"name":"奎奎","address":"大道","sex":38},];var obj2=[1,2,3];

3.javascript操作json

语法:

  1. 把json赋值一个给一本变量,通过变量直接用对象名.key就可以读取
  2. 如果是数组,则可以循环,obj[i]读取
  3. 如果key值为对象,直接用:对象名.key.属性读取
  4. 如果要修改值,直接用对象名.key=xxx则可以修改

3.1 javascript操作json对象

eg:

 <script>function dd() {//1.基本属性读取=========================var obj = {name: "蒋增奎1",address: "天府大道",sex: 30,exist: true,};alert(obj.name);obj.name = "jzk"; //改变属性值//2.key值为对象==========================var obj4 = {name: "雪邦科技",boss: {name: "蒋增奎--",age: 40,},};alert("obj4.boss.name=" + obj4.boss.name);//3.json本身是一个数组====================var obj1 = [{ name: "蒋增奎", address: "天府大道", sex: 30 },{ name: "奎奎", address: "大道", sex: 38 },];//循环读取for (index in obj1) {alert("数组[" +index +"]=" +obj1[index].name +"-" +obj1[index].address +"-" +obj1[index].sex);}//4.key值是一个数组var company = {name: "雪邦",address: "天府大道1号",boss: "蒋增奎",exist: true,tax: 5000,users: [{ name: "蒋增奎", sex: "男", mobile: "13688006645" },{ name: "张三", sex: "女", mobile: "13688006640" },],};var users = company.users;for (index in users) {alert("company.users数组[" +index +"]=" +users[index].name +"-" +users[index].mobile +"-" +users[index].sex);}}</script>

3.2 js操作json字符串,把字符串转化为json对象

有两种写法:
(1)JSON.parse(字符串)
(2) eval (“(” + txt + “)”);

eg:

   <script>function dd() {//1.eval((json字符串))语法转换成json对象var s = '{"name":"蒋增奎","address":"天府大道","sex":30}';s = "(" + s + ")";var obj5 = eval(s);alert(obj5.sex);// 2.JSON.parse(json字符串)语法转换成json对象var txt ='{ "sites" : [' +'{ "name":"菜鸟教程" , "url":"www.runoob.com" },' +'{ "name":"google" , "url":"www.google.com" },' +'{ "name":"微博" , "url":"www.weibo.com" } ]}';var obj6 = JSON.parse(txt);alert(obj6.sites[0].name);}</script>

3.3 键值为null或者键不存在判断

如果键值为null.可以直接用:obj.sex == null判断
如果键不存在,用:typeof obj.deptId == "undefined"判断

function dd2() {var obj = {name: "蒋增奎1",address: "天府大道",sex: null,exist: true,deptId: 3,};//如果获取得一个键key本身不存在if (!obj.deptId) {alert("不存在obj.deptId");}if (obj.deptId == null) {alert("不存在obj.deptId");}alert(obj.deptId);//存在key,但值为nullif (!obj.sex) {alert("不存在obj.sex");}//存在key,但值为nullif (obj.sex == null) {alert("obj.sex==null");}alert(obj.sex);//通过typeof可以判断出是否是null还是key不存在if (typeof obj.deptId == "undefined") {alert("key==deptId不存在");}//排除掉无key和key值为nullif (typeof obj.deptId != "undefined" && obj.deptId) {alert("key==deptId存在并且值不为null");}}

3.4json对象转字符串

var str=JSON.stringify(json对象)

  function dd1() {var obj = { name: "runoob", alexa: 10000, site: "www.runoob.com" };var JSONStr = JSON.stringify(obj);alert(JSONStr);}

4.java操作json

Java中并没有内置JSON的解析,因此使用JSON需要借助第三方类库。
下面是几个常用的 JSON 解析类库:

  • Gson: 谷歌开发的 JSON 库,功能十分全面。
  • FastJson: 阿里巴巴开发的 JSON 库,性能十分优秀。
  • Jackson: 社区十分活跃且更新速度很快。,springMVC默认

4.1准备两个比较全面的VO类

@Data
@NoArgsConstructor
@AllArgsConstructor
public class JsonVO {private Long id;private String name;private BigDecimal weight;//年纪private Date birth;private Date creatTime;private Boolean money;private Address address;private List<Address> addresses;private Map<String,Object> son;private String[] wifes;
}
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Address {private String shen;private String  city;
}

4.1 FastJson介绍

4.1.1引入依赖

 <dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.47</version></dependency>

4.1.2 vo基础解析

最基础,直接调用JSON.toJSONString(vo);
/**
* 问题:
* 1.vo对象属性为null不会传递
* 2.日期转化成时间戳数字
*
*/

    @Testpublic void test2(){//--------------vo转json-------------JsonVO vo=new JsonVO();vo.setId(1l);vo.setBirth(new Date());String jsonString = JSON.toJSONString(vo);System.out.println("只传vo对象:"+jsonString);}

打印效果

只传vo对象:{"birth":1701706009427,"id":1}

4.1.3 把null的字段全部传递过来,值显示为null

传入参数:SerializerFeature.WriteMapNullValue
问题:前端需要去处理null

 @Testpublic void test3(){JsonVO vo=new JsonVO();vo.setId(1l);vo.setBirth(new Date());String jsonString = "";jsonString = JSON.toJSONString(vo,SerializerFeature.WriteMapNullValue);System.out.println(jsonString);}

效果

{"addresses":null,"birth":1701707310898,"creatTime":null,"id":1,
"money":null,"name":null,"weight":null}

4.1.4 字符串类型的null处理成""

null的字符串类型能传递,并转化成""
问题:
1.日期和自定义对象依然显示为nul
2.数组、list、数字、boolean无法传递

@Testpublic void test4(){JsonVO vo=new JsonVO();vo.setId(1l);vo.setBirth(new Date());String jsonString = "";jsonString = JSON.toJSONString(vo,SerializerFeature.WriteNullStringAsEmpty    //字符串为null的转化为"");System.out.println(jsonString);}

效果

{"address":null,"birth":1701708039585,"creatTime":null,"id":1,"name":""}

4.1.5 数字、布尔、数组/list、日期null处理

SerializerFeature.WriteNullStringAsEmpty, //字符串为null的转化为""
SerializerFeature.WriteNullNumberAsZero, //数字为null转化为0
SerializerFeature.WriteNullListAsEmpty, //数组、list为null的转化成[]
SerializerFeature.WriteNullBooleanAsFalse,//布尔值为null转化成false
SerializerFeature.WriteDateUseDateFormat //日期把时间戳格式化
问题
1.日期、自定义的对象依然为null
2.如果数字0,和布尔值false有意义,前端区分不出来
3.日期区分不出来是时间还是日期

 @Testpublic void test5(){JsonVO vo=new JsonVO();vo.setId(1l);vo.setBirth(new Date());String jsonString = "";jsonString = JSON.toJSONString(vo,SerializerFeature.WriteNullStringAsEmpty,    //字符串为null的转化为""SerializerFeature.WriteNullNumberAsZero,   //数字为null转化为0SerializerFeature.WriteNullListAsEmpty,   //数组、list为null的转化成[]SerializerFeature.WriteNullBooleanAsFalse,//布尔值为null转化成falseSerializerFeature.WriteDateUseDateFormat   //日期把时间戳格式化);System.out.println(jsonString);}

效果

{"address":null,"addresses":[],"birth":"2023-12-05 00:51:55",
"creatTime":null,"id":1,"money":false,"name":"","weight":0}

4.1.5 把null全部转化成""

重写过滤器,拦截null的,全部置换成""
问题:
1.前端如果有数字计算,要去转化
2.如果自定义对象,数组等,需要先判断""再做相关操作

过滤器

public class JsonUtil {/*** 过滤器,把null全部转化成空字符串* @return*/public static ValueFilter  getFilter(){ValueFilter filter = new ValueFilter() {@Overridepublic Object process(Object obj, String s, Object v) {// System.out.println(s);if(v==null)return "";return v;}};return filter;}
}

解析

{
"address":"","addresses":"","birth":1701709403555,"creatTime":"","id":1,
"money":"","name":"","weight":""
}

4.1.6日期转换

采用注解的方式,可以解析出日期和时间两种,此方法最完美
在日期变量属性上加:
@JSONField(format=“yyyy-MM-dd”)或者
@JSONField(format=“yyyy-MM-dd HH:mm:ss”)

vo

@Data
@NoArgsConstructor
@AllArgsConstructor
public class JsonVO {private Long id;private String name;private BigDecimal weight;//年纪@JSONField(format="yyyy-MM-dd")private Date birth;@JSONField(format="yyyy-MM-dd HH:mm:ss")private Date creatTime;private Boolean money;private Address address;private List<Address> addresses;}

测试

  @Testpublic void test7(){JsonVO vo=new JsonVO();vo.setId(1l);vo.setBirth(new Date());vo.setCreatTime(new Date());String jsonString = "";jsonString = JSON.toJSONString(vo);System.out.println(jsonString);}

效果

{"birth":"2023-12-05","creatTime":"2023-12-05 01:07:51","id":1}

4.1.7 map处理

@Test@Testpublic void test8(){Map<String,Object> map=new HashMap<String,Object>();map.put("name","jzk");map.put("id",1);map.put("sex",null);String jsonString = "";jsonString = JSON.toJSONString(map,JsonUtil.getFilter());System.out.println(jsonString);}

效果:

{"sex":"","name":"jzk","id":1}

4.1.8 list处理

不需要特殊处理

 @Testpublic void test9(){List<Address> list=new ArrayList<>();list.add(new Address("四川","成都"));list.add(new Address("四川","简阳"));list.add(new Address());String jsonString = "";jsonString = JSON.toJSONString(list,JsonUtil.getFilter());System.out.println(jsonString);}

效果:

[{"city":"成都","shen":"四川"},{"city":"简阳","shen":"四川"},{"city":"","shen":""}]

4.1.9 总结

用过滤器还是最简单

4.1.10 json转java对象

采用语法VO vo=JSON.parseObject(jsonStr,VO.class);
如果key是"",其他对象可以转化成null
这里有两个特殊的:

  1. 数组转化成list
    要用JSON.parseArray来转化,JSONArray 本身也是一个数组
    2.数组转化成map
方法说明
SON.parseObject(jsonStgr,映射类.class);json和一个类对应,不管这个vo类里属性有多复杂,都能映射上
Map<String,Object> map=JSON.parseObject(jsonStgr,Map.class);和map对象的映射
JSONArray jsonArray = JSONArray.parseArray(jsonStgr);返回一个数组,json本身也是一个数组
List< VO > list=JSON.parseArray(jsonStgr,VO.class);映射到一个List< VO > 列表里
  @Testpublic void test33(){String txt="{'address':'','addresses':'','birth':'2023-12-05','creatTime':'','id':1,'money':'','name':'','weight':''}";JsonVO vo= JSON.parseObject(txt,JsonVO.class);System.out.println(vo);//json有,但vo没有的字段,不报错,//waihao这个属性,vo对象里没有txt="{'name':'jzk','waihao':'李富贵'}";vo= JSON.parseObject(txt,JsonVO.class);System.out.println(vo);//自定义对象txt="{'address':{'city':'cd','shen':'sc'},'addresses':'','birth':'2023-12-05','creatTime':'','id':1,'money':'','name':'','weight':''}";vo= JSON.parseObject(txt,JsonVO.class);//数组txt="{'address':'','addresses':[{'city':'cd','shen':'sc'},{'city':'my','shen':'sc'}],'birth':'2023-12-05','creatTime':'','id':1,'money':'','name':'','weight':''}";vo= JSON.parseObject(txt,JsonVO.class);System.out.println(vo);//数组txt="{'address':'','addresses':[{'city':'cd','shen':'sc'},{'city':'my','shen':'sc'}],'birth':'2023-12-05','creatTime':'','id':1,'money':'','name':'','weight':''}";vo= JSON.parseObject(txt,JsonVO.class);System.out.println(vo);//-------------------特殊数据类型---------------------//纯数组转listtxt="[{'city':'成都','shen':'四川'},{'city':'简阳','shen':'四川'},{'city':'','shen':''}]";List<Address> list=JSON.parseArray(txt,Address.class);for (Address a:list){System.out.println(a);}//数组转数组,数组转数组没有直接方法,需要用JSONArray来过渡System.out.println("数组转数组");txt="[{'city':'成都','shen':'四川'},{'city':'简阳','shen':'四川'},{'city':'','shen':''}]";JSONArray jsonArray = JSONArray.parseArray(txt);Address[] ss=new Address[jsonArray.size()];for(int i=0;i<jsonArray.size();i++){Address address=jsonArray.getObject(i,Address.class);ss[i]=address;}for (Address address:ss){System.out.println(address);}//str转maptxt="{'city':'成都','shen':'四川'}";Map<String,Object> map=JSON.parseObject(txt,Map.class);for(String key:map.keySet()){String value = map.get(key).toString();System.out.println("key="+key+" vlaue="+value);}}

4.2 Gson介绍

4.2.1引入依赖

  <dependency><groupId>com.google.code.gson</groupId><artifactId>gson</artifactId><version>2.8.5</version></dependency></dependencies>

4.2.2 vo基础解析

最基础,直接调
Gson gson = new Gson();
String jsonStr=gson.toJson(vo,JsonVO.class);
/**
* 问题:
* 1.vo对象属性为null不会传递
* 2.日期转化成没有格式化
*
*/

@Testpublic void t1(){Gson gson = new Gson();JsonVO vo=new JsonVO();vo.setName("jzk");vo.setBirth(new Date());String jsonStr=gson.toJson(vo,JsonVO.class);System.out.println(jsonStr);}

效果

{"name":"jzk","birth":"Dec 6, 2023 9:51:56 PM"}

4.2.3 把值为null的传递出去

这里是GsonBuilder来创建Gson对象
Gson gson = new GsonBuilder().serializeNulls().create();
这样获得全部null

@Testpublic void t2(){Gson gson = new GsonBuilder().serializeNulls().create();JsonVO vo=new JsonVO();// vo.setName("jzk");vo.setId(2l);vo.setBirth(new Date());String  jsonStr=gson.toJson(vo,JsonVO.class);System.out.println(jsonStr);}

效果

{
"id":2,"name":null,"weight":null,"birth":"Dec 6, 2023 9:54:19 PM",
"creatTime":null,"money":null,"address":null,
"addresses":null,"son":null,"wifes":null
}

4.2.4 toJson支持对象所有属性转化

public JsonVO getAllVo(){JsonVO vo=new JsonVO();vo.setName("jzk");vo.setBirth(new Date());vo.setId(1l);vo.setCreatTime(new Date());vo.setMoney(true);vo.setWeight(new BigDecimal("20.56"));vo.setAddress(new Address("四川","成都"));List<Address> list=new ArrayList<Address>();list.add(new Address("四川","绵阳"));list.add(new Address("四川","简阳"));vo.setAddresses(list);Map<String,Object> son=new HashMap<>();son.put("name","将填好");son.put("sex","1");vo.setSon(son);vo.setWifes(new String[]{"冰冰","雅致"});return vo;}@Testpublic void t3(){Gson gson = new Gson();JsonVO vo=getAllVo();String  jsonStr=gson.toJson(vo,JsonVO.class);System.out.println(jsonStr);}

效果

{
"id":1,"name":"jzk","weight":20.56,"birth":"Dec 6, 2023 9:57:35 PM",
"creatTime":"Dec 6, 2023 9:57:35 PM","money":true,
"address":{"shen":"四川","city":"成都"},
"addresses":
[
{"shen":"四川","city":"绵阳"},{"shen":"四川","city":"简阳"}
],
"son":{"sex":"1","name":"将填好"},
"wifes":["冰冰","雅致"]
}

4.2.5处理null-空值

GsonBuilder.registerTypeAdapter注册,进行重写

帮助类

public class GsonUtil {public static Gson getGson(){Gson gson =new  GsonBuilder().serializeNulls()   //null全部显示.registerTypeAdapter(String.class,new StringAdapter())  //空字符串处理"".registerTypeAdapter(Long.class,new LongAdapter())  //Long字段处理成"".registerTypeAdapter(Integer.class,new IntegerAdapter()) //Integer.registerTypeAdapter(BigDecimal.class,new BigDecimalAdapter()) //BigDecimal.registerTypeAdapter(Date.class,new DateAdapter()) //Date.registerTypeAdapter(Boolean.class,new BooleanAdapter())//Boolean.create();return gson;}/*** 字符串为""*/public static class StringAdapter extends TypeAdapter<String> {@Overridepublic void write(JsonWriter jsonWriter, String s) throws IOException {if (s == null) {//序列化使用的是adapter的write方法//jsonWriter.nullValue();//这个方法是错的,而是应该将null转成""jsonWriter.value("");return;}jsonWriter.value(s);}@Overridepublic String read(JsonReader jsonReader) throws IOException {if (jsonReader.peek() == JsonToken.NULL) {//反序列化使用的是read方法jsonReader.nextNull();return null;}return jsonReader.nextString();}}/*** Long null为""*/public static class LongAdapter extends TypeAdapter<Long> {@Overridepublic void write(JsonWriter jsonWriter, Long s) throws IOException {if (s == null) {//序列化使用的是adapter的write方法//jsonWriter.nullValue();//这个方法是错的,而是应该将null转成""jsonWriter.value("");return;}jsonWriter.value(s);}@Overridepublic Long read(JsonReader jsonReader) throws IOException {if (jsonReader.peek() == JsonToken.NULL) {//反序列化使用的是read方法jsonReader.nextNull();return null;}return jsonReader.nextLong();}}/*** Double*/public static class DoubleAdapter extends TypeAdapter<Double> {@Overridepublic void write(JsonWriter jsonWriter, Double s) throws IOException {if (s == null) {//序列化使用的是adapter的write方法//jsonWriter.nullValue();//这个方法是错的,而是应该将null转成""jsonWriter.value("");return;}jsonWriter.value(s);}@Overridepublic Double read(JsonReader jsonReader) throws IOException {if (jsonReader.peek() == JsonToken.NULL) {//反序列化使用的是read方法jsonReader.nextNull();return null;}return jsonReader.nextDouble();}}/*** Boolean*/public static class BooleanAdapter extends TypeAdapter<Boolean> {@Overridepublic void write(JsonWriter jsonWriter, Boolean s) throws IOException {if (s == null) {//序列化使用的是adapter的write方法//jsonWriter.nullValue();//这个方法是错的,而是应该将null转成""jsonWriter.value("");return;}jsonWriter.value(s);}@Overridepublic Boolean read(JsonReader jsonReader) throws IOException {if (jsonReader.peek() == JsonToken.NULL) {//反序列化使用的是read方法jsonReader.nextNull();return null;}return jsonReader.nextBoolean();}}/*** BigDecimal*/public static class BigDecimalAdapter extends TypeAdapter<BigDecimal> {@Overridepublic void write(JsonWriter jsonWriter, BigDecimal s) throws IOException {if (s == null) {//序列化使用的是adapter的write方法//jsonWriter.nullValue();//这个方法是错的,而是应该将null转成""jsonWriter.value("");return;}jsonWriter.value(s);}@Overridepublic BigDecimal read(JsonReader jsonReader) throws IOException {if (jsonReader.peek() == JsonToken.NULL) {//反序列化使用的是read方法jsonReader.nextNull();return null;}return new BigDecimal(jsonReader.nextString());}}/*** Integer*/public static class IntegerAdapter extends TypeAdapter<Integer> {@Overridepublic void write(JsonWriter jsonWriter, Integer s) throws IOException {if (s == null) {//序列化使用的是adapter的write方法//jsonWriter.nullValue();//这个方法是错的,而是应该将null转成""jsonWriter.value("");return;}jsonWriter.value(s);}@Overridepublic Integer read(JsonReader jsonReader) throws IOException {if (jsonReader.peek() == JsonToken.NULL) {//反序列化使用的是read方法jsonReader.nextNull();return  null;}return jsonReader.nextInt();}}/*** Integer*/public static class DateAdapter extends TypeAdapter<Date> {@Overridepublic void write(JsonWriter jsonWriter, Date s) throws IOException {if (s == null) {//序列化使用的是adapter的write方法//jsonWriter.nullValue();//这个方法是错的,而是应该将null转成""jsonWriter.value("");return;}String temp=getStrByDate(s,"yyy-MM-dd HH:mm:ss");if(temp.indexOf("00:00:00")!=-1){temp=temp.substring(0,temp.indexOf("00:00:00"));temp= temp.trim();}jsonWriter.value(temp);}@Overridepublic Date read(JsonReader jsonReader) throws IOException {if (jsonReader.peek() == JsonToken.NULL) {//反序列化使用的是read方法jsonReader.nextNull();return null;}//  return jsonReader.nextString();System.out.println("jsonReader.nextString()="+jsonReader.nextString());return getDateByStr(jsonReader.nextString(),"yyy-MM-dd HH:mm:ss");}}private static String getStrByDate(Date date,String gs){if(date==null)return "";DateFormat df = new SimpleDateFormat(gs);return  df.format(date);}private static Date getDateByStr(String dateStr,String gs){if(dateStr==null || dateStr.trim().length()==0)return null;DateFormat df = new SimpleDateFormat(gs);try{return df.parse(dateStr);}catch(ParseException e){throw new RuntimeException("日期转换出错:"+e);}}}

代码

@Testpublic void t4(){Gson gson= GsonUtil.getGson();//然后用上面一行写的gson来序列化和反序列化实体类typeJsonVO vo=new JsonVO();// vo.setName("jzk");// vo.setId(2l);//设置一个没有时间的日期vo.setBirth(DateUtil.getDateByStr("2022-10-01",DateUtil.date_gs));String  jsonStr=gson.toJson(vo,JsonVO.class);System.out.println(jsonStr);}

效果

{"id":"","name":"","weight":"","birth":"2022-10-01",
"creatTime":"","money":"","address":null,"addresses":null,
"son":null,"wifes":null,"birth2":null}

4.2.6 日期处理

有三种方式:
1.GsonBuilder…setDateFormat(“yyyy-MM-dd HH:mm:ss”) //设置日期转换
问题:对象里的所有日期只能用一种格式
2.自定义一个类日期属性的注解【如FastJson,Gson没有自带日期注解】
3.做一个TypeAdapter的实现类,自己写(看上文GsonUtil.java里面的代码)

@Testpublic void t6(){//通过setDateFormat来设置日期格式,问题:所有数据都设置成了一种格式//gson没有提供注解,可以自定义一个注解,处理VO对象里有日期和时间两个字段Gson gson  = new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss") //设置日期转换.create();JsonVO vo=new JsonVO();// vo.setName("jzk");// vo.setId(2l);vo.setBirth(new Date());vo.setCreatTime(new Date());String  jsonStr=gson.toJson(vo,JsonVO.class);System.out.println(jsonStr);}

效果:

{"birth":"2023-12-06 23:57:12","creatTime":"2023-12-06 23:57:12"}

4.2.7 list和 map处理

gson.toJson(list,ArrayList.class);
gson.toJson(map,HashMap.class);

 @Testpublic void t33(){Gson gson = new Gson();List<Address> list=new ArrayList<Address>();list.add(new Address("四川","绵阳"));list.add(new Address("四川","简阳"));String  jsonStr=gson.toJson(list,ArrayList.class);System.out.println(jsonStr);Map<String,Object> map=new HashMap();map.put("name","jzk");map.put("address","天赋达到");jsonStr=gson.toJson(map,HashMap.class);System.out.println(jsonStr);}

效果

[{"shen":"四川","city":"绵阳"},{"shen":"四川","city":"简阳"}]
{"address":"天赋达到","name":"jzk"}

4.2.8 JSON转java对象

1.json转vo对象
JsonVO vo=new Gson().fromJson(jsonStr,JsonVO.class);
2.json转list< vo >
Type type = new TypeToken<List< Address>>(){}.getType();//获取转化类型
List< Address> list=new Gson().fromJson(json,type)
3.json转map
Map<String,String> map = new Gson().fromJson(json, Map.class);

@Testpublic void toVo(){//有null的数据String json="{'id':2,'name':null,'weight':null,'birth':'2023-10-23','creatTime':null,'money':null,'address':null,'addresses':null,'son':null,'wifes':null}";JsonVO vo=new Gson().fromJson(json,JsonVO.class);System.out.println(vo);//所有数据都有值
json="{'id':1,'name':'jzk','weight':20.56,'birth':'2021-10-11','creatTime':'2023-10-01 12:23:23','money':true,'address':{'shen':'四川','city':'成都'},'addresses':[{'shen':'四川','city':'绵阳'},{'shen':'四川','city':'简阳'}],'son':{'sex':'1','name':'将填好'},'wifes':['冰冰','雅致']}";vo =new Gson().fromJson(json,JsonVO.class);System.out.println(vo);//json有,vo对象没有字段,不报错json="{'id':2,'waihao':'黑旋风'}";  //waihao这个属性,vo没有vo=new Gson().fromJson(json,JsonVO.class);System.out.println(vo);//纯List转换json="[{'shen':'四川','city':'绵阳'},{'shen':'四川','city':'简阳'}]";Type type = new TypeToken<List<Address>>(){}.getType();//获取转化类型List<Address> list=new Gson().fromJson(json,type);for(Address a:list){System.out.println(a);}//map转换json="{'shen':'四川','city':'绵阳'}";Map<String,String> map = new Gson().fromJson(json, Map.class);for(String key:map.keySet()){String value = map.get(key).toString();System.out.println("key="+key+" vlaue="+value);}}

4.3 Jackson介绍

4.3.1引入依赖

  <dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.9.1</version></dependency>

4.3.2 vo基础解析

String str=new ObjectMapper()…writeValueAsString(解析对象);
问题:
1.全部null都会传递过来
2.时间展示是时间戳格式

 @Testpublic void t1() throws JsonProcessingException {JsonVO vo=new JsonVO();vo.setId(2l);vo.setBirth(new Date());ObjectMapper mapper=new ObjectMapper();String jsonStr="";jsonStr=mapper.writeValueAsString(vo);System.out.println(jsonStr);}

效果

{"id":2,"name":null,"weight":null,"birth":1701912127118,"creatTime":null,
"money":null,"address":null,"addresses":null,"son":null,
"wifes":null,"birth2":null}

4.3.3全局配置

//在反序列化时忽略在 json 中存在但 Java 对象不存在的属性
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
//在序列化时日期格式默认为 yyyy-MM-dd’T’HH:mm:ss.SSSZ
mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
//在序列化时自定义时间日期格式
mapper.setDateFormat(new SimpleDateFormat(“yyyy-MM-dd HH:mm:ss”));
//在序列化时忽略值为 null 的属性
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
//在序列化时忽略值为默认值的属性
mapper.setDefaultPropertyInclusion(JsonInclude.Include.NON_DEFAULT);
//在反序列时,配置允许单引号,否则json里面的单引号如: ‘name’:'jzk’会报错
mapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);

//输出json格式化,调试的时候可使用,增加易读性
mapper.writerWithDefaultPrettyPrinter()

4.3.4 支持vo里所有复杂属性的转化

@Testpublic void t2()throws JsonProcessingException {ObjectMapper mapper=new ObjectMapper();JsonVO vo=getAllVo();String jsonStr="";jsonStr=mapper.writerWithDefaultPrettyPrinter().writeValueAsString(vo);System.out.println(jsonStr);}public JsonVO getAllVo(){JsonVO vo=new JsonVO();vo.setName("jzk");vo.setBirth(new Date());vo.setId(1l);vo.setCreatTime(new Date());vo.setMoney(true);vo.setWeight(new BigDecimal("20.56"));vo.setAddress(new Address("四川","成都"));List<Address> list=new ArrayList<Address>();list.add(new Address("四川","绵阳"));list.add(new Address("四川","简阳"));vo.setAddresses(list);Map<String,Object> son=new HashMap<>();son.put("name","将填好");son.put("sex","1");vo.setSon(son);vo.setWifes(new String[]{"冰冰","雅致"});vo.setBirth2(java.sql.Date.valueOf("2012-10-01"));return vo;}

效果

{"id" : 1,"name" : "jzk","weight" : 20.56,"birth" : 1701917471582,"creatTime" : 1701917471582,"money" : true,"address" : {"shen" : "四川","city" : "成都"},"addresses" : [ {"shen" : "四川","city" : "绵阳"}, {"shen" : "四川","city" : "简阳"} ],"son" : {"sex" : "1","name" : "将填好"},"wifes" : [ "冰冰", "雅致" ],"birth2" : 1349020800000
}

4.4.5 把null全部转化成""

重写setNullValueSerializer()方法

@Testpublic void t4() throws JsonProcessingException {ObjectMapper mapper=new ObjectMapper();mapper.getSerializerProvider().setNullValueSerializer(new JsonSerializer<Object>() {@Overridepublic void serialize(Object paramT,JsonGenerator paramJsonGenerator, SerializerProvider paramSerializerProvider) throws IOException, JsonProcessingException {paramJsonGenerator.writeString("");}});JsonVO vo=new JsonVO();vo.setId(2l);vo.setBirth(new Date());String jsonStr="";jsonStr=mapper.writerWithDefaultPrettyPrinter().writeValueAsString(vo);System.out.println(jsonStr);}

效果:

{"id" : 2,"name" : "dddddd","weight" : "","birth" : 1701917789597,"creatTime" : "","money" : "","address" : "","addresses" : "","son" : "","wifes" : "","birth2" : ""
}

4.4.6日期处理

日期处理有两种方式:
1.在对象属性上配置注解
@JsonFormat(timezone = “GMT+8”, pattern = “yyyy-MM-dd”)
@JsonFormat(timezone = “GMT+8”, pattern = “yyyy-MM-dd HH:mm:ss”)
2.jackson配置类上使用
mapper.setDateFormat(new SimpleDateFormat(“yyyy-MM-dd”));
因为注解大于配置,如果yyyy-MM-dd比较多,setDateFormat配置"yyyy-MM-dd",注解只使用带时分秒的。
省略掉配置日期的注解

代码
vo

ublic class JsonVO {private Long id;private String nameprivate BigDecimal weight;//年纪@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd")private Date birth;@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")private Date creatTime;

解析

public void t5() throws JsonProcessingException {ObjectMapper mapper=new ObjectMapper();//在序列化时自定义时间日期格式mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd"));JsonVO vo=new JsonVO();vo.setId(2l);vo.setBirth(new Date());vo.setBirth2(java.sql.Date.valueOf("2012-12-01"));vo.setCreatTime(new Date());String jsonStr="";jsonStr=mapper.writerWithDefaultPrettyPrinter().writeValueAsString(vo);System.out.println(jsonStr);
}

效果

{"id" : 2,"name" : "dddddd","weight" : null,"birth" : "2023-12-07","creatTime" : "2023-12-07 11:54:14","money" : null,"address" : null,"addresses" : null,"son" : null,"wifes" : null,"birth2" : "2012-12-01"
}

4.4.7 list处理

默认支持list参数

@Testpublic void t6() throws JsonProcessingException {ObjectMapper mapper = new ObjectMapper();List<Address> list=new ArrayList<>();list.add(new Address("四川","成都"));list.add(new Address("四川","简阳"));list.add(new Address());String jsonInString = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(list);System.out.println(jsonInString);}

效果

[ {"shen" : "四川","city" : "成都"
}, {"shen" : "四川","city" : "简阳"
}, {"shen" : null,"city" : null
} ]

4.4.8 map处理

默认支持map

@Testpublic void t7() throws JsonProcessingException {ObjectMapper mapper = new ObjectMapper();Map<String,Object> map=new HashMap<>();map.put("address","天府大道");map.put("name","张三丰");String jsonInString = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(map);System.out.println(jsonInString);}

效果

{"address" : "天府大道","name" : "张三丰"
}

4.3.9 json转vo

注意事项:
1.假如json是单引号 ALLOW_SINGLE_QUOTES=true
2.假如json 中存在但 Java 对象不存在的属性 FAIL_ON_UNKNOWN_PROPERTIES=false
否则前两者要报错
3.json转list和map,需要使用constructCollectionType、constructMapType构造器注意对应的class

@Testpublic void t8() throws IOException {ObjectMapper mapper = new ObjectMapper();//允许json用单引号,不是双引号mapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);//在反序列化时忽略在 json 中存在但 Java 对象不存在的属性mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);//1.vo部分有值 okJsonVO vo=new JsonVO();String jsonStr="";jsonStr="{'id':2,'name':'蒋增奎'}";vo=mapper.readValue(jsonStr,JsonVO.class);System.out.println(vo);//2.vo全部有值 okjsonStr="{\"id\":1,\"name\":\"jzk\",\"weight\":20.56,\"birth\":\"2023-12-07\",\"creatTime\":\"2023-12-07 13:44:17\",\"money\":true,\"address\":{\"shen\":\"四川\",\"city\":\"成都\"},\"addresses\":[{\"shen\":\"四川\",\"city\":\"绵阳\"},{\"shen\":\"四川\",\"city\":\"简阳\"}],\"son\":{\"sex\":\"1\",\"name\":\"将填好\"},\"wifes\":[\"冰冰\",\"雅致\"],\"birth2\":\"2023-12-07\"}";vo=mapper.readValue(jsonStr,JsonVO.class);System.out.println(vo);//3.json有,但vo里没有对应属性,要使用//   mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);//引号允许//   mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);jsonStr="{'id':2,'name':'蒋增奎','waihao':'带头大哥'}";vo=mapper.readValue(jsonStr,JsonVO.class);System.out.println(vo);//4.直接转化成list//必须获得一个CollectionType,注入vo.classCollectionType javaType = mapper.getTypeFactory().constructCollectionType(List.class, Address.class);jsonStr="[{\"shen\":\"四川\",\"city\":\"成都\"},{\"shen\":\"四川\",\"city\":\"简阳\"},{\"shen\":null,\"city\":null}]";List<Address> list=mapper.readValue(jsonStr,javaType);System.out.println("list start -----");for (Address a:list){System.out.println(a);}//4.直接转化成map//第二参数是 map 的 key 的类型,第三参数是 map 的 value 的类型MapType mapJavaType = mapper.getTypeFactory().constructMapType(HashMap.class, String.class, Address.class);jsonStr="{\"address2\":{\"shen\":\"四川\",\"city\":\"简阳\"},\"address1\":{\"shen\":\"四川\",\"city\":\"成都\"}}";Map<String,Address> map=mapper.readValue(jsonStr,mapJavaType);for(String key:map.keySet()){Address value = map.get(key);System.out.println("key="+key+" vlaue="+value);}}

4.4解析总结

在这里插入图片描述

4.5调调用第三方接口json解析

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/210702.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2、关于使用ajax验证绕过(实例2)

ajax原理我上一篇有写过&#xff0c;参考&#xff1a;1、关于前端js-ajax绕过-CSDN博客 一、实例环境&#xff1a; 为手机上的某一割韭菜app 二、目的&#xff1a; 实现绕过手机验证码&#xff0c;找回密码 三、工具&#xff1a; bp代理 四、验证步骤如下&#xff1a; …

hive自定义函数及案例

一.自定义函数 1.Hive自带了一些函数&#xff0c;比如&#xff1a;max/min等&#xff0c;但是数量有限&#xff0c;自己可以通过自定义UDF来方便的扩展。 2.当Hive提供的内置函数无法满足你的业务处理需要时&#xff0c;此时就可以考虑使用用户自定义函数。 3.根据用户自定义…

构建外卖系统:使用Django框架

在当今数字化的时代&#xff0c;外卖系统的搭建不再是什么复杂的任务。通过使用Django框架&#xff0c;我们可以迅速建立一个强大、灵活且易于扩展的外卖系统。本文将演示如何使用Django构建一个简单的外卖系统&#xff0c;并包含一些基本的技术代码。 步骤一&#xff1a;安装…

波奇学Linux:父子进程和进程状态

vim编辑器&#xff0c;编写一个程序模拟进程 在vim中查看sleep函数 底行模式输入 写个Makefile自动运行波奇学Linux:yum和vim-CSDN博客 运行程序 PID和PPID 查看进程目录信息 实际有过滤出来有两个&#xff0c;一个进程本身一个是grep程序&#xff0c;通过 -v grep过滤走含gre…

新版Android Studio 正则表达式匹配代码注释,删除注释,删除全部注释,IntelliJ IDEA 正则表达式匹配代码注释

正则表达式匹配代码注释 完整表达式拼接Android Studio 搜索匹配【IntelliJ IDEA 也是一样的】 完整表达式拼接 (/*{1,2}[\s\S]?*/)|(//[\x{4e00}-\x{9fa5}].)|(<!-[\s\S]?–>)|(^\s\n)|(System.out.println.*) 表达式拆解&#xff0c;可以根据自己需求自由组合&#x…

Mybatis、Mybatis整合Spring的流程图

Mybatis 注意MapperProxy里面有invoke方法&#xff0c;当进到invoker方法会拿到 二、mybatis整合Spring 1、当我们的拿到的【Dao】其实就是【MapperProxy】&#xff0c;执行Dao的方法时&#xff0c;会被MapperProxy的【Invoke方法拦截】 2、图上已经标注了MapperProxy包含哪些…

STM32-TIM定时器中断

目录 一、TIM&#xff08;Timer&#xff09;定时器简介 二、定时器类型 2.1基本定时器结构 2.2通用定时器结构 2.3高级定时器结构 三、定时中断基本结构 四、时序图分析 4.1 预分频器时序 4.2 计数器时序 4.3 计数器无预装时序&#xff08;无影子寄存器&#xff09; …

PyQt6 水平布局Horizontal Layout (QHBoxLayout)

锋哥原创的PyQt6视频教程&#xff1a; 2024版 PyQt6 Python桌面开发 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili2024版 PyQt6 Python桌面开发 视频教程(无废话版) 玩命更新中~共计41条视频&#xff0c;包括&#xff1a;2024版 PyQt6 Python桌面开发 视频教程(无废话版…

[足式机器人]Part2 Dr. CAN学习笔记-自动控制原理Ch1-1开环系统与闭环系统Open/Closed Loop System

本文仅供学习使用 本文参考&#xff1a; B站&#xff1a;DR_CAN Dr. CAN学习笔记-自动控制原理Ch1-1开环系统与闭环系统Open/Closed Loop System EG1: 烧水与控温水壶EG2: 蓄水与最终水位闭环控制系统 EG1: 烧水与控温水壶 EG2: 蓄水与最终水位 h ˙ q i n A − g h A R \dot{…

阿里云SLS采集jvm日志

一、背景 java应用部署在阿里云的k8s容器里&#xff0c;采集其日志的需求则是一个不可缺少的。而不同公司的jvm日志会存在很大的差异&#xff0c;所以本文仅以我的实际情况作一个示例&#xff0c;仅供有需要采集jvm日志的同学们一个参考。 我们打印的Jvm日志格式见下&#xf…

【干货分享】KingIOServer与三菱PLC的通讯的应用案例

哈喽&#xff0c;大家好&#xff0c;我是雷工&#xff01; 最近一个项目涉及用KingIOServer采集三菱PLC数据&#xff0c;特记录通讯过程方便备忘。 一、版本说明&#xff1a; 1、KingIOServer版本&#xff1a;3.7SP2 2、PLC型号&#xff1a;Q03UDV 和Q03UDE自带以太网网口。…

【Dubbo3云原生微服务开发实战】「Dubbo前奏导学」 RPC服务的底层原理和实现

RPC服务 RPC服务介绍RPC通信模式RPC架构组成RPC技术要点RPC通信技术选项分析RPC实战开发6大基础组件基础组件之Guava基础组件之Hutools基础组件之ReflectionASM基础组件之FastJSON/FastJSON2基础组件之FST相比FastJSON的优势 基础组件之Commons-Codec RPC框架层面选项分析RPC组…

持续集成交付CICD:Jenkins配置Nexus制品上传流水线

目录 一、实验 1.Jenkins配置制品上传流水线 二、问题 1.上传制品显示名称有误 一、实验 1.Jenkins配置制品上传流水线 (1) 新建流水线项目 &#xff08;2&#xff09;描述 &#xff08;3&#xff09;添加参数 &#xff08;4&#xff09;查看构建首页 &#xff08;5&…

实现简易的一对一用户聊天

服务端 package 一对一用户;import java.awt.BorderLayout; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.ServerSocket; import java.net.Socket; import java.util.Vector…

Redis课程:黑马点评

文章目录 基于Redis实现短信登录商户查询缓存优惠券秒杀一人一单 分布式锁Redis分布式锁误删情况说明解决Redis分布式锁误删问题使用lua脚本解决分布式锁的原子性问题 基于阻塞队列实现秒杀优化Redis消息队列优化秒杀业务达人探店参考 本文是根据黑马程序员的视频课程 黑马程序…

Kubernetes架构及核心部件

文章目录 1、Kubernetes集群概述1.1、概述1.2、通过声明式API即可 2、Kubernetes 集群架构2.1、Master 组件2.1.1、API Server2.1.2、集群状态存储2.1.3、控制器管理器2.1.4、调度器 2.2、Worker Node 组件2.2.1、kubelet2.2.2、容器运行时环境2.2.3、kube-proxy 2.3、图解架构…

深入解析Node.js:V8引擎、事件驱动和非阻塞式I/O

文章目录 1. 引言2. 什么是Node.js&#xff1f;3. V8引擎3.1 V8引擎简介3.2 V8引擎的特点 4. 事件驱动4.1 事件循环4.2 事件触发与监听4.2.1 代码示例 4.3 异步回调4.3.1 代码示例 5. 非阻塞式I/O5.1 非阻塞式I/O的优势5.2 异步与同步的对比5.2.1 同步I/O的代码示例5.2.2 异步I…

Linux 系统上配置 SSH 密钥

1. 生成 SSH 密钥 打开终端&#xff0c;运行以下命令来生成 SSH 密钥&#xff1a; ssh-keygen -t rsa -b 4096 -C "wqzbxhexample.com" 替换 "wqzbxhexample.com" 为你在 GitHub 注册时使用的邮箱地址。 2. 添加 SSH 密钥到 SSH 代理 运行以下命令来启…

ROS gazebo 机器人仿真,环境与robot建模,添加相机 lidar,控制robot运动

b站上有一个非常好的ros教程234仿真之URDF_link标签简介-机器人系统仿真_哔哩哔哩_bilibili&#xff0c;推荐去看原视频。 视频教程的相关文档见&#xff1a;6.7.1 机器人运动控制以及里程计信息显示 Autolabor-ROS机器人入门课程《ROS理论与实践》零基础教程 本文对视频教程…

【论文精读】REACT: SYNERGIZING REASONING AND ACTING IN LANGUAGE MODELS

REACT: SYNERGIZING REASONING AND ACTING IN LANGUAGE MODELS 前言ABSTRACT1 INTRODUCTION2 REACT: SYNERGIZING REASONING ACTING3 KNOWLEDGE-INTENSIVE REASONING TASKS3.1 SETUP3.2 METHODS3.3 RESULTS AND OBSERVATIONS 4 DECISION MAKING TASKS5 RELATED WORK6 CONCLUSI…