JSON常用解析框架使用操作詳解
JSON概述
JSON(JavaScript Object Notation)是一種輕量級(jí)的數(shù)據(jù)交換格式,相比xml數(shù)據(jù)交換格式來說,因?yàn)榻馕鰔ml比較的復(fù)雜且需要編寫大段的代碼,所以客戶端和服務(wù)器的數(shù)據(jù)交換格式往往通過JSON來進(jìn)行交換。
json可以說就是javascript中的對(duì)象和數(shù)組,所以這兩種結(jié)構(gòu)就是對(duì)象和數(shù)組兩種結(jié)構(gòu),通過這兩種結(jié)構(gòu)可以表示各種復(fù)雜的結(jié)構(gòu)。
常用JSON解析框架
fastjson(阿里)
gson(谷歌)
jackson(SpringMVC自帶)
XML與JSON的區(qū)別
Xml是重量級(jí)數(shù)據(jù)交換格式,占寬帶比較大。
JSON是輕量級(jí)交換格式,占寬帶小。
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ù)組對(duì)象
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 對(duì)象轉(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是一種低級(jí) API,它使用JsonReader和JsonWriter作為離散記號(hào)讀取和寫入 JSON 內(nèi)容。 這些類將數(shù)據(jù)讀取為JsonTokens。 該 API 具有最低的開銷,并且在讀/寫操作中速度很快。 它類似于 XML 的 Stax 解析器
添加依賴
添加對(duì)Gson的Maven依賴
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.9.0</version>
</dependency>
toJson()
Gson是使用Gson庫的主要類
toJson()方法將指定的對(duì)象序列化為其等效的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對(duì)象中
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)用于對(duì)象的字段。
// 字段命名策略設(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對(duì)象數(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 對(duì)象中的字段為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,通過這些包可以方便的對(duì) 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對(duì)象映射器
ObjectMapper是Jackson 庫中最常用的一個(gè)類,使用它可以進(jìn)行 Java 對(duì)象和JSON字符串之間快速轉(zhuǎn)換
readValue() 方法:進(jìn)行JSON 的反序列化操作,比如可以將字符串、文件流、字節(jié)流、字節(jié)數(shù)組等將常見的內(nèi)容轉(zhuǎn)換成 Java 對(duì)象。
writeValue() 方法:進(jìn)行JSON 的序列化操作,可以將 Java 對(duì)象轉(zhuǎn)換成 JSON 字符串。
ObjectMapper的工作原理是通過 Java Bean 對(duì)象的 Get/Set 方法進(jìn)行轉(zhuǎn)換時(shí)映射的,所以Java對(duì)象的 Get/Set方法尤為重要。
對(duì)象轉(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)對(duì)象
@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對(duì)象時(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對(duì)象時(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() 方法來注冊(cè)依賴。
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 對(duì)象中的屬性,它將不參與 JSON 的序列化與反序列化。
@JsonIgnore
private String username;
@JsonGetter:使用 @JsonGetter 可以在對(duì) Java 對(duì)象進(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 可以在對(duì) 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解析框架使用的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Bootstrap實(shí)現(xiàn)前端登錄頁面帶驗(yàn)證碼功能完整示例
這篇文章主要介紹了Bootstrap實(shí)現(xiàn)前端登錄頁面帶驗(yàn)證碼功能,結(jié)合完整實(shí)例形式分析了Bootstrap前端登錄頁面帶驗(yàn)證碼界面布局與功能實(shí)現(xiàn)相關(guān)操作技巧,需要的朋友可以參考下2020-03-03
JavaScript中十種一步拷貝數(shù)組的方法實(shí)例詳解
JavaScript中我們經(jīng)常會(huì)遇到拷貝數(shù)組的場景,但是都有哪些方式能夠來實(shí)現(xiàn)呢,我們不妨來梳理一下,感興趣的朋友跟隨小編一起看看吧2019-04-04
jser必看的破解javascript各種加密的反向思維方法
才發(fā)現(xiàn)的破解javascript各種加密的反向思維方法,大家有好的方法都跟帖啊最近發(fā)現(xiàn)了一個(gè)代碼,加密了5層左右,我將破解到最后一步,而且不用javascript解密程序2007-04-04
JavaScript 中判斷變量是否為數(shù)字的示例代碼
這篇文章主要介紹了JavaScript 中判斷變量是否為數(shù)字的示例代碼,代碼簡單易懂對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-10-10
前淘寶前端開發(fā)工程師阿當(dāng)?shù)腜PT中有JS技術(shù)理念問題
第一屆 web rebuild 北京會(huì)有個(gè)前淘寶前端開發(fā)工程師阿當(dāng)分享的 PPT 在公司團(tuán)隊(duì)內(nèi)部有同事下載的分享,然后看了。發(fā)現(xiàn)了有些技術(shù)理念的問題:2010-01-01
javascript實(shí)現(xiàn)倒計(jì)時(shí)小案例
這篇文章主要為大家詳細(xì)介紹了javascript實(shí)現(xiàn)倒計(jì)時(shí)小案例,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-07-07
單行 JS 實(shí)現(xiàn)移動(dòng)端金錢格式的輸入規(guī)則
這篇文章主要介紹了單行 JS 實(shí)現(xiàn)移動(dòng)端金錢格式的輸入規(guī)則,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2017-05-05
微信小程序之圓形進(jìn)度條實(shí)現(xiàn)思路
這篇文章主要介紹了微信小程序之圓形進(jìn)度條實(shí)現(xiàn)思路,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2018-02-02
JS采用絕對(duì)定位實(shí)現(xiàn)回到頂部效果完整實(shí)例
這篇文章主要介紹了JS采用絕對(duì)定位實(shí)現(xiàn)回到頂部效果,以完整實(shí)例形式分析了JS定位到頁面頂部功能的實(shí)現(xiàn)方法,涉及javascript動(dòng)態(tài)操作頁面元素與屬性的相關(guān)技巧,需要的朋友可以參考下2016-06-06

