本文介紹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
語法:
- 把json賦值一個給一本變量,通過變量直接用對象名.key就可以讀取
- 如果是數組,則可以循環,obj[i]讀取
- 如果key值為對象,直接用:對象名.key.屬性讀取
- 如果要修改值,直接用對象名.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
這里有兩個特殊的:
- 數組轉化成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);}}