原文參考分享自CSDN:你了解JSON嗎?--Jackson、FastJson在SpringMVC中的簡單使用_歡迎來到 Baret~H 的博客-CSDN博客
1. 什么是 JSON
JSON
(JavaScript Object Notation, JS 對象標記)
- 是一種輕量級的數據交換格式
- 采用完全獨立于編程語言的
文本格式
來存儲和表示數據。 - 簡潔和清晰的層次結構使得 JSON 成為理想的數據交換語言。
- 易于人閱讀和編寫,也易于機器解析和生成,并有效地提升網絡傳輸效率。
在 JavaScript 語言中,一切都是對象。因此,任何JavaScript 支持的類型都可以通過 JSON 來表示,例如字符串、數字、對象、數組等。
2. JSON 語法規則
鍵值對
表示對象,數據由逗號分隔花括號
保存對象方括號
保存數組
JSON 鍵值對 是用來保存 JavaScript 對象的一種方式
- 由
花括號
括起來的逗號
分割的成員構成 - 鍵值對組合中的鍵名寫在前面并用雙引號
""
包裹,使用冒號:
分隔,然后緊接著值
{"name": "zsr","age": "20","sex": "男"}
3. JSON 與 JS 對象的關系
JSON 是 JavaScript 對象的字符串表示法,它使用文本表示一個 JS 對象的信息,本質是一個字符串。
var obj = {a: 'Hello', b: 'World'}; //這是一個對象,注意鍵名也是可以使用引號包裹的
var json = '{"a": "Hello", "b": "World"}'; //這是一個 JSON 字符串,本質是一個字符串
4. JSON 和 JS 對象互轉
編寫一個html頁面進行測試
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>test</title>
</head>
<body>
<script type="text/javascript">var user = {name: "zsr",age: 20,sex: "男"};console.log(user);//將js對象轉換為json對象var json = JSON.stringify(user);console.log(json);//將json對象轉換為js對象var obj = JSON.parse(json);console.log(obj);
</script>
</body>
</html>
運行測試,查看控制臺信息:
JSON
就是一個字符串,不能展開JavaScript
是一個對象,可以展開

5. 使用Jackson數據交互
Jackson
是一個 Java 的用來處理JSON
格式數據的類庫,性能非常好
當然不止這一個類庫,比如還有阿里巴巴的 fastjson
等等。

接下來我們簡單介紹一下SpringMVC中Jackson
的使用
1、導入依賴
導入Jackson
的jar包
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.11.2</version>
</dependency>
2、配置web.xml
配置SpringMVC需要的配置web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"version="4.0"><!--1.注冊servlet--><servlet><servlet-name>SpringMVC</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><!--通過初始化參數指定SpringMVC配置文件的位置,進行關聯--><init-param><param-name>contextConfigLocation</param-name><param-value>classpath:springmvc-servlet.xml</param-value></init-param><!-- 啟動順序,數字越小,啟動越早 --><load-on-startup>1</load-on-startup></servlet><!--所有請求都會被springmvc攔截 --><servlet-mapping><servlet-name>SpringMVC</servlet-name><url-pattern>/</url-pattern></servlet-mapping><!--SpringMVC內置過濾器,防止中文亂碼--><filter><filter-name>encoding</filter-name><filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class><init-param><param-name>encoding</param-name><param-value>utf-8</param-value></init-param></filter><filter-mapping><filter-name>encoding</filter-name><url-pattern>/</url-pattern></filter-mapping>
</web-app>
3、編寫SpringMVC配置文件
springmvc-servlet.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xmlns:mvc="http://www.springframework.org/schema/mvc"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttps://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/mvchttps://www.springframework.org/schema/mvc/spring-mvc.xsd"><!-- 自動掃描指定的包,下面所有注解類交給IOC容器管理 --><context:component-scan base-package="controller"/><!-- 視圖解析器 --><bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"id="internalResourceViewResolver"><!-- 前綴 --><property name="prefix" value="/WEB-INF/jsp/" /><!-- 后綴 --><property name="suffix" value=".jsp" /></bean></beans>
4、編寫實體類 (lombok)
編寫一個User的實體類,然后我們去編寫我們的測試Controller;
package pojo;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {private String name;private int age;private String sex;
}
5、編寫Controller
@Controller
public class UserController {@RequestMapping("/j1")@ResponseBody //它不會走視圖解析器,會直接返回一個字符串public String json1() {//創建一個對象User user = new User("zsr", 20, "男");return user.toString();}
}
這里我們使用了@ResponseBody
注解,他是配合@Controller
使用的,該注解可以使不走視圖解析器,而是直接返回一個字符串
同樣可以直接將@Controller
替換為@RestController
,也可以達到不走視圖解析器,直接返回字符串的效果,此時就不用使用@ResponseBody
注解了
6、運行測試
配置Tomcat,點擊運行,訪問http://localhost:8080/j1
,結果如下

