Spring MVC如何設置響應
本篇文章介紹響應相關(guān)的知識, 通過 Spring 來設置響應中的值, 向客戶端返回設置好的響應.
1. 返回靜態(tài)頁面
我們首先使用 html 寫一個前端頁面, 再通過 Spring 方法, 將這個 html 頁面作為響應的內(nèi)容, 展示給用戶.
顯然, 方法返回的只是一個字符串, 并非 html 展示的頁面.
如何將 html 頁面返回給客戶端呢?? 這需要修改 類注解.
若方法返回的是一個頁面, 則需要將原來的類注解 @RestController 修改為 @Controller.
接下來, 對涉及到的幾個注解逐個進行解釋.
1.1 Spring 默認掃描路徑
我們知道, 每一個路徑, 都對應了一個方法. 當服務器收到客戶端的請求時, Spring 就會根據(jù)請求中的資源路徑, 尋找該路徑對應的方法, 進而計算響應結(jié)果, 最后返回響應.
而 Spring 中有大量的方法存在, 包括使用 Maven 引入的第三方庫, 都存在于 Spring 中. 若 Spring 要掃描所有的方法, 一個一個的去進行比對, 確定哪個是資源路徑所對應的方法的話, 那工作量是巨大的.
因此, Spring 有一個默認掃描路徑: 只掃描啟動類所在的目錄, 及其子目錄.
若請求中資源路徑對應的方法, 屬于啟動類所在目錄或子目錄時, 會被 Spring 掃描到:
而當請求中資源路徑所對應的方法, 不屬于啟動類所在目錄或子目錄時, 則 Spring 不會掃描, 客戶端就會顯示錯誤:
因此, Spring 也當然不會掃描 Maven 中第三方庫中的方法.
有了默認的掃描路徑, 大大降低了 Spring 的工作量, 提升了開發(fā)效率.
1.2 @RestController
雖然 Spring 有默認的掃描路徑, 但是當項目很大時, 這個路徑下也是會有很多的方法存在的.
于是, 可以使用 @RestController 對類進行標記, Spring 只需掃描被 @RestController 標記的類.
因此, Spring 的掃描對象為: 默認掃描路徑中的類 && 使用 @RestController 進行標記的類
當默認路徑下的類沒有使用 @RestController 進行標記時, 那么 Spring 也不會進行掃描, 進一步減少了 Spring 的工作量.
@RestController 的特性如下:
- 類注解. 只能對類進行使用
- 存活于運行階段. (整個項目運行時, 都存在)
- 包含 @Controller 和 @ResponseBody
其中, @Controller 表示返回的是頁面. @ResponseBody 表示返回的是數(shù)據(jù).
@RestController 也表示返回的是數(shù)據(jù).
由于 @RestController = @Controller + @ResponseBody, 因此, 左右兩側(cè)的注解效果相同:
1.2.1 @Controller => 返回頁面
@Controller 是一個類注解(只能給類使用), 并且使用此注解標記類時, 表示該類中的所有方法(@ResponseBody 標記的方法除外, 見下文), 返回的均是頁面.
因此, 我們將類的注釋修改為 @Controller, 就可以返回靜態(tài)頁面了:
Spring 會以 resources.static 為該 html 文件的基準路徑, 掃描指定路徑下的 html 文件, 并返回該 html 構(gòu)造的頁面. 并且, html 文件的路徑前要加上 /
不過, 現(xiàn)在后端已經(jīng)基本不會返回頁面了.
@RequestMapping("/resp") @Controller // 表示類中的方法只能返回頁面 public class RespController { @ResponseBody // 該方法可以返回數(shù)據(jù) @RequestMapping("/r1") public String returnPage() { // 返回頁面時, 一定要加上 / return "/index.html"; } }
1.2.2 @ResponseBody
@ResponseBody 既是一個類注解, 也是一個方法注解, 表示返回的是數(shù)據(jù).
當類注解為 @Controller 時, 類中的方法只能返回頁面, 若此時我們想返回數(shù)據(jù), 可以對方法使用 @ResponseBody 進行標記, 被標記的方法可以返回數(shù)據(jù).
綜上, @RestController, @Controller, @ResponseBody 的使用場景如下:
- 一個類中, 既有返回頁面的方法, 也有返回數(shù)據(jù)的方法 ==> 使用 @Controller 對類標記, 對返回數(shù)據(jù)的方法使用 @ResponseBody 標記.
- 如果一個類中所有的方法, 返回的都是數(shù)據(jù) ==> 使用 @RestController 或者 @Controller + @ResponseBody 對類標記
- 如果一個類中所有的方法, 返回的都是頁面 ==> 使用 @Controller 對類標記
- 類必須有 @Controller 注解才能被 Spring 掃描到(@RestController 包含了 @Controller)
2. 返回 HTML
默認情況下, 響應中的 Content-Type 都是 test/html, 因此, 瀏覽器收到數(shù)據(jù)后, 都會按照 html 的格式來解析, 最終展示在頁面上.
因此, 如果我們想要給客戶端返回一個 HTML 片段, 那我們無需任何操作, 直接返回 HTML 代碼即可.
// 返回 HTML 片段 @ResponseBody @RequestMapping("/r3") public String returnHTML() { return "<h1>這是一個一級標題</h1>"; }
2.1 @RequestMapping
@RequestMapping 是一個類注解, 也是一個方法注解, 既可以對類設置路徑, 也可以對方法設置路徑.
此外, @RequestMapping 還有一些屬性.
2.1.1 produces(修改響應的 Content-Type)
但是, 如果我們想要把這個 HTML 代碼, 當做一個普通的字符串去返回, 該怎么辦呢?
顯然, 我們將響應的 Content-Type 類型修改為純文本格式即可, 即: test/plain
我們可以通過修改 @RequestMapping 中的 produces 屬性, 來修改 Content-Type:
這樣, 瀏覽器接收響應后, 就會將 Body 中的內(nèi)容, 以純文本的格式來解析, 而不是當做 HTML .
// 返回純文本 @ResponseBody @RequestMapping(value = "/r4", produces = "text/plain") // 修改 Content-Type 為純文本格式 public String returnText() { // 當成普通字符串返回 return "<h1>這是一個一級標題</h1>"; }
2.1.2 其他屬性
@RequestMapping 中不僅有 produces 這一屬性, 還有其他屬性. 通過設置這些屬性值, 可以對請求或者響應中的內(nèi)容做出要求:
method
: 要求請求的方法必須是什么(如:GET, POST, ....), 否則不處理params
: 要求請求中必須包含哪些參數(shù), 否則不處理headers
: 要求請求的 header 中必須包含哪些 header 信息, 否則不處理consumes
: 要求請求的 Content-Type 必須是什么, 否則不處理produces
: 設置響應的 Content-Type
3. 返回 JSON
Spring 會根據(jù)返回數(shù)據(jù)的類型, 自動對 Content-Type 進行類型的轉(zhuǎn)換.
上文提到, 當返回的數(shù)據(jù)是字符串時, 默認的 Content-Type 是 text/html; 若想改成其他類型, 還需要手動進行轉(zhuǎn)換.
但是當我們返回的數(shù)據(jù)是一個對象時, Spring 會自動將這個對象序列化為 JSON 格式, 并自動將 Content-Type 轉(zhuǎn)換為 application/json:
// 返回 JSON @ResponseBody @RequestMapping("/r5") public UserInfo returnJson() { // 若返回的數(shù)據(jù)是一個對象 // Spring 會自動將響應中的 Content-Type 轉(zhuǎn)換為 JSON 格式 return new UserInfo("dings", "aaa", 1); }
4. 設置狀態(tài)碼
4.1 HttpServletResponse
在后端的 Spring 項目中, 我們既可以通過 HttpServletRequest 來獲取請求中的信息, 同樣也可以通過 HttpServletResponse 來設置響應中的信息.
因此, 我們可以拿到 HttpServletResponse 對象, 進而通過 setStatus 方法修改響應中的狀態(tài)碼:
// 設置狀態(tài)碼 @ResponseBody @RequestMapping("/r6") public String setStatus(HttpServletResponse response) { // 手動將響應中的狀態(tài)碼設置為 404 response.setStatus(404); return "設置狀態(tài)碼成功!!"; }
注意: 狀態(tài)碼不影響頁面的展示!!
不管狀態(tài)碼是什么, 都可以返回我們自定義的內(nèi)容. 至于為什么有些網(wǎng)站的 404 頁面是一些提示內(nèi)容, 因為那個界面也是維護那個網(wǎng)站的程序員自己代碼寫的.
程序員當然也可以將 404 頁面打扮的很漂亮!! 比如 bilibili:
5. 設置 Header
后端可以設置響應中的 header, 通過 header 來向客戶端傳遞一些信息.
仍然是通過 HttpServletResponse 設置響應中的 header:
(header 是以鍵值對的形式存儲數(shù)據(jù)的)
// 設置 header @ResponseBody @RequestMapping("/r7") public String setHeader(HttpServletResponse response) { response.setHeader("myHeader", "hahaha"); return "設置 header 成功!!"; }
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Kotlin基礎(chǔ)教程之函數(shù)定義與變量聲明
這篇文章主要介紹了Kotlin基礎(chǔ)教程之函數(shù)定義與變量聲明的相關(guān)資料,需要的朋友可以參考下2017-05-05使用ShardingJDBC進行數(shù)據(jù)分片以及讀寫分離
ShardingJDBC是一個輕量級的Java框架,提供了數(shù)據(jù)分片、讀寫分離、分布式主鍵生成等數(shù)據(jù)訪問功能,本文將給大家介紹如何使用ShardingJDBC進行數(shù)據(jù)分片以及讀寫分離,需要的朋友可以參考下2024-01-01Java數(shù)組轉(zhuǎn)List及Stream的基本方法使用方法
Java?的?Stream?流操作是一種簡潔而強大的處理集合數(shù)據(jù)的方式,允許對數(shù)據(jù)進行高效的操作,如過濾、映射、排序和聚合,這篇文章主要介紹了Java數(shù)組轉(zhuǎn)List及Stream的基本方法使用教程,需要的朋友可以參考下2024-08-08Spring Boot靜態(tài)資源路徑的配置與修改詳解
最近在做SpringBoot項目的時候遇到了“白頁”問題,通過查資料對SpringBoot訪問靜態(tài)資源做了總結(jié),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2022-09-09