作者簡(jiǎn)介 :一只大皮卡丘,計(jì)算機(jī)專業(yè)學(xué)生,正在努力學(xué)習(xí)、努力敲代碼中! 讓我們一起繼續(xù)努力學(xué)習(xí)!
該文章參考學(xué)習(xí)教材為:
《Java EE企業(yè)級(jí)應(yīng)用開發(fā)教程 (Spring + Spring MVC +MyBatis)》 黑馬程序員 / 編著
文章以課本知識(shí)點(diǎn) + 代碼為主線,結(jié)合自己看書學(xué)習(xí)過程中的理解和感悟 ,最終成就了該文章文章用于本人學(xué)習(xí)使用 , 同時(shí)希望能幫助大家。
歡迎大家點(diǎn)贊?? 收藏? 關(guān)注??哦?。?!(侵權(quán)可聯(lián)系我,進(jìn)行刪除,如果雷同,純屬巧合)
?
SpringMVC 在數(shù)據(jù)綁定 的過程中,需要對(duì) 傳遞數(shù)據(jù)的格式 和 類型 進(jìn)行 轉(zhuǎn)換 ,它 既可以轉(zhuǎn)換String 類型的數(shù)據(jù),也能夠 轉(zhuǎn)換 JSON 等其他類型的數(shù)據(jù)。
一、JSON 數(shù)據(jù)交互
JSON 是近幾年才流行的一種新的數(shù)據(jù)格式,它與 XML 非常相似,都是用于存儲(chǔ)數(shù)據(jù)的;但 JSON 相對(duì)于 XML來說,解析速度更快,占用空間更小。因此在實(shí)際開發(fā)中,使用JSON 格式的數(shù)據(jù)進(jìn)行前后臺(tái)的數(shù)據(jù)交互是很常見的。
1.1 JSON概述
JSON ( JavaScript Object Notation ,JS對(duì)象標(biāo)記 ) 是一種 輕量級(jí) 的 數(shù)據(jù)交換格式。它是 基于 JavaScript 的一個(gè) 子集 ( JSON 是 JavaScript 的子集 ),使用了 C、C++、C#、Java、JavaScript、Perl、Python 等其他語言的約定,采用 完全獨(dú)立于編程語言的文本格式來存儲(chǔ)和表示數(shù)據(jù)。這些特性使 JSON 成為理想的數(shù)據(jù)交互語言,它易于閱讀和編寫,同時(shí)也易于機(jī)器解析和生成。
與 XML 一樣,JSON 也是基于純文本的數(shù)據(jù)格式。可以使用 JSON 傳輸一個(gè)簡(jiǎn)單的String、Number、Boolean,也可以傳輸一個(gè)數(shù)組或者一個(gè)復(fù)雜的 Object 對(duì)象。
1.2 JSON的“數(shù)據(jù)結(jié)構(gòu)”
JSON 有如下 兩種數(shù)據(jù)結(jié)構(gòu) :
①對(duì)象結(jié)構(gòu)②數(shù)組結(jié)構(gòu)
對(duì)象結(jié)構(gòu)
對(duì)象結(jié)構(gòu) 以 “{”開始,以 “}”結(jié)束。中間部分 由0個(gè)或多個(gè)以英文逗號(hào) “,” 分隔的 name/value對(duì) 構(gòu)成,name 和 value 之間以英文冒號(hào) “:” 分隔。 (以 { }開始和結(jié)束,中間由0個(gè)或多個(gè) name:value,name:value 對(duì)構(gòu)成,name 和value之間用 : 分隔 )
例子如 :
{“id”:111,“name”:“張三”} ,這個(gè)就是 JSON的“數(shù)據(jù)結(jié)構(gòu)”中的對(duì)象結(jié)構(gòu)”。(name必須為String類型,value就不限制一定得是String類型。)JSON “對(duì)象結(jié)構(gòu)” 的“存儲(chǔ)形式” 下圖所示 :
JSON “對(duì)象結(jié)構(gòu)” 的語法結(jié)構(gòu)代碼如下 :
{ key1:value1, key2:value2, ... } ps : key必須為String類型,value不一定得是String類型
其中關(guān)鍵字 (key )必須為String 類型,值( value )可以是 String、Number、Object、Array等數(shù)據(jù)類型。例如,一個(gè)address 對(duì)象包含城市、街道、郵編等信息,使用JSON的表示形式如下 :
{ "city":"beijing","street":"Xisanqi","postcode":10096}
數(shù)組結(jié)構(gòu)
數(shù)組結(jié)構(gòu)以 “[”開始,以 “]”結(jié)束。中間部分由0個(gè)或多個(gè)以英文逗號(hào) “,” 分隔的值的列表組成。
(value 值 之間用英文逗號(hào) , 進(jìn)行 分隔 )JSON “數(shù)組結(jié)構(gòu)” 的“存儲(chǔ)形式” 下圖所示 :
JSON “數(shù)組結(jié)構(gòu)” 的語法結(jié)構(gòu)代碼如下 :
[ value1, value2, ... ] ps1 : value可以是Spring、Number、Boolean、null等數(shù)據(jù)類型 ps2 : value之間用英文逗號(hào), 進(jìn)行分隔
value 可以是Spring、Number、Boolean、null等數(shù)據(jù)類型,例如 :
["abc",123,flase,null]
上述 兩種 數(shù)據(jù)結(jié)構(gòu) ( 對(duì)象結(jié)構(gòu)、數(shù)組結(jié)構(gòu) )也可以分別組合構(gòu)成更為復(fù)雜的數(shù)據(jù)結(jié)構(gòu)。例如 : 一個(gè)
person對(duì)象包含 name、hobby 和 address 對(duì)象 ,其代碼表現(xiàn)形式如下 :
(要實(shí)現(xiàn)這個(gè)例子中的JSON數(shù)據(jù)表示,要用到數(shù)據(jù)結(jié)構(gòu)中的 “對(duì)象結(jié)構(gòu)” 和 “數(shù)組結(jié)構(gòu)” 這兩種數(shù)據(jù)結(jié)構(gòu))//“對(duì)象結(jié)構(gòu)”中嵌套了“數(shù)組結(jié)構(gòu)” 和 “對(duì)象結(jié)構(gòu)” { "name":"張三", "hobby":["唱","跳","rap"], "address":{ "city":"Beijing, "street","Xisanqi", "postcode":10096 } }
需要注意的是,如果使用 JSON存儲(chǔ)單個(gè)數(shù)據(jù) (如 “abc”),一定要使用 數(shù)組結(jié)構(gòu)的形式,不要使用 對(duì)象結(jié)構(gòu),因?yàn)?對(duì)象結(jié)構(gòu) 必須是“ 名稱:值”的形式。
1.3 JSON的“數(shù)據(jù)轉(zhuǎn)換”
為了實(shí)現(xiàn)瀏覽器與 控制器類(Controller) 之間的數(shù)據(jù)交互,Spring 提供了一個(gè) HttpMessageConverter<T>接口 來完成此項(xiàng)工作。該接口主要用于將請(qǐng)求信息中的數(shù)據(jù) “轉(zhuǎn)換”為一個(gè)類型為 T 的對(duì)象,并將類型為T的對(duì)象綁定到請(qǐng)求方法的 參數(shù) 中,或者將 對(duì)象 轉(zhuǎn)換為 響應(yīng)信息 傳遞給 瀏覽器顯示。
Spring 為 HttpMessageConverter<T>接口提供了很多實(shí)現(xiàn)類,這些實(shí)現(xiàn)類可以對(duì)不同類型的數(shù)據(jù)進(jìn)行信息轉(zhuǎn)換。其中 MappingJackson2HttpMessageConverter 是SpringMVC 默認(rèn)處理JSON 格式請(qǐng)求響應(yīng)的 實(shí)現(xiàn)類。該實(shí)現(xiàn)類利用 Jackson 開源包讀寫 JSON 數(shù)據(jù),將Java對(duì)象轉(zhuǎn)換為JSON對(duì)象和 XML 文檔,同時(shí)也可以將JSON 對(duì)象和 XML文檔轉(zhuǎn)換為 Java對(duì)象。
要使用MappingJackson2HttpMessageConverter對(duì)數(shù)據(jù)進(jìn)行轉(zhuǎn)換。
(可通過 <mvc:annotation-driven/>來自動(dòng)配置 : MappingJackson2HttpMessageConverter轉(zhuǎn)換器 )
(通過該轉(zhuǎn)換器來將后端的對(duì)象類型的返回值,轉(zhuǎn)換為JSON格式數(shù)據(jù)響應(yīng)給前端 )JSON數(shù)據(jù)轉(zhuǎn)換 要使用Jackson的開源包 ( 需要JAR ) :
①jackson-annotations.jar : JSON轉(zhuǎn)換注解包。
②jackson-core.jar : JSON轉(zhuǎn)換核心包。
③jackson-databind.jar : JSON 轉(zhuǎn)換的數(shù)據(jù)綁定包。JSON數(shù)據(jù)轉(zhuǎn)換中的Jackson所需JAR (百度網(wǎng)盤)
也可通過 “http://mvnrepository.com/artifact/com.fasterxml.jackson.core” 地址自行下載JAR。
- 在使用 注解式開發(fā)時(shí),需要用到兩個(gè)重要的 JSON 格式轉(zhuǎn)換注解,分別為@RequestBody 和 @ResponseBody,兩個(gè)與“JSON格式轉(zhuǎn)換”有關(guān)的注解描述如下 :
注解 說明 @RequestBody 用于將 請(qǐng)求體 中的 數(shù)據(jù)綁定 到 方法 的 形參 中。該注解 用在方法 的 形參 上。該注解用在 “方法的形參”上。
如 :
將前端傳來的JSON類型的參數(shù),轉(zhuǎn)換為User類型,后賦值入該指定的形參中。
(該注解的作用并不局限與為JSON數(shù)據(jù)轉(zhuǎn)換服務(wù),其本質(zhì)是,將請(qǐng)求體中的數(shù)據(jù)綁定到方法的形參中 ,但簡(jiǎn)單類型的參數(shù)綁定不一定要用到該注解,復(fù)雜參數(shù)綁定可考慮用該注解)@ResponseBody 用于 直接返回return 對(duì)象。該注解用在 方法 上。
將方法的“返回值”自動(dòng)轉(zhuǎn)換為“指定的格式”,后響應(yīng)給"前端"。
ps :
① 如果方法的 返回值 是一個(gè) “字符串”,那么這個(gè)字符串會(huì)直接寫入響應(yīng)體中;
② 如果 返回值 是一個(gè) “對(duì)象”,SpringMVC會(huì) 默認(rèn)使用MappingJackson2HttpMessageConverter(在Spring 4.x版本后)將 對(duì)象 轉(zhuǎn)換為 JSON格式的字符串,然后寫入響應(yīng)體中(響應(yīng)給前端)。
用 <mvc:annotation-driven/>的方式 來“自動(dòng)配置” MappingJackson2HttpMessageConverter轉(zhuǎn)換器 (來完成JSON數(shù)據(jù)轉(zhuǎn)換)
用 <mvc:annotation-driven/> 來 “自動(dòng)配置”MappingJackson2HttpMessageConverter轉(zhuǎn)換器 來完成 JSON數(shù)據(jù)轉(zhuǎn)換 例子如 : (前端傳遞JSON數(shù)據(jù)給后端,后端響應(yīng)JSON格式數(shù)據(jù)給“前端”) :
第一步、導(dǎo)入依賴 :
JSON交互中的所需的各種JAR)
第二步、編寫JSON數(shù)據(jù)交互的各種文件 :
該 JSON數(shù)據(jù)交互 的“項(xiàng)目結(jié)構(gòu)” :
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"> <!-- 配置DispatcherServlet : 前端控制器,負(fù)責(zé)url的攔截和分發(fā) --> <servlet> <servlet-name>dispatcherServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!-- 配置springmvc-config.xml 配置文件的位置 (上下文配置位置) --> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:springmvc-config.xml</param-value> </init-param> <!-- 配置服務(wù)器啟動(dòng)時(shí)加載此配置文件,加載此Servlet --> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>dispatcherServlet</servlet-name> <!-- 攔截/接收所有請(qǐng)求 --> <!-- 此處的/會(huì)將頁(yè)面中引入的靜態(tài)文件(如.js文件)也進(jìn)行攔截,攔截后頁(yè)面就找不到這些“靜態(tài)資源”了,會(huì)導(dǎo)致報(bào)錯(cuò)。 此時(shí)可在springmvc-config.xml中通過 <mvc:resources mapping="" location=""/> 標(biāo)簽來對(duì)“靜態(tài)資源”放行 --> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>
springmvc-config.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/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd"> <!-- 組件掃描,根包掃描 : 讓注解生效 --> <context:component-scan base-package="com.myh.controller"/> <!-- 配置視圖解析器 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/jsp/"/> <property name="suffix" value=".jsp"/> </bean> <!-- 注解驅(qū)動(dòng) : 作用1 : 用于啟用"注解驅(qū)動(dòng)"的"控制器方法",同時(shí)讓注解生效。(一般而言,用到"控制器類"或"控制器方法" 就要配置"注解驅(qū)動(dòng)") 作用2 : 會(huì)注冊(cè)RequestMappingHandlerMapping 和 RequestMappingHandlerAdapter這兩個(gè)bean 作用3 : 對(duì)“讀寫XML”和“讀寫JSON”的支持 (所以此處的JSON數(shù)據(jù)交互要在springmvc-config.xml中用此注解) 作用4 : <mvc:annotation-driven/>注解會(huì)會(huì)自動(dòng)配置一些常用的消息轉(zhuǎn)換器(Message Converters),其中就包括處理JSON數(shù)據(jù)的`MappingJackson2HttpMessageConverter`(所以進(jìn)行JSON數(shù)據(jù)交互時(shí)要導(dǎo)入該標(biāo)簽: 注解驅(qū)動(dòng)) --> <mvc:annotation-driven/> <!-- 放行靜態(tài)資源,讓前端能直接訪問“靜態(tài)資源” --> <mvc:resources mapping="/js/" location="/js/**"/> </beans>
在上述springmvc-config.xml文件中,不僅配置了組件掃描器 (進(jìn)行根包掃描) 和 視圖解析器,還配置了Spring MvC的注解驅(qū)動(dòng)mvc:annotation-drivern/ 和 靜態(tài)資源訪問映射<mvc:resources …>,其中、<mvc:annotation-drivern/>配置會(huì)自動(dòng)注冊(cè) RequestMappingHandlerMapping 和 RequestMappingHandlerAdapter 這兩個(gè)Bean,并提供 對(duì)讀寫XML和讀寫JSON等功能的 支持。
(所以此處要配置該內(nèi)容,因?yàn)榇颂帪?strong>JSON的數(shù)據(jù)交互)
<mvc:resources… />元素用于配置靜態(tài)資源的訪問路徑,由于在 web.xml 中配置的 “/” 會(huì) 將頁(yè)面中引入 ( 如.js )的靜態(tài)文件也進(jìn)行攔截,而攔截后頁(yè)面中將找不到這些靜態(tài)資源文件,這樣就會(huì)引起頁(yè)面報(bào)錯(cuò)。而增加了靜態(tài)資源的訪問映射配置后,程序會(huì)自動(dòng)地去配置路徑下找靜態(tài)的內(nèi)容。<mvc:resources …> 中有兩個(gè)重要屬性 :location 和 mapping,兩個(gè)屬性的說明如下 :
屬性 說明 location 用于 定位需要訪問的本地靜態(tài)資源文件路徑,具體到某個(gè)文件夾。 mapping 匹配靜態(tài)資源全路徑,其中 “/**” 表示 文件夾及其子文件夾下 的 某個(gè)具體文件。
User.java :
package com.myh.po; public class User { private String username; private String password; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } @Override public String toString() { return "User{" + "username='" + username + '\'' + ", password='" + password + '\'' + '}'; } }
userController.java :
package com.myh.controller; import com.myh.po.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.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; @Controller //把該類標(biāo)記為“處理器類”,用于鏈接DispatcherServlet,讓該類中的方法能被前端訪問 public class UserController { // @ResponseBody() : 將User對(duì)象轉(zhuǎn)換為JSON格式數(shù)據(jù)響應(yīng)給“前端” //該注解本質(zhì)意思是 : 將方法的“返回值”自動(dòng)轉(zhuǎn)換為“指定的格式”,后響應(yīng)給"前端"。如:如果方法的返回值是一個(gè)"字符串",那么這個(gè)字符串會(huì)直接寫入響應(yīng)體中; // 如果返回值是一個(gè)“對(duì)象”,Spring MVC會(huì)默認(rèn)使用 MappingJackson2HttpMessageConverter(在Spring 4.x版本后)將對(duì)象轉(zhuǎn)換為JSON格式的字符串,然后寫入響應(yīng)體中(響應(yīng)給前端) @ResponseBody @RequestMapping(value = "/testJson") //@RequestBody : 將前端傳來的JSON類型的參數(shù),轉(zhuǎn)換為User類型,后賦值入該User對(duì)象參數(shù)中 //該注解本質(zhì)意思 : 將前端傳來的數(shù)據(jù)綁定到方法中的“形參”中 public User testJson(@RequestBody User user) { System.out.println(user); return user; //響應(yīng)一個(gè)User對(duì)象給前端(通過@ResponseBody注解會(huì)轉(zhuǎn)換為JSON格式數(shù)據(jù),后進(jìn)行響應(yīng)) //此時(shí)返回值為一個(gè)對(duì)象,因?yàn)橛昧薂ResponseBody注解,所以此時(shí)會(huì)將其轉(zhuǎn)換為JSON格式的字符串,后響應(yīng)給前端。 } }
在 userController.java 中,使用注解方式定義了一個(gè)控制器類,并編寫了接收和響應(yīng)JSON格式數(shù)據(jù)
的testJson( )方法,在方法中接收并打印了接收到的JSON格式的用戶數(shù)據(jù),然后響應(yīng)了JSON格式的用戶對(duì)象。
方法中的 @RequestBody注解 用于將前端請(qǐng)求體中的JSON格式數(shù)據(jù)綁定到形參user上,
@ResponseBody注解 用于直接返回User對(duì)象( 當(dāng)返回POJO對(duì)象時(shí),會(huì)默認(rèn)轉(zhuǎn)換為JSON格式數(shù)據(jù)進(jìn)行響應(yīng))。index.jsp :
<%-- Created by IntelliJ IDEA. To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>測(cè)試JSON數(shù)據(jù)交互</title> <%-- ${pageContext.request.contextPath} : 獲取當(dāng)前應(yīng)用的“上下文路徑” ,獲取當(dāng)前應(yīng)用的“根URL” --%> <%-- 例如,如果你的 Web 應(yīng)用部署在 <http://example.com/myapp/>,那么上下文路徑就是 `/myapp`。 --%> <%-- 導(dǎo)入Jquery文件 --%> <script type="text/javascript" src="${pageContext.request.contextPath}/js/jquery-3.7.1.js"></script> <script type="text/javascript"> function testJson() { //獲取用戶輸入的“用戶名”和“密碼” var username = $("#username").val(); var password = $("#password").val(); //ajax操作 $.ajax({ url: "${pageContext.request.contextPath}/testJson", type:"POST", // {username:username, password: password} : 為JS字面量對(duì)象,可通過JSON.stringify()方法轉(zhuǎn)換為JSON字符串 data : JSON.stringify({username:username, password: password}), //表示: 后端響應(yīng)的“數(shù)據(jù)類型” dataType:"json", //表示前端傳遞給后端的數(shù)據(jù)類型 或 后端響應(yīng)給前端的“數(shù)據(jù)類型” contentType: "application/json;charset=UTF-8", //回調(diào)函數(shù) success : function (data) { if (data != null) { alert("你輸入的用戶名為: " + data.username + ",密碼為: " + data.password); } } }); } </script> </head> <body> <form> 用戶名: <label for="username"></label><input type="text" name="username" id="username"><br/> 密碼: <label for="password"></label><input type="password" name="password" id="password"><br/> <input type="button" value="測(cè)試JSON交互2" onclick=" testJson()"> </form> </body> </html>
在index.jsp文件中,編寫了一個(gè)測(cè)試JSON交互的表單,當(dāng)單擊“測(cè)試JSON交互”按鈕時(shí),會(huì)執(zhí)行頁(yè)面中的testJson( )函數(shù)。在函數(shù)中使用了jQuery的AJAX方式將JSON格式的用戶名和密碼傳遞到以"/testjson" 結(jié)尾的請(qǐng)求中。
需要注意的是,在AJAX中包含了3個(gè)特別重要的屬性,其說明如下 :
屬性 說明 data 即 前端 請(qǐng)求時(shí)攜帶的數(shù)據(jù) / 參數(shù)。當(dāng)使用JSON格式時(shí),要注意編寫規(guī)范。 dataType 表示 后端響應(yīng)的數(shù)據(jù)的類型。
ps :
當(dāng) 后端響應(yīng)數(shù)據(jù) 為JSON格式時(shí),dataType屬性 此時(shí)的 值 必須 為json。
(dataType : "json"也可以省略不寫,頁(yè)面會(huì)自動(dòng)識(shí)別響應(yīng)的數(shù)據(jù)格式)contentType 表示 ①前端請(qǐng)求的數(shù)據(jù)的類型 或 ② 后端響應(yīng)的數(shù)據(jù)的類型。
ps :
當(dāng) 請(qǐng)求數(shù)據(jù)為JSON格式 時(shí),contentType的值 必須為 application/json;charset=UTF-8。
配置tomcat,且啟動(dòng)項(xiàng)目成功后,自動(dòng)跳轉(zhuǎn)index.jsp頁(yè)面,填寫數(shù)據(jù)后,前端將JSON格式數(shù)據(jù)傳遞給后端
后端控制臺(tái)輸出效果 :
從上面的控制臺(tái)輸出結(jié)果可以看出,編寫的代碼已經(jīng)正確 實(shí)現(xiàn)了JSON數(shù)據(jù)交互,可以將 JSON格式 的請(qǐng)求數(shù)據(jù)轉(zhuǎn)換為方法中的 Java對(duì)象 ,也可以將 Java對(duì)象 轉(zhuǎn)換為 JSON格式 的響應(yīng)數(shù)據(jù)。
(該例子中前端傳輸JSON格式參數(shù)給后端,后端用 @RequestBody注解將 JSON格式數(shù)據(jù)綁定到方法的形參中,后端返回值為User對(duì)象類型,但因?yàn)槭褂昧?@ResponseBody注解,所以此處返回值的User對(duì)象會(huì)被SpringMVC默認(rèn)使用MappingJackson2HttpMessageConverter轉(zhuǎn)換器 來將對(duì)象轉(zhuǎn)換為JSON格式的字符串,后響應(yīng)給前端,所以可以說 JSON格式–> Java對(duì)象 , Java對(duì)象 –>JSON格式 )
ps :
該例子中用的Java對(duì)象轉(zhuǎn)換為JSON格式的轉(zhuǎn)換器為 :MappingJackson2HttpMessageConverter ( 該例子 中用的的 “自動(dòng)配置” 轉(zhuǎn)換器)。
用<bean>標(biāo)簽方式的來“自行配置” JSON轉(zhuǎn)換器配置MappingJackson2HttpMessageConverter轉(zhuǎn)換器 (來完成JSON數(shù)據(jù)轉(zhuǎn)換)
在配置JSON轉(zhuǎn)換器 : MappingJackson2HttpMessageConverter時(shí),除了常用的 <mvc:annotation-drivern /> 方式 “自動(dòng)配置” 外,還可以使用 <bean>標(biāo)簽 的方式進(jìn)行 “自行配置”。
<bean>標(biāo)簽自行配置 : 配置方式如下 :
<!-- 用bean標(biāo)簽的方式來“自行配置”轉(zhuǎn)換器 : MappingJackson2HttpMessageConverter --> <!-- "處理器映射器"和"處理器適配器"必須搭配使用,以下是配置 (注解方式的“處理器映射器”/"處理器適配器") --> <!-- 配置“處理器映射器” --> <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/> <!-- 配置“處理器適配器” --> <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"> <!-- 在“處理器適配器”中配置JSON轉(zhuǎn)換器(來完成JSON數(shù)據(jù)的轉(zhuǎn)換) --> <property name="messageConverters"> <list> <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/> </list> </property> </bean>
從上述配置代碼可以看出,使用 <bean>標(biāo)簽 配置方式 配置JSON轉(zhuǎn)換器 時(shí),需要同時(shí)配置 處理器映射器 和 處理器適配器,并且 JSON轉(zhuǎn)換器 是 在配置在適配器中。
1.4 配置靜態(tài)資源訪問的方式 (對(duì)靜態(tài)資源放行) (有三種方式)
除了使用 <mvc:resources mapping=" " location=" "/>元素 ( 這種方式最常用 )可以實(shí)現(xiàn) 對(duì)靜態(tài)資源的訪問
( 對(duì)靜態(tài)資源放行,不攔截靜態(tài)資源,還有另外 兩種可以實(shí)現(xiàn) “靜態(tài)資源訪問” 的方式 :①使用<mvc:default-servlet-handler>標(biāo)簽
②使用激活Tomcat默認(rèn)的Servlet來處理靜態(tài)文件訪問。
(第一種方式開發(fā)中最常用,即上面的例子中的“資源放行”的方式)
ps :
第一種 : 對(duì) 靜態(tài)資源放行的方式 :<mvc:resources mapping=" " location=" "/>元素
—該方式開發(fā)中最常用。
<mvc:default-servlet-handler>標(biāo)簽 (對(duì)靜態(tài)資源放行)
使用 <mvc:default-servlet-handler>標(biāo)簽 實(shí)現(xiàn)對(duì)“靜態(tài)資源“放行 , springmvc-config.xml 的 配置方式 如下 :
<!-- 實(shí)現(xiàn)對(duì)“靜態(tài)資源”的訪問外 / 放行靜態(tài)資源,讓前端能直接訪問“靜態(tài)資源” --> <mvc:default-servlet-handler/>
在springmve-config.xml中配置 <mvc:default-servlet-handler> 后,會(huì)在 Spring MVC 上下文中定義一個(gè)org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler (即默認(rèn)的Servlet請(qǐng)求處理器)。它會(huì)像一個(gè)檢查員,對(duì)進(jìn)入DispatcherServlet的URL進(jìn)行篩查。如果發(fā)現(xiàn)是 靜態(tài)資源 的 請(qǐng)求,就將該請(qǐng)求轉(zhuǎn)由Web服務(wù)器默認(rèn)的Servlet 處理,默認(rèn)的Servlet就會(huì)對(duì)這些靜態(tài)資源放行;如果不是靜態(tài)資源的請(qǐng)求,才由DispatcherServlet繼續(xù)處理。
注意點(diǎn):
一般 Web服務(wù)器默認(rèn)的Servlet名稱是"default",因此DefaultServletHttpRequestHandler 可以找到它。如果使用的Web應(yīng)用服務(wù)器默認(rèn)的Servlet名稱不是"default",則需要通過default-servlet-name屬性顯示指定,具體方式如下 :
<mvc:default-servlet-handler default-servlet-name="Servlet名稱"/>
而 Web服務(wù)器的Servlet名稱 是由使用的服務(wù)器確定的,常用服務(wù)器及其Servlet名稱如下 :
①Tomcat、 Jetty、 JBoss和 and GlassFish 默認(rèn)Servlet的名稱 :default。
②Google App Engine默認(rèn)Servlet的名稱: _ah_default 。
③Resin默認(rèn)Servlet的名稱 :resin-file 。
④WebLogic默認(rèn)Servlet的名稱 : FileServlet。
⑤WebSphere默認(rèn)Servlet的名稱 : SimpleFileServlet。
使用激活Tomcat默認(rèn)的Servlet (對(duì)靜態(tài)資源放行)
使用 激活Tomcat默認(rèn) 的 Servlet 來處理 靜態(tài)文件訪問,激活Tomcat默認(rèn)的Servlet時(shí),需要在web.xml中添加以下內(nèi)容 :
<!-- 激活Tomcat默認(rèn)的Servlet來處理靜態(tài)文件訪問 (來對(duì)靜態(tài)資源放行) --> <!-- 激活Tomcat的靜態(tài)資源攔截,需要哪些“靜態(tài)資源”,再往下追加 --> <servlet-mapping> <servlet-name>default</servlet-name> <url-pattern>*.js</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>default</servlet-name> <url-pattern>*.css</url-pattern> </servlet-mapping> ...
在上述代碼中,配置了 <servlet-mapping>元素來激活Tomcat 默認(rèn)的Servlet 來處理靜態(tài)文件,我們還可以根據(jù)需要繼續(xù)追加<servlet-mapping>。此種配置方式和上一種方式本質(zhì)上是一樣的,都是使用Web服務(wù)器默認(rèn)的Servlet來處理靜態(tài)資源文件的訪問。其中 Servelt名稱 (即 <servlet-name>元素的值)也是 由使用的服務(wù)器來確定 的,不同的服務(wù)器需要使用不同的名稱。
- 以上3種靜態(tài)資源訪問的配置方式不同,并且各有優(yōu)缺點(diǎn),具體如下 :
第一種和第三種配置方式 可以 選擇性的釋放靜態(tài)資源。
第二種 配置方式 配置相對(duì)簡(jiǎn)單,只需要一行代碼,就 可以釋放所有靜態(tài)資源。
第二 和 第三種配置方式 會(huì) 導(dǎo)致項(xiàng)目移植性較差,需要根據(jù) 具體的Web服務(wù)器來更改Servlet名稱。
第三種配置方式 運(yùn)行 效率更高,因?yàn)?strong>服務(wù)器啟動(dòng)時(shí)已經(jīng)加載了web.xml中的靜態(tài)資源。- 在實(shí)際開發(fā) 中,更為 常用的配置 還是 第一種(即案例中的)配置方式,這樣就不需要考慮Web服務(wù)器的問題了。
二、RESTful支持
Spring MVC 除了支持JSON數(shù)據(jù)交互外,還支持RESTful風(fēng)格的編程。
2.1 RESTful設(shè)計(jì)風(fēng)格
- RESTful 也稱之為REST ( Representational State Transfer : 表述性狀態(tài)轉(zhuǎn)移) ,可以將它理解為一種 軟件架構(gòu)風(fēng)格 或 設(shè)計(jì)風(fēng)格,而 不是一個(gè)標(biāo)準(zhǔn) ( RESTFUL是一種軟件架構(gòu)/設(shè)計(jì)風(fēng)格 )。
★★★★★
簡(jiǎn)單來說,RESTful風(fēng)格 的重要特征之一 :把請(qǐng)求參數(shù)變成請(qǐng)求路徑。( 意思就是說 : 當(dāng)你的 “URL中的參數(shù)” 成為了請(qǐng)求路徑的一部分時(shí),說明時(shí)候你使用的就是RESTful風(fēng)格在進(jìn)行編程 )。
★★★★★例如,傳統(tǒng)風(fēng)格 的帶參數(shù)的 URL請(qǐng)求 格式為:
//傳統(tǒng)風(fēng)格的帶參數(shù)的URL請(qǐng)求以下格式,請(qǐng)求參數(shù)一般是“不作為”URL路徑中的一部分的,但RESTful風(fēng)格中的請(qǐng)求參數(shù)一般是“作為”URL路徑中的一部分。 http://.../queryItems?id=1
而采用 RESTful風(fēng)格后,其URL請(qǐng)求為 :
(傳統(tǒng)風(fēng)格請(qǐng)求參數(shù)不是請(qǐng)求路徑的一部分,而用RESTful風(fēng)格中請(qǐng)求參數(shù)是請(qǐng)求路徑中的一部分)//此風(fēng)格為RESTful風(fēng)格,請(qǐng)求參數(shù)1作為了URL路徑中的一部分,后端通過{xxx} 和 @PathVariable()注解來獲取該請(qǐng)求參數(shù) http://.../items/1 /** * 后端接收前端通過RESTful風(fēng)格傳遞來的參數(shù) */ @RequestMapping(value = "/user/{id}",method = RequestMethod.GET) //通過 {xxx} 和 @PathVariable()注解來獲得URL路徑上的參數(shù) public User selectUserByRestful(@PathVariable("id") String id) { ..... }
從上述兩個(gè)請(qǐng)求中可以看出,RESTful風(fēng)格 中的 URL將請(qǐng)求參數(shù)id=1變成了請(qǐng)求路徑的一部分,并且URL中的querytems也變成了items ( RESTful風(fēng)格中的URL不存在動(dòng)詞形式的路徑,如queryltems表示查詢訂單,是一個(gè)動(dòng)詞,而 items表示訂單,為名詞)。
RESTful風(fēng)格在HTTP請(qǐng)求中,使用put、delete、 post 和get方式分別對(duì)應(yīng)添加、刪除、修改和查詢的操作。不過目前國(guó)內(nèi)開發(fā),(更多) 還是只使用post和get方式來進(jìn)行增刪改查操作。
例子如 : (用戶信息查詢) :
本案例將采用 RESTful風(fēng)格的請(qǐng)求實(shí)現(xiàn)對(duì)用戶信息的查詢,同時(shí) 返回JSON格式 的 數(shù)據(jù) :
restful.jsp :
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>RESTful測(cè)試</title> <script type="text/javascript" src="${pageContext.request.contextPath}/js/jquery-3.7.1.js"></script> <script type="text/javascript"> function search() { //獲取輸入的查詢編號(hào) var id = $("#number").val(); $.ajax({ //該url中傳遞的參數(shù)不直接接在url后面,后端則通過@PathVirable()注解來獲得該參數(shù) url: "${pageContext.request.contextPath}/user/" + id, type:"GET", //定義回調(diào)響應(yīng)的數(shù)據(jù)格式為JSON字符串 dataType:"json", //后端響應(yīng)的類型是 :josn //回調(diào)函數(shù) success : function (data) { if (data.username != null) { alert("你查詢的用戶是: " + data.username); } else { alert("沒有找到id為:" + id + "的用戶!"); } } }); } </script> </head> <body> <form> 編號(hào): <input type="text" name="number" id="number"> <input type="button" value="搜索" onclick="search()"> </form> </body> </html>
UserController.java :
package com.myh.controller; import com.myh.po.User; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*; @Controller //把該類標(biāo)記為“處理器類”,用于鏈接DispatcherServlet,讓該類中的方法能被前端訪問 public class UserController { /** * 前端通過RESTful風(fēng)格來進(jìn)行參數(shù)的傳遞 * (接收RESTful風(fēng)格的請(qǐng)求,其接收方式為GET) * * RESTful風(fēng)格 的體現(xiàn)之一: “請(qǐng)求參數(shù)”作為了URL中的“一部分” */ @ResponseBody //該注解的作用: 將“返回值”自動(dòng)轉(zhuǎn)換為“指定格式的數(shù)據(jù)”,響應(yīng)給前端。(返回對(duì)象類型時(shí),會(huì)將對(duì)象轉(zhuǎn)換為JSON格式字符串來響應(yīng)給前端) @RequestMapping(value = "/user/{id}",method = RequestMethod.GET) //通過 {xxx} 和 @PathVariable()注解來獲得URL路徑上的參數(shù) public User selectUserByRestful(@PathVariable("id") String id) { System.out.println(id); User user = new User(); //模擬根據(jù)id查詢出用戶對(duì)象數(shù)據(jù) if (id.equals("1234")) { user.setUsername("zhangsan"); } //返回JSON格式的數(shù)據(jù) return user; } }
在上述代碼中,value = "/user/{id}"表示可以匹配 以/user/{id}結(jié)尾的請(qǐng)求,id為請(qǐng)求中的動(dòng)態(tài)參數(shù) (前端可用RESTful風(fēng)格來設(shè)置該動(dòng)態(tài)參數(shù))。method=RequestMethod.GET表示只接收GET方式的請(qǐng)求。 方法中的 @PathVariable("id”)注解 則用于接收并綁定請(qǐng)求參數(shù),它可以 將請(qǐng)求URL 中的 變量映射
到 方法的形參 上,如果請(qǐng)求路徑為“user/{id}",即 請(qǐng)求參數(shù)中的 id 和方法形參名稱id 一樣,則
@PathVariable后面的“(“id”)” 可以省略。
文章來源:http://www.zghlxwxcb.cn/news/detail-847074.html
文章來源地址http://www.zghlxwxcb.cn/news/detail-847074.html
到了這里,關(guān)于SpringMVC | SpringMVC中的 “JSON數(shù)據(jù)交互“ 和 “RESTful設(shè)計(jì)風(fēng)格“的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!