我們并沒有通過視圖解析器,而是直接返回了字符串
7、轉換為JSON格式
如果我們想以json的格式進行輸出,除了上述@ResponseBody
注解之外,還需要一個objectMapper
對象
我們修改上述Controller
@Controller
public class UserController {@RequestMapping("/j1")@ResponseBody //它不會走視圖解析器,會直接返回一個字符串public String json1() throws JsonProcessingException {//創建jackson的對象映射器,用來解析數據ObjectMapper mapper = new ObjectMapper();//創建一個對象User user = new User("zsr", 20, "男");//將對象轉換成json格式String str = mapper.writeValueAsString(user);//由于@ResponseBody注解,這里會將str轉成json格式返回;十分方便return str;}
}
重新運行測試,同行訪問http://localhost:8080/j1
,成功以json的格式進行顯示!

但是還存在亂碼問題,我們需要設置一下他的編碼格式為utf-8,以及它返回的類型;
這里可以通過@RequestMapping
的produces
屬性來實現,修改下代碼
//produces:指定響應體返回類型和編碼
@RequestMapping(value = "/json1",produces = "application/json;charset=utf-8")
再次測試,亂碼問題得到解決

8、代碼優化
1. 亂碼問題
上述設置@RequestMapping
中produces
屬性值的方式比較麻煩,如果項目中有多個controller
則每一個都要添加
可以通過Spring配置統一指定,在SpringMVC配置文件中加入如下代碼即可
<!--json亂碼問題配置-->
<mvc:annotation-driven><mvc:message-converters register-defaults="true"><bean class="org.springframework.http.converter.StringHttpMessageConverter"><constructor-arg value="UTF-8"/></bean><bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"><property name="objectMapper"><bean class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean"><property name="failOnEmptyBeans" value="false"/></bean></property></bean></mvc:message-converters>
</mvc:annotation-driven>
2. 返回json字符串統一解決
上述我們使用了@ResponseBody
注解,他是配合@Controller
使用的,該注解可以使不走視圖解析器,而是直接返回一個字符串
同樣可以直接將@Controller
替換為@RestController
,也可以達到不走視圖解析器,直接返回字符串的效果,此時就不用使用@ResponseBody
注解了
@RestController
public class UserController {@RequestMapping(value = "/json1")public String json1() throws JsonProcessingException {//創建一個jackson的對象映射器,用來解析數據ObjectMapper mapper = new ObjectMapper();//創建一個對象User user = new User("zsr", 20, "男");//將我們的對象解析成為json格式String str = mapper.writeValueAsString(user);//由于@RestController注解,這里會將str轉成json格式返回;十分方便return str;}
}
9、測試集合輸出
增加一個新的方法,多個對象的情況下,我們會將其放在一個集合中
@RequestMapping(value = "/j2")
public String json2() throws JsonProcessingException {//創建jackson的對象映射器,用來解析數據ObjectMapper mapper = new ObjectMapper();//創建容器List<User> list = new ArrayList<User>();//創建多個對象User user1 = new User("zsr1", 20, "男");User user2 = new User("zsr2", 20, "男");User user3 = new User("zsr3", 20, "男");User user4 = new User("zsr4", 20, "男");User user5 = new User("zsr5", 20, "男");//將所有對象存入容器list.add(user1);list.add(user2);list.add(user3);list.add(user4);list.add(user5);//將對象轉換成json格式String str = mapper.writeValueAsString(list);//由于@RequestMapping注解,這里會將str轉成json格式返回;十分方便return str;
}
運行測試,成功將所有對象的信息都以json的形式顯示出來

10、輸出日期對象
增加一個新的方法,測試日期對象的輸出
@RequestMapping(value = "/j3")
public String json3() throws JsonProcessingException {//創建jackson的對象映射器,用來解析數據ObjectMapper mapper = new ObjectMapper();//創建一個日期對象Date date = new Date();//將對象轉換為json格式String str = mapper.writeValueAsString(date);//ObjectMapper對時間解析后的默認格式為:Timestamp(時間戳)return str;
}
運行測試,訪問http://localhost:8080/j3
,手動刷新,可以看到這個數字增長很快

- 默認日期格式會變成一個數字,是1970年1月1日到當前日期的毫秒數!
- Jackson 默認是會把時間轉成timestamps形式
如果我們不想以時間戳的方式顯示呢?
方式一:我們新增一個方法,自定義日期的格式
@RequestMapping(value = "/j4")
public String json4() throws JsonProcessingException {//創建jackson的對象映射器,用來解析數據ObjectMapper mapper = new ObjectMapper();//創建一個日期對象Date date = new Date();//自定義日期格式SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yy-mm-dd hh:mm:ss");//將對象轉換為json格式String str = mapper.writeValueAsString(simpleDateFormat.format(date));return str;
}
運行測試:訪問http://localhost:8080/j4
,成功按我們規定的格式輸出

方式二:取消timestamps形式 , 自定義時間格式
@RequestMapping(value = "/j5")
public String json5() throws JsonProcessingException {//創建jackson的對象映射器,用來解析數據ObjectMapper mapper = new ObjectMapper();//不使用時間戳的方式mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);//自定義日期格式SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yy-mm-dd hh:mm:ss");//指定日期格式mapper.setDateFormat(simpleDateFormat);//創建一個日期對象Date date = new Date();//將對象轉換為json格式String str = mapper.writeValueAsString(date);return str;
}
運行測試:訪問http://localhost:8080/j5
,同樣成功按我們規定的格式輸出

6. 使用FastJson進行數據交互
fastjson.jar
是阿里開發的一款專門Java處理JSON開發的包
- Fastjson 是一個 Java 庫,可以將 Java 對象轉換為 JSON 格式,當然它也可以將 JSON 字符串轉換為 Java 對象。
- Fastjson 可以操作任何 Java 對象,即使是一些預先存在的沒有源碼的對象。
菜鳥教程:https://www.runoob.com/w3cnote/fastjson-intro.html
Fastjson 源碼地址:https://github.com/alibaba/fastjson
Fastjson 中文 Wiki:https://github.com/alibaba/fastjson/wiki/Quick-Start-CN

接下來我們簡單介紹一下SpringMVC中fastjson
的使用
1. 導入依賴依賴
<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
<dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.73</version>
</dependency>
2. 三個主要的類
JSONObject
代表 json對象
- JSONObject實現了Map接口, 猜想 JSONObject底層操作是由Map實現的。
- JSONObject對應json對象,通過各種形式的get()方法可以獲取json對象中的數據,也可利用諸如size(),isEmpty()等方法獲取"鍵:值"對的個數和判斷是否為空。其本質是通過實現Map接口并調用接口中的方法完成的。
JSONArray
代表 json對象數組
- 內部是有List接口中的方法來完成操作的。
JSON
代表JSONObject
和JSONArray
的轉化
- JSON類源碼分析與使用
- 仔細觀察這些方法,主要是實現json對象,json對象數組,javabean對象,json字符串之間的相互轉化。
3. 代碼測試
新建一個方法,利用fastjson的方法返回json字符串:
@RequestMapping(value = "/j6")
public String json6() throws JsonProcessingException {//創建容器List<User> list = new ArrayList<User>();//創建多個對象User user1 = new User("zsr1", 20, "男");User user2 = new User("zsr2", 20, "男");User user3 = new User("zsr3", 20, "男");User user4 = new User("zsr4", 20, "男");User user5 = new User("zsr5", 20, "男");//將所有對象存入容器list.add(user1);list.add(user2);list.add(user3);list.add(user4);list.add(user5);return JSON.toJSONString(list);
}
運行測試:同樣正確顯示了結果

4. 常用方法測試代碼
這種工具類,我們只需知道了解即可,在使用的時候在根據具體的業務去找對應的實現即可
接下來是幾種常用的方法(更多的方法在具體的業務時查找使用即可)
public static void main(String[] args) {//創建容器List<User> list = new ArrayList<User>();//創建多個對象User user1 = new User("zsr1", 20, "男");User user2 = new User("zsr2", 20, "男");User user3 = new User("zsr3", 20, "男");User user4 = new User("zsr4", 20, "男");User user5 = new User("zsr5", 20, "男");//將所有對象存入容器list.add(user1);list.add(user2);list.add(user3);list.add(user4);list.add(user5);//常用代碼測試System.out.println("Java對象集合轉化為JSON字符串: "+ JSON.toJSONString(list));System.out.println("Java對象user1轉化為JSON字符串: "+ JSON.toJSONString(user1));System.out.println("JSON字符串轉化為Java對象user1: "+ JSON.parseObject(JSON.toJSONString(user1), User.class));System.out.println("Java對象user1轉化為JSON對象: "+ JSON.toJSON(user1));System.out.println("JSON對象轉化為Java對象user1: "+ JSON.toJavaObject((JSON) JSON.toJSON(user1), User.class));
}
運行結果:
