JSON常用解析框架使用操作詳解
JSON概述
JSON(JavaScript Object Notation)是一種輕量級的數(shù)據(jù)交換格式,相比xml數(shù)據(jù)交換格式來說,因?yàn)榻馕鰔ml比較的復(fù)雜且需要編寫大段的代碼,所以客戶端和服務(wù)器的數(shù)據(jù)交換格式往往通過JSON來進(jìn)行交換。
json可以說就是javascript中的對象和數(shù)組,所以這兩種結(jié)構(gòu)就是對象和數(shù)組兩種結(jié)構(gòu),通過這兩種結(jié)構(gòu)可以表示各種復(fù)雜的結(jié)構(gòu)。
常用JSON解析框架
fastjson(阿里)
gson(谷歌)
jackson(SpringMVC自帶)
XML與JSON的區(qū)別
Xml是重量級數(shù)據(jù)交換格式,占寬帶比較大。
JSON是輕量級交換格式,占寬帶小。
fastjson的使用
引入依賴
<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson --> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.76</version> </dependency>
常用API
//把JSON文本parse為JSONObject或者JSONArray public static final Object parse(String text); //把JSON文本parse成JSONObject public static final JSONObject parseObject(String text); //把JSON文本parse為JavaBean public static final <T> T parseObject(String text, Class<T> clazz); //把JSON文本parse成JSONArray public static final JSONArray parseArray(String text); //把JSON文本parse成JavaBean集合 public static final <T> List<T> parseArray(String text, Class<T> clazz); //將JavaBean序列化為JSON文本 public static final String toJSONString(Object object); //將JavaBean序列化為帶格式的JSON文本 public static final String toJSONString(Object object, boolean prettyFormat); //將JavaBean轉(zhuǎn)換為JSONObject或者JSONArray。 public static final Object toJSON(Object javaObject);
JSON解析
public static void main(String[] args) { String userJson = "{\"users\":[{\"name\":\"小白\",\"age\":\"12\"},{\"name\":\"大白\",\"age\":\"22\"}]}"; //將json字符串轉(zhuǎn)換為jsonObject JSONObject parseObject = JSON.parseObject(userJson); // 獲取json數(shù)組對象 JSONArray usersArray = parseObject.getJSONArray("users"); for (Object object : usersArray) { JSONObject jsonObejct = (JSONObject) object; String name = jsonObejct.getString("name"); String age = jsonObejct.getString("age"); System.out.println(name + "----" + age); } }
JSON封裝
public static void main(String[] args) { JSONObject jsonObject = new JSONObject(); JSONArray usersArray = new JSONArray(); JSONObject user1 = new JSONObject(); user1.put("name", "小白"); user1.put("age", "12"); usersArray.add(user1); JSONObject user2 = new JSONObject(); user2.put("name", "大白"); user2.put("age", "22"); usersArray.add(user2); jsonObject.put("users", usersArray); System.out.println(jsonObject.toJSONString()); }
{"users":[{"age":"12","name":"小白"},{"age":"22","name":"大白"}]}
gson的使用
概述
Gson是Java序列化/反序列化庫,用于將 Java 對象轉(zhuǎn)換為JSON并返回。 Gson由Google創(chuàng)建,供內(nèi)部使用,后來開源。
Gson具有三種API:數(shù)據(jù)綁定 API、樹模型 API、流 API
數(shù)據(jù)綁定 API 使用屬性訪問器將JSON與POJO之間進(jìn)行轉(zhuǎn)換。 Gson使用數(shù)據(jù)類型適配器處理 JSON 數(shù)據(jù)。 它類似于XML JAXB解析器。
樹模型 API創(chuàng)建JSON 文檔的內(nèi)存樹表示。 它構(gòu)建JsonElements的樹。 它類似于XML DOM解析器。
流 API是一種低級 API,它使用JsonReader和JsonWriter作為離散記號讀取和寫入 JSON 內(nèi)容。 這些類將數(shù)據(jù)讀取為JsonTokens。 該 API 具有最低的開銷,并且在讀/寫操作中速度很快。 它類似于 XML 的 Stax 解析器
添加依賴
添加對Gson的Maven依賴
<dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> <version>2.9.0</version> </dependency>
toJson()
Gson是使用Gson庫的主要類
toJson()方法將指定的對象序列化為其等效的JSON表示形式
public static void main(String[] args) { Map<Integer, String> map = new HashMap<>(); map.put(1, "a"); map.put(2, "b"); map.put(3, "c"); Gson gson = new Gson(); String output = gson.toJson(map); System.out.println(output); }
{"1":"a","2":"b","3":"c"}
fromJson()
fromJson()方法將JSON讀取到Java對象中
public static void main(String[] args) { String json_string = "{\"username\":\"Jack\", \"age\": \"20\"}"; Gson gson = new Gson(); User user = gson.fromJson(json_string, User.class); System.out.println(user); } @ToString @AllArgsConstructor class User { private String username; private String age; }
GsonBuilder
GsonBuilder可使用各種配置設(shè)置構(gòu)建Gson。GsonBuilder遵循構(gòu)建器模式,通常通過首先調(diào)用各種配置方法來設(shè)置所需的選項(xiàng),最后調(diào)用create()來使用它。
public static void main(String[] args) throws UnsupportedEncodingException { try (PrintStream prs = new PrintStream(System.out, true, "UTF8")) { Gson gson = new GsonBuilder() // 配置Gson在序列化和反序列化期間將特定的命名策略應(yīng)用于對象的字段。 // 字段命名策略設(shè)置為FieldNamingPolicy.UPPER_CAMEL_CASE: 確保Java字段名稱的第一個(gè)“字母”在序列化為其JSON形式時(shí)大寫 .setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE) .create(); User user = new User("Jack", 20); gson.toJson(user, prs); } } @ToString @AllArgsConstructor static class User { private String username; private Integer age; }
{"Username":"Jack","Age":20}
JSON對象數(shù)據(jù)寫入文件
將JSON數(shù)據(jù)寫入一個(gè)json文件。
public static void main(String[] args) throws IOException { String filePath = "src/main/resources/users.json"; try (FileOutputStream fos = new FileOutputStream(filePath); OutputStreamWriter isr = new OutputStreamWriter(fos, StandardCharsets.UTF_8)) { Gson gson = new Gson(); User user1 = new User("Jack", 23); User user2 = new User("Jon", 22); User user3 = new User("Tom", 33); List<User> users = new ArrayList<>(); users.add(user1); users.add(user2); users.add(user3); gson.toJson(users, isr);
將JSON數(shù)據(jù)讀取到Java數(shù)組
將json文件中的JSON數(shù)據(jù)讀取到數(shù)組中,并打印到控制臺(tái)。
public static void main(String[] args) throws IOException { String filePath = "src/main/resources/users.json"; Path path = new File(filePath).toPath(); try (Reader reader = Files.newBufferedReader(path, StandardCharsets.UTF_8)) { User[] users = new Gson().fromJson(reader, User[].class); Arrays.stream(users).forEach(e -> System.out.println(e)); } }
ApplicationTests.User(username=Jack, age=23)
ApplicationTests.User(username=Jon, age=22)
ApplicationTests.User(username=Tom, age=33)
從URL讀取JSON
public static void main(String[] args) throws IOException { String url = "xxx"; try (InputStream is = new URL(url).openStream(); Reader reader = new InputStreamReader(is, StandardCharsets.UTF_8)) { Gson gson = new Gson(); User user = gson.fromJson(reader, User.class); System.out.println(user); } }
打印
Gson 有兩種輸出模式:緊湊和漂亮。通過setPrettyPrinting()方法設(shè)置漂亮的打印模式。
public static void main(String[] args) { Gson gson1 = new GsonBuilder().create(); Gson gson2 = new GsonBuilder().setPrettyPrinting().create(); Map<Integer, String> map = new HashMap<>(); map.put(1, "a"); map.put(2, "b"); map.put(3, "c"); gson1.toJson(map, System.out); System.out.println(""); gson2.toJson(map, System.out); }
{"1":"a","2":"b","3":"c"}
{
"1": "a",
"2": "b",
"3": "c"
}
序列化空值
默認(rèn)情況下,Gson 不會(huì)將具有空值的字段序列化為 JSON。 如果 Java 對象中的字段為null,則 Gson 會(huì)將其排除。 我們可以使用serializeNulls()方法強(qiáng)制 Gson 通過 GsonBuilder 序列化null值。
public static void main(String[] args) { Gson gson1 = new GsonBuilder().create(); Gson gson2 = new GsonBuilder().serializeNulls().create(); User user = new User("Jack", null); System.out.println(gson1.toJson(user)); System.out.println(gson2.toJson(user)); }
{"username":"Jack"}
{"username":"Jack","age":null}
使用@Expose排除字段
@Expose注解指定那些成員公開以進(jìn)行JSON序列化或反序列化
@Expose注解可以采用兩個(gè)布爾參數(shù):serialize和deserialize進(jìn)行控制
必須使用excludeFieldsWithoutExposeAnnotation()方法顯式啟用@Expose注解
public static void main(String[] args) { Gson gson = new GsonBuilder() .excludeFieldsWithoutExposeAnnotation() .create(); User user = new User("Jack", 23); gson.toJson(user, System.out); } @ToString @AllArgsConstructor static class User { @Expose private String username; private Integer age; }
{"username":"Jack"}
jackson的使用
概述
Jackson有三個(gè)核包,分別是 Streaming、Databid、Annotations,通過這些包可以方便的對 JSON 進(jìn)行操作。
Streaming (opens new window)在 jackson-core 模塊。 定義了一些流處理相關(guān)的 API 以及特定的 JSON 實(shí)現(xiàn)。
Annotations (opens new window)在 jackson-annotations 模塊,包含了 Jackson 中的注解。
Databind (opens new window)在 jackson-databind 模塊, 在 Streaming 包的基礎(chǔ)上實(shí)現(xiàn)了數(shù)據(jù)綁定,依賴于 Streaming 和 Annotations 包。
添加依賴
jackson-databind依賴 jackson-core 和 jackson-annotations,所以可以只顯示地添加jackson-databind依賴
<dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.11.4</version> </dependency>
ObjectMapper對象映射器
ObjectMapper是Jackson 庫中最常用的一個(gè)類,使用它可以進(jìn)行 Java 對象和JSON字符串之間快速轉(zhuǎn)換
readValue() 方法:進(jìn)行JSON 的反序列化操作,比如可以將字符串、文件流、字節(jié)流、字節(jié)數(shù)組等將常見的內(nèi)容轉(zhuǎn)換成 Java 對象。
writeValue() 方法:進(jìn)行JSON 的序列化操作,可以將 Java 對象轉(zhuǎn)換成 JSON 字符串。
ObjectMapper的工作原理是通過 Java Bean 對象的 Get/Set 方法進(jìn)行轉(zhuǎn)換時(shí)映射的,所以Java對象的 Get/Set方法尤為重要。
對象轉(zhuǎn)JSON
public static void main(String[] args) throws JsonProcessingException { ObjectMapper objectMapper = new ObjectMapper(); User user = new User("Jack", 20); String json = objectMapper.writeValueAsString(user); System.out.println(json); }
{"username":"Jack","age":20}
JSON轉(zhuǎn)對象
@Data class User { private String username; private Integer age; public User() { } public User(String username, Integer age) { this.username = username; this.age = age; } }
public static void main(String[] args) throws JsonProcessingException { ObjectMapper objectMapper = new ObjectMapper(); String json = "{\"username\":\"Jack\", \"age\": \"20\"}"; User user = objectMapper.readValue(json, User.class); System.out.println("user = " + user); }
user = User(username=Jack, age=20)
JSON轉(zhuǎn)List
public static void main(String[] args) throws JsonProcessingException { ObjectMapper objectMapper = new ObjectMapper(); String json = "[{\"username\":\"Jack\", \"age\": \"20\"},{\"username\":\"Tom\", \"age\": \"22\"}]"; List<User> userList = objectMapper.readValue(json, new TypeReference<List<User>>() {}); userList.forEach(System.out::print); }
User(username=Jack, age=20)User(username=Tom, age=22)
JSON轉(zhuǎn)Map
JSON轉(zhuǎn)Map適用于在沒有一個(gè)明確的Java對象時(shí)十分實(shí)用
public static void main(String[] args) throws JsonProcessingException { ObjectMapper objectMapper = new ObjectMapper(); String json = "{\"username\":\"Jack\", \"age\": \"20\"}"; Map<String, Object> userNmp = objectMapper.readValue(json, new TypeReference<Map>() {}); for (Map.Entry<String, Object> entry : userNmp.entrySet()) { System.out.println(entry.getKey() + ":" + entry.getValue()); } }
字段忽略
如果在進(jìn)行JSON 轉(zhuǎn) Java對象時(shí),JSON中出現(xiàn) Java 類中不存在的屬性,那么在轉(zhuǎn)換時(shí)會(huì)遇到com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException
異常。
使用objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
配置可以忽略不存在的屬性。
public static void main(String[] args) throws JsonProcessingException { ObjectMapper objectMapper = new ObjectMapper(); String json = "{\"username\":\"Jack\", \"age\": \"20\",, \"test\": \"test\"}"; objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); User user = objectMapper.readValue(json, User.class); System.out.println("user = " + user); }
日期格式化
開發(fā)中通常使用java.util.Date類或時(shí)間類java.time.LocalDateTime類(JDK8),兩者在Jackson中的處理略有不同。
Date類型
@AllArgsConstructor @NoArgsConstructor @Data class User { private String username; private Integer age; private Date createTime; }
public static void main(String[] args) throws JsonProcessingException { ObjectMapper objectMapper = new ObjectMapper(); User user = new User("Jack", 20, new Date()); String json = objectMapper.writeValueAsString(user); System.out.println(json); User u = objectMapper.readValue(json, User.class); System.out.println(u.toString()); }
未使用@JsonFormat
注解,可以正常的進(jìn)行JSON的序列化與反序列化,但是JSON 中的時(shí)間是一個(gè)時(shí)間戳格式
{"username":"Jack","age":20,"createTime":1669690748654} User(username=Jack, age=20, createTime=Tue Nov 29 10:59:08 CST 2022)
使用 @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Shanghai")
{"username":"Jack","age":20,"createTime":"2022-11-29 10:56:28"} User(username=Jack, age=20, createTime=Tue Nov 29 10:56:28 CST 2022)
LocalDateTime類型
注意:默認(rèn)情況下進(jìn)行 LocalDateTime 類的 JSON 轉(zhuǎn)換會(huì)遇到報(bào)錯(cuò)。異常信息:com.fasterxml.jackson.databind.exc.InvalidDefinitionException
需要添加相應(yīng)的數(shù)據(jù)綁定支持包。
<dependency> <groupId>com.fasterxml.jackson.datatype</groupId> <artifactId>jackson-datatype-jsr310</artifactId> <version>2.13.3</version> </dependency>
定義 ObjectMapper 時(shí)通過 findAndRegisterModules() 方法來注冊依賴。
public static void main(String[] args) throws JsonProcessingException { ObjectMapper objectMapper = new ObjectMapper().findAndRegisterModules(); User user = new User("Jack", 20, LocalDateTime.now()); String json = objectMapper.writeValueAsString(user); System.out.println(json); User u = objectMapper.readValue(json, User.class); System.out.println(u.toString()); }
{"username":"Jack","age":20,"createTime":"2022-11-29 11:02:32"} User(username=Jack, age=20, createTime=2022-11-29T11:02:32)
Jackson常用注解
@JsonIgnore:使用@JsonIgnore 可以忽略某個(gè) Java 對象中的屬性,它將不參與 JSON 的序列化與反序列化。
@JsonIgnore private String username;
@JsonGetter:使用 @JsonGetter 可以在對 Java 對象進(jìn)行 JSON 序列化時(shí)自定義屬性名稱。
private String username; @JsonGetter(value = "myName") public String getUsername() { return username; }
public static void main(String[] args) throws JsonProcessingException { ObjectMapper objectMapper = new ObjectMapper(); User user = new User("Jack", 20); String json = objectMapper.writeValueAsString(user); System.out.println(json); User u = objectMapper.readValue(json, User.class); System.out.println(u.toString()); }
{"age":20,"myName":"Jack"} User(username=Jack, age=20)
@JsonSetter:使用 @JsonSetter 可以在對 JSON 進(jìn)行反序列化時(shí)設(shè)置 JSON 中的 key 與 Java 屬性的映射關(guān)系。
@JsonSetter(value = "myName") private String username;
public static void main(String[] args) throws JsonProcessingException { ObjectMapper objectMapper = new ObjectMapper(); String json="{\"age\":20,\"myName\":\"Jack\"}"; User u = objectMapper.readValue(json, User.class); System.out.println(u.toString()); }
User(username=Jack, age=20)
以上就是JSON常用解析框架使用操作詳解的詳細(xì)內(nèi)容,更多關(guān)于JSON解析框架使用的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
vue/js實(shí)現(xiàn)頁面自動(dòng)往上滑動(dòng)效果
這篇文章主要為大家詳細(xì)介紹了vue/js實(shí)現(xiàn)頁面自動(dòng)往上滑動(dòng)效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-04-04使用Bootstrap和Vue實(shí)現(xiàn)用戶信息的編輯刪除功能
這篇文章主要介紹了使用Bootstrap和Vue實(shí)現(xiàn)用戶信息的編輯刪除功能,需要的朋友可以參考下2017-10-10uniapp小程序自定義tabbar以及初次加載閃屏解決方法
Uniapp小程序可以通過自定義tabbar來實(shí)現(xiàn)更加個(gè)性化的界面設(shè)計(jì),下面這篇文章主要給大家介紹了關(guān)于uniapp小程序自定義tabbar以及初次加載閃屏解決方法,文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下2023-05-05詳解webpack+ES6+Sass搭建多頁面應(yīng)用
這篇文章主要介紹了webpack+ES6+Sass搭建多頁面應(yīng)用,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-11-11JavaScript中Require調(diào)用js的實(shí)例分享
下面小編就為大家?guī)硪黄狫avaScript中Require調(diào)用js的實(shí)例分享。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-10-10javascript 延遲加載技術(shù)(lazyload)簡單實(shí)現(xiàn)
延遲加載技術(shù)(簡稱lazyload)并不是新技術(shù), 它是js程序員對網(wǎng)頁性能優(yōu)化的一種方案.2011-01-01詳解用函數(shù)式編程對JavaScript進(jìn)行斷舍離
本篇文章主要介紹了用函數(shù)式編程對JavaScript進(jìn)行斷舍離,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-09-09獲取offsetTop和offsetLeft值的js代碼(兼容)
offsetTop和offsetLeft的值在某些特殊的情況下是會(huì)使用到的,為了實(shí)現(xiàn)值的準(zhǔn)確獲取,本文采用js代碼實(shí)現(xiàn)下,有需求的朋友可以參考下哈2013-04-04js實(shí)現(xiàn)三角形粒子運(yùn)動(dòng)
這篇文章主要為大家詳細(xì)介紹了js實(shí)現(xiàn)三角形粒子運(yùn)動(dòng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-09-09