我們在開發中后端經常需要接受來自于前端傳遞的Json字符串數據,怎么把Json字符串轉換為Java對象呢?后端也經常需要給前端返回Json字符串,怎么把Java對象數據轉換為Json字符串返回呢?
回顧JSON
JSON(JavaScript Object Notation)
各個JSON技術比較
早期 JSON 的組裝和解析都是通過手動編寫代碼來實現的,這種方式效率不高,所以后來有許多的關于組裝和解析 JSON 格式信息的工具類出現,如 json-lib、Jackson、Gson 和 FastJson 等,可以解決 JSON 交互的開發效率。
1)json-lib
json-lib 最早也是應用廣泛的 JSON 解析工具,缺點是依賴很多的第三方包,如 commons-beanutils.jar、commons-collections-3.2.jar、commons-lang-2.6.jar、commons-logging-1.1.1.jar、ezmorph-1.0.6.jar 等。
對于復雜類型的轉換,json-lib 在將 JSON 轉換成 Bean 時還有缺陷,比如一個類里包含另一個類的 List 或者 Map 集合,json-lib 從 JSON 到 Bean 的轉換就會出現問題。
所以 json-lib 在功能和性能上面都不能滿足現在互聯網化的需求。
2)開源的Jackson
開源的 Jackson 是 Spring MVC 內置的 JSON 轉換工具。相比 json-lib 框架,Jackson 所依賴 jar 文件較少,簡單易用并且性能也要相對高些。并且 Jackson 社區相對比較活躍,更新速度也比較快。
但是 Jackson 對于復雜類型的 JSON 轉換 Bean 會出現問題,一些集合 Map、List 的轉換出現問題。而 Jackson 對于復雜類型的 Bean 轉換 JSON,轉換的 JSON 格式不是標準的 JSON 格式。
3)Google的Gson
Gson 是目前功能最全的 JSON 解析神器,Gson 當初是應 Google 公司內部需求由 Google 自行研發。自從在 2008 年 5 月公開發布第一版后,Gson 就已經被許多公司或用戶應用。
Gson 主要提供了 toJson 與 fromJson 兩個轉換函數,不需要依賴其它的 jar 文件,就能直接在 JDK 上運行。在使用這兩個函數轉換之前,需要先創建好對象的類型以及其成員才能成功的將 JSON 字符串轉換為相對應的對象。
類里面只要有 get 和 set 方法,Gson 完全可以將復雜類型的 JSON 到 Bean 或 Bean 到 JSON 的轉換,是 JSON 解析的神器。Gson 在功能上面無可挑剔,但性能比 FastJson 有所差距。
4)阿里巴巴的FastJson
FastJson 是用 Java 語言編寫的高性能 JSON 處理器,由阿里巴巴公司開發。
FastJson 不需要依賴其它的 jar 文件,就能直接在 JDK 上運行。
FastJson 在復雜類型的 Bean 轉換 JSON 上會出現一些問題,可能會出現引用的類型,導致 JSON 轉換出錯,需要制定引用。
FastJson 采用獨創的算法,將 parse 的速度提升到極致,超過所有 JSON 庫。
綜上 4 種 JSON 技術的比較,在項目選型的時候可以使用 Google 的 Gson 和阿里巴巴的 FastJson 兩種并行使用,如果只是功能要求,沒有性能要求,可以使用Google 的 Gson。如果有性能上面的要求可以使用 Gson 將 Bean 轉換 JSON 確保數據的正確,使用 FastJson 將 JSON 轉換 Bean。
JSON 數據轉換
Spring MVC 在數據綁定的過程中需要對傳遞數據的格式和類型進行轉換,它既可以轉換 String 等類型的數據,也可以轉換 JSON 等其他類型的數據。
開源的Jackson
新建一個module ,springmvc-05-json , 添加web的支持
導入jar文件
Maven 項目在 pom.xml 文件中添加以下依賴。
1
2
3
4
5
6
|
<!-- https: //mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version> 2.9 . 8 </version> </dependency> |
配置Spring MVC核心配置文件
web.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
<?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> <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> |
springmvc-servlet.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
<?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/beans http: //www.springframework.org/schema/beans/spring-beans.xsd http: //www.springframework.org/schema/context https: //www.springframework.org/schema/context/spring-context.xsd http: //www.springframework.org/schema/mvc https: //www.springframework.org/schema/mvc/spring-mvc.xsd"> <!-- 自動掃描指定的包,下面所有注解類交給IOC容器管理 --> <context:component-scan base- package = "com.kuang.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> |
創建POJO類
1
2
3
4
5
6
7
8
|
package com.kuang.pojo; public class User { private String name; private int age; private String sex; /**省略setter和getter方法*/ |
創建控制器
完成后端Java對象轉換為前端Json字符串
@ResponseBody
當返回 POJO 對象時默認轉換為 JSON 格式數據進行響應
這里我們需要兩個新東西,一個是@ResponseBody,一個是ObjectMapper對象
@RestController(推薦)
返回json字符串統一解決
在類上直接使用 @RestController ,這樣子,里面所有的方法都只會返回 json 字符串了,不用再每一個都添加@ResponseBody !我們在前后端分離開發中,一般都使用
運行測試
配置Tomcat運行
解決亂碼
@RequestMaping的produces屬性
1
2
|
//produces:指定響應體返回類型和編碼 @RequestMapping (value = "/json1" ,produces = "application/json;charset=utf-8" ) |
如果項目中有許多請求則每一個都要添加
Spring配置統一指定(推薦)
我們可以在springmvc的配置文件上添加一段消息StringHttpMessageConverter轉換配置,這樣就不用每次都去處理了
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
<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> |
測試集合輸出
控制器增加方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
@RestController public class UserController { //produces:指定響應體返回類型和編碼 @RequestMapping (value = "/json1" ) public String json1() throws JsonProcessingException { //創建一個jackson的對象映射器,用來解析數據 ObjectMapper mapper = new ObjectMapper(); //創建一個對象 User user = new User( "秦疆1號" , 3 , "男" ); //將我們的對象解析成為json格式 String str = mapper.writeValueAsString(user); //由于@ResponseBody注解,這里會將str轉成json格式返回;十分方便 return str; } @RequestMapping ( "/json2" ) public String json2() throws JsonProcessingException { //創建一個jackson的對象映射器,用來解析數據 ObjectMapper mapper = new ObjectMapper(); //創建一個對象 User user1 = new User( "秦疆1號" , 3 , "男" ); User user2 = new User( "秦疆2號" , 3 , "男" ); User user3 = new User( "秦疆3號" , 3 , "男" ); User user4 = new User( "秦疆4號" , 3 , "男" ); List<User> list = new ArrayList<User>(); list.add(user1); list.add(user2); list.add(user3); list.add(user4); //將我們的對象解析成為json格式 String str = mapper.writeValueAsString(list); return str; } } |
輸出時間對象
增加一個新的方法
默認日期格式會變成一個數字,是1970年1月1日到當前日期的毫秒數!
Jackson 默認是會把時間轉成timestamps形式
自定義時間格式
抽取為工具類
如果要經常使用的話,這樣是比較麻煩的,我們可以將這些代碼封裝到一個工具類中;我們去編寫下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
package com.kuang.utils; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; import java.text.SimpleDateFormat; public class JsonUtils { public static String getJson(Object object) { return getJson(object, "yyyy-MM-dd HH:mm:ss" ); } public static String getJson(Object object,String dateFormat) { ObjectMapper mapper = new ObjectMapper(); //不使用時間差的方式 mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false ); //自定義日期格式對象 SimpleDateFormat sdf = new SimpleDateFormat(dateFormat); //指定日期格式 mapper.setDateFormat(sdf); try { return mapper.writeValueAsString(object); } catch (JsonProcessingException e) { e.printStackTrace(); } return null ; } } |
我們使用工具類,代碼就更加簡潔了!
阿里巴巴的FastJson
1
2
3
4
5
|
<dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version> 1.2 . 60 </version> </dependency> |
fastjson.jar是阿里開發的一款專門用于Java開發的包,可以方便的實現json對象與JavaBean對象的轉換,實現JavaBean對象與json字符串的轉換,實現json對象與json字符串的轉換。實現json的轉換方法很多,最后的實現結果都是一樣的。
這種工具類,我們只需要掌握使用就好了,在使用的時候在根據具體的業務去找對應的實現。和以前的commons-io那種工具包一樣,拿來用就好了!
fastjson 三個主要的類
JSON代表 JSONObject和JSONArray的轉化
- JSON類源碼分析與使用
- 仔細觀察這些方法,主要是實現json對象,json對象數組,javabean對象,json字符串之間的相互轉化。
JSONObject 代表 json 對象
- JSONObject實現了Map接口, 猜想 JSONObject底層操作是由Map實現的。
- JSONObject對應json對象,通過各種形式的get()方法可以獲取json對象中的數據,也可利用諸如size(),isEmpty()等方法獲取"鍵:值"對的個數和判斷是否為空。其本質是通過實現Map接口并調用接口中的方法完成的。
JSONArray 代表 json 對象數組
內部是有List接口中的方法來完成操作的。
代碼實例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
package com.kuang.controller; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.kuang.pojo.User; import java.util.ArrayList; import java.util.List; public class FastJsonDemo { public static void main(String[] args) { //創建一個對象 User user1 = new User( "秦疆1號" , 3 , "男" ); User user2 = new User( "秦疆2號" , 3 , "男" ); User user3 = new User( "秦疆3號" , 3 , "男" ); User user4 = new User( "秦疆4號" , 3 , "男" ); List<User> list = new ArrayList<User>(); list.add(user1); list.add(user2); list.add(user3); list.add(user4); System.out.println( "*******Java對象 轉 JSON字符串*******" ); String str1 = JSON.toJSONString(list); System.out.println( "JSON.toJSONString(list)==>" +str1); String str2 = JSON.toJSONString(user1); System.out.println( "JSON.toJSONString(user1)==>" +str2); System.out.println( " ****** JSON字符串 轉 Java對象*******" ); User jp_user1=JSON.parseObject(str2,User. class ); System.out.println( "JSON.parseObject(str2,User.class)==>" +jp_user1); System.out.println( " ****** Java對象 轉 JSON對象 ******" ); JSONObject jsonObject1 = (JSONObject) JSON.toJSON(user2); System.out.println( "(JSONObject) JSON.toJSON(user2)==>" +jsonObject1.getString( "name" )); System.out.println( " ****** JSON對象 轉 Java對象 ******" ); User to_java_user = JSON.toJavaObject(jsonObject1, User. class ); System.out.println( "JSON.toJavaObject(jsonObject1, User.class)==>" +to_java_user); } } |
到此這篇關于Spring MVC JSON數據交互的文章就介紹到這了,更多相關Spring MVC JSON數據交互內容請搜索服務器之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持服務器之家!
原文鏈接:https://blog.csdn.net/m0_53698336/article/details/121006145