JOSN處理和HttpMessageConverter
1.JSON處理-@ResponseBody
說明:在實際開發中,我們往往需要服務器回傳的資料都是 JSON 格式,
SpringMVC 提供了 @ResponseBody 注解,用來標注 Controller 方法的回傳的格式為 JSON,將 Java 物件或集合轉為 JSON 格式的資料,
方法回傳的物件通過適當的轉換器轉換為指定的格式之后,寫入到 response 物件的 body 區,通常用來回傳 JSON 資料或者是 XML 資料,
注意:在使用此注解之后不會再走視圖處理器,而是直接將資料寫入到輸入流中,它的效果等同于通過 response物件輸出指定格式的資料,
使用案例
下面是要完成的效果:請求目標方法,目標方法回傳一個json格式的資料
(1)引入處理JSON需要的jar包,注意spring5.x 需要使用jackson-2.9.x.jar 的包,
(2)創建 json.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>json提交</title>
<!--引入jquery-->
<script type="text/javascript" src="https://www.cnblogs.com/liyuelian/archive/2023/02/16/script/jquery-3.6.0.min.js"></script>
<!--使用jquery的ajax-->
<script type="text/javascript">
$(function () {
//給id=getJson的超鏈接系結一個事件
$("#getJson").click(function () {
var href = https://www.cnblogs.com/liyuelian/archive/2023/02/16/this.href;
var args = {"time": new Date()};
$.get(
href,//請求url
args,//發送時間,防止瀏覽器快取
function (data) {
console.log("data="https://www.cnblogs.com/liyuelian/archive/2023/02/16/, data)
},"json"//指定回傳的格式
)
return false;//超鏈接不跳轉
})
})
</script>
</head>
<body>
<h1>請求一個json資料</h1>
<a href="https://www.cnblogs.com/liyuelian/archive/2023/02/16//json/dog" id="getJson">點擊獲取json資料</a>
</body>
</html>
(3)創建 Javabean 作為回傳的資料
package com.li.web.json.entity;
/**
* @author 李
* @version 1.0
*/
public class Dog {
private String name;
private String address;
public Dog() {
}
public Dog(String name, String address) {
this.name = name;
this.address = address;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "Dog{" +
"name='" + name + '\'' +
", address='" + address + '\'' +
'}';
}
}
(4)創建 JsonHandler 處理請求
package com.li.web.json;
import com.li.web.json.entity.Dog;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
/**
* @author 李
* @version 1.0
*/
@Controller
public class JsonHandler {
/**
* 1.目標方法的 @ResponseBody注解表示回傳的資料是json格式
* 2.SpringMVC 底層根據目標方法@ResponseBody,回傳指定格式
* 回傳的格式根據http請求來處理
* 3.底層原理之前在實作SpringMVC底層機制時講過,
* 這里原生的SpringMVC使用了轉換器 HttpMessageConverter
* @return
*/
@RequestMapping(value = "https://www.cnblogs.com/json/dog")
@ResponseBody
public Dog getJson(){
//回傳物件
//SpringMVC 會根據你的設定,轉成json格式資料回傳
Dog dog = new Dog();
dog.setName("大黃狗");
dog.setAddress("小新的家");
return dog;
}
}
(5)啟動tomcat,訪問json.jsp頁面,點擊超鏈接,回傳如下資訊:
2.JSON處理-@RequestBody
和 @ResponseBody 注解相反,@RequestBody 注解是將客戶端提交的 json資料,封裝成 Javabean 物件,
注意:@RequestBody 用于修飾引數,
應用案例
在前端頁面發出一個json資料,后端接收資料,并使用 @RequestBody 注解將 json 資料轉成 Javabean 物件,然后使用 @ResponseBody 注解將該 Javabean 物件轉回 json 資料,回傳給前端,
(1)修改json.jsp,增加發送 json 資料代碼
這里使用 ajax 請求的 contentType 指定發送格式為 json,發送請求時會被封裝到請求頭中,這樣后端在接收時,根據 contentType 能知道資料是 json 格式的,
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>json提交</title>
<!--引入jquery-->
<script type="text/javascript" src="https://www.cnblogs.com/liyuelian/archive/2023/02/16/script/jquery-3.6.0.min.js"></script>
<!--使用jquery的ajax-->
<script type="text/javascript">
$(function () {
//系結按鍵點擊事件,提交json資料
$("button[name='but1']").click(function () {
var url = "/springmvc/save2";
var username = $("#username").val();
var age = $("#age").val();
//將 username和 age封裝成 json字串
var args = {"username": username, "age": age};//json物件
//將json物件封裝成json字串
var jsonString = JSON.stringify(args);//json字串
$.ajax({
url:url,
data:jsonString,
type:"POST",
success:function (data) {
console.log("回傳的data="https://www.cnblogs.com/liyuelian/archive/2023/02/16/,data)
},
//指定發送資料的編碼和格式
contentType:"application/json;charset=utf-8"
})
})
})
</script>
</head>
<body>
<h1>發出一個json資料</h1>
u:<input id="username" type="text"/><br/>
a:<input id="age" type="text"/><br/>
<button name="but1">添加用戶</button>
</body>
</html>
(2)User.java
package com.li.web.json.entity;
/**
* @author 李
* @version 1.0
*/
public class User {
private String username;
private Integer age;
public User() {
}
public User(String username, Integer age) {
this.username = username;
this.age = age;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "User{" +
"username='" + username + '\'' +
", age=" + age +
'}';
}
}
(3)JsonHandler.java
package com.li.web.json;
import com.li.web.json.entity.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
/**
* @author 李
* @version 1.0
*/
@Controller
public class JsonHandler {
/**
* 1.在形參指定了 @RequestBody 注解
* 2.SpringMVC 就會將提交的json字串資料填充給指定的Javabean
* @param user 指定的Javabean物件
* @return 這里使用了 @ResponseBody 注解,因此回傳的也是json
*/
@RequestMapping(value = "https://www.cnblogs.com/save2")
@ResponseBody
public User save2(@RequestBody User user) {
//將前端傳過來的資料以json的格式回傳瀏覽器
System.out.println("user=" + user);
return user;
}
}
(4)啟動tomcat,訪問json.jsp,提交和回傳的資料如下:
后臺輸出:
說明后端成功拿到了前端發送的 json 資料,并將其填充到了指定的Javabean物件中,然后又將 Javabean 物件轉成了 json 格式的資料回傳前端,
3.JSON處理-注意事項和細節
-
目標方法正常回傳 Json 需要的資料,可以是一個物件,也可以是一個集合
-
@ResponseBody 注解也可以用于修飾于 Controller 上,這樣會對 Controller 中所有方法生效
-
@ResponseBody 和 @Controller 可以直接寫成一個注解 @RestController
4.HttpMessageConverter
- 基本說明
SpringMVC 處理 JSON 底層實作是依靠 HttpMessageConverter<T> 來進行轉換的
- 作業機制簡圖
整個程序為:
請求報文發送到后端,HttpInputMessage 的實作子類會將請求報文封裝起來,然后找到對應的轉換器進行轉換,然后封裝成對應的 Java 物件給到目標方法,
目標方法回傳,找到指定格式對應的訊息轉換器,訊息轉換器將回傳的資料再進行轉換,將轉換后的資料封裝到 HttpOutputMessage ,然后回傳給客戶端,
這里的 HttpMessageConverter(訊息轉換器),HttpInputMessage 和 HttpOutputMessage 都是介面,下面有很多實作子類,會根據請求/回應報文頭來找到匹配子類,
- 處理JSON-底層實作(HttpMessageConverter< T>)
- 使用
HttpMessageConverter<T>將請求資訊轉換并系結到處理方法的入參中,或將回應結果轉為對應型別的回應資訊,Spring 提供了兩種途徑:- 使用
@RequestBody/@ResponseBody對目標方法或方法引數進行標注 - 使用
HttpEntity<T>/ResponseEntity<T>作為目標方法的入參或回傳值
- 使用
- 當控制器處理方法使用到
@RequestBody / @ResponseBody或HttpEntity<T> / ResponseEntity<T>時,Spring 首先根據請求頭或回應頭的 Accept 屬性選擇匹配的 HttpMessageConverter,進而根據引數型別或泛型型別的過濾得到匹配的訊息轉換器 HttpMessageConverter,若找不到可用的訊息轉換器,將會報錯,
debug原始碼
以處理JSON-@RequestBody的例子為案例:
(1)快捷鍵 ctrl+n 在 IDEA 中搜索 AbstractJackson2HttpMessageConverter 類,在該類的 readJavaType() 方法中打上斷點,點擊 debug
(2)瀏覽器訪問 json.jsp 頁面,填寫資料并點擊按鈕
(3)后臺游標跳轉到斷點處,此時方法引數 inputMessage 的資料如下,說明此時 http 請求的內容已經被封裝到了給物件中,
方法引數 javaType 用于指定 inputMessage 的相應資料填充到什么樣的 Java 型別中
(4)點擊 step over,方法首先獲取http請求資料指定的型別 contentType
(5)在獲取了指定的資料型別后,將資料進行轉換
(6)點擊 step over:

(7)在目標方法中添加斷點,點擊 resume,可以看到游標跳轉到斷點處,此時目標方法就拿到了由json資料填充后的 Javabean物件

(8)在 AbstractJackson2HttpMessageConverter 類的 writeInternal() 方法中打上斷點,點擊 resume,游標跳轉到如下位置:
由于我們在目標方法使用了 @ResponseBody 注解,因此回傳的時候不再會進入視圖處理器,而是通過訊息轉換器,將回傳的 user 物件轉換為指定的 json 格式資料,下圖的 HttpOutputMessage 物件就是用于存放轉換后的資料,
獲取要轉換的格式:
使用 selectObjectMapper 方法將物件轉換為指定格式:
后面就是進行一些處理,然后將資料回傳給客戶端,
(9)然后瀏覽器獲得指定格式的資料:
5.檔案下載-ResponseEntity< T>
- 說明
在SpringMVC 中,通過回傳 ResponseEntity<T> 的型別,可以實作檔案的下載功能
使用案例
實作效果如下:在前端頁面點擊超鏈接,可以實作檔案下載,
(1)修改json.jsp
(2)修改 JsonHandler.java,增加方法,用于回應下載檔案的請求
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/544100.html
標籤:其他
下一篇:紅黑樹——一種自平衡的二叉樹
