Spring Boot企業(yè)級(jí)開發(fā)入門與實(shí)踐 課件 第5、6章 Spring Boot安全管理、SpringBoot消息服務(wù)_第1頁
Spring Boot企業(yè)級(jí)開發(fā)入門與實(shí)踐 課件 第5、6章 Spring Boot安全管理、SpringBoot消息服務(wù)_第2頁
Spring Boot企業(yè)級(jí)開發(fā)入門與實(shí)踐 課件 第5、6章 Spring Boot安全管理、SpringBoot消息服務(wù)_第3頁
Spring Boot企業(yè)級(jí)開發(fā)入門與實(shí)踐 課件 第5、6章 Spring Boot安全管理、SpringBoot消息服務(wù)_第4頁
Spring Boot企業(yè)級(jí)開發(fā)入門與實(shí)踐 課件 第5、6章 Spring Boot安全管理、SpringBoot消息服務(wù)_第5頁
已閱讀5頁,還剩85頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

第5章SpringBoot安全管理本章內(nèi)容:1.了解SpringSecurity的核心類2.掌握自定義用戶認(rèn)證3.掌握自定義用戶授權(quán)管理engineeringSoftware5.1SpringSecurity介紹SpringSecurity應(yīng)用級(jí)別的安全主要包含兩個(gè)主要部分,即登錄認(rèn)證(Authentication)和訪問授權(quán)(Authorization),首先用戶登錄的時(shí)候傳入登錄信息,登錄驗(yàn)證器完成登錄認(rèn)證并將登錄認(rèn)證好的信息存儲(chǔ)到請(qǐng)求上下文,然后在進(jìn)行其他操作,如接口訪問、方法調(diào)用時(shí),權(quán)限認(rèn)證器從上下文中獲取登錄認(rèn)證信息,然后根據(jù)認(rèn)證信息獲取權(quán)限信息,通過權(quán)限信息和特定的授權(quán)策略決定是否授權(quán)。engineeringSoftware簡單來說,SpringSecurity核心功能只做以下幾件事情:1)系統(tǒng)初始化時(shí),告訴SpringSecurity訪問路徑所需要的對(duì)應(yīng)權(quán)限。2)登錄時(shí),告訴SpringSecurity真實(shí)用戶名和密碼。3)登錄成功時(shí),告訴SpringSecurity當(dāng)前用戶具備的權(quán)限。用戶訪問接口時(shí),SpringSecurity已經(jīng)知道用戶具備的權(quán)限,也知道訪問路徑需要的對(duì)應(yīng)權(quán)限,所以自動(dòng)判斷能否訪問。5.1SpringSecurity介紹

engineeringSoftwareSpringSecurity的核心類有如下幾個(gè):1.SecurityContext

SecurityContext中包含當(dāng)前正在訪問系統(tǒng)的用戶的詳細(xì)信息,SecurityContext的信息是由SecurityContextHolder來處理的。2.SecurityContextHolder

最基本的對(duì)象,保存著當(dāng)前會(huì)話用戶認(rèn)證,權(quán)限,鑒權(quán)等核心數(shù)據(jù)。SecurityContextHolder默認(rèn)使用ThreadLocal策略來存儲(chǔ)認(rèn)證信息,與線程綁定的策略。用戶退出時(shí),自動(dòng)清除當(dāng)前線程的認(rèn)證信息。

最常用的是通過getContext()方法,用來獲得當(dāng)前的SecurityContext。5.1SpringSecurity介紹engineeringSoftware3.PrividerManager會(huì)維護(hù)一個(gè)認(rèn)證列表,來處理不同認(rèn)證方式的認(rèn)證,因?yàn)橄到y(tǒng)可能會(huì)存在多種認(rèn)證方式。比如手機(jī)號(hào)、用戶名密碼、郵箱。如果認(rèn)證結(jié)果不是null,說明成功,存在SecurityContext中。如果不成功,拋出ProviderNotFoundException異常。4.DaoAuthenticationProvider它是AuthenticationProvider最常用的實(shí)現(xiàn),用來獲取用戶提交的用戶名和密碼,并進(jìn)行正確性比對(duì)。如果正確,則返回?cái)?shù)據(jù)庫中的用戶信息。5.1SpringSecurity介紹engineeringSoftware5.UserDetails它是SpringSecurity的用戶實(shí)體類,包含用戶名、密碼、權(quán)限等信息。SpringSecurity默認(rèn)實(shí)現(xiàn)了內(nèi)置的User類,供SpringSecurity安全認(rèn)證使用。也可以自己實(shí)現(xiàn)。UserDetails接口和Authentication接口很類似,都擁有username和authorites。一定要區(qū)分清楚Authentication的getCredentials()與UserDetatils中的getPassword()。前者是用戶提交的密碼憑證,不一定正確,或者數(shù)據(jù)庫不一定存在。后者是用戶正確地密碼,認(rèn)證器要進(jìn)行比對(duì)的就是兩者是否相同。5.1SpringSecurity介紹engineeringSoftware6.UserDetailsService用戶信息通過UserDetailsService接口來加載。該接口的唯一方法是loadUserByUsername(Stringusername),用來根據(jù)用戶名加載相關(guān)信息。這個(gè)方法返回值是UserDetatils接口,其中包含了用戶的信息,包括用戶名、密碼、權(quán)限、是否啟用等。7.Authentication建立系統(tǒng)使用者信息(Principal)的過程。用戶認(rèn)證一般要求用戶提供用戶名和密碼,系統(tǒng)通過用戶名密碼來完成認(rèn)證通過或者拒絕。SpringSecurity支持主流認(rèn)證方式,包括HTTP基本認(rèn)證、表單驗(yàn)證、摘要認(rèn)證、OpenID和LDAP等。5.1SpringSecurity介紹engineeringSoftware8.授權(quán)(authorization)在一個(gè)系統(tǒng)中,不同用戶具有權(quán)限是不同的。系統(tǒng)會(huì)為不同的用戶分配不同的角色,而每個(gè)角色則對(duì)應(yīng)一系列的權(quán)限。對(duì)Web資源的保護(hù),最好的辦法是使用過濾器。對(duì)方法調(diào)用的保護(hù),最好的方法是使用AOP。5.1SpringSecurity介紹engineeringSoftwareSpringBoot針對(duì)SpringSecurity提供了自動(dòng)化配置方案,因此可以使SpringSecurity非常容易地整合進(jìn)SpringBoot項(xiàng)目中,這也是在SpringBoot項(xiàng)目中使用SpringSecurity的優(yōu)勢。在maven中添加依賴以便啟用安全管理。<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId></dependency>5.2安全管理效果測試engineeringSoftware需要說明的是,在SpringBoot項(xiàng)目中加入安全依賴啟動(dòng)器后,Security會(huì)默認(rèn)提供一個(gè)可登錄的用戶信息,其中用戶名為user,密碼隨機(jī)生成,這個(gè)密碼會(huì)隨著項(xiàng)目的每次啟動(dòng)隨機(jī)生成并打印在控制臺(tái)上。

如果開發(fā)者對(duì)默認(rèn)的用戶名和密碼不滿意,可以在perties中配置默認(rèn)的用戶名、密碼以及用戶角色,配置方式如下:=zhangsanspring.security.user.password=123456spring.security.user.roles=admin5.2安全管理效果測試engineeringSoftware通過自定義WebSecurityConfigurerAdapter類型的Bean組件,可以完全關(guān)閉Security提供的Web應(yīng)用默認(rèn)安全配置,但是不會(huì)關(guān)閉UserDetailsService用戶信息自動(dòng)配置類。如果要關(guān)閉UserDetailsService默認(rèn)用戶信息配置,可以自定義UserDetailsService、AuthenticationProvider或AuthenticationManager類型的Bean組件。另外,可以通過自定義WebSecurityConfigurerAdapter類型的Bean組件覆蓋默認(rèn)訪問規(guī)則。SpringBoot提供了非常多方便的方法,可用于覆蓋請(qǐng)求映射和靜態(tài)資源的訪問規(guī)則。5.3自定義用戶認(rèn)證engineeringSoftwarein-MemoryAuthentication(內(nèi)存身份認(rèn)證)是最簡單的身份認(rèn)證方式,主要用于Security安全認(rèn)證體驗(yàn)和測試。自定義內(nèi)存身份認(rèn)證時(shí),只需要在重寫的configure(AuthenticationManagerBuilderauth)方法中定義測試用戶即可。5.3.1內(nèi)存身份認(rèn)證engineeringSoftwareJDBCAuthentication(JDBC身份認(rèn)證)是通過JDBC連接數(shù)據(jù)庫對(duì)已有用戶身份進(jìn)行認(rèn)證。下面通過SpringBoot整合SpringSecurity實(shí)現(xiàn)JDBC身份認(rèn)證。5.3.2JDBC身份認(rèn)證engineeringSoftwareSpringSecurity中進(jìn)行身份驗(yàn)證的是AuthenticationManager接口,ProviderManager是它的一個(gè)默認(rèn)實(shí)現(xiàn),但它并不用來處理身份認(rèn)證,而是委托給配置好的AuthenticationProvider,每個(gè)AuthenticationProvider會(huì)輪流檢查身份認(rèn)證。檢查后或者返回Authentication對(duì)象或者拋出異常。驗(yàn)證身份就是加載響應(yīng)的UserDetails,看看是否和用戶輸入的賬號(hào)、密碼、權(quán)限等信息匹配。此步驟由實(shí)現(xiàn)AuthenticationProvider的DaoAuthenticationProvider(它利用UserDetailsService驗(yàn)證用戶名、密碼和授權(quán))處理。包含GrantedAuthority的UserDetails對(duì)象在構(gòu)建Authentication對(duì)象時(shí)填入數(shù)據(jù)。5.3.3UserDetailsService身份認(rèn)證engineeringSoftwareUserDetailsService接口只有一個(gè)方法,這個(gè)方法返回值UserDetails,UserDetails這個(gè)類是系統(tǒng)默認(rèn)的用戶“主體"。登錄的時(shí)候是會(huì)訪問這個(gè)方法的,并且會(huì)將登錄傳入的用戶名以參數(shù)形式傳過來。我們需要做的就是實(shí)現(xiàn)UserDetailsService接口,然后重寫這個(gè)方法,并返回一個(gè)UserDetails對(duì)象。在這個(gè)方法我們一般有如下步驟:第1步:根據(jù)登錄用戶名查詢數(shù)據(jù)庫判斷該用戶是否存在。第2步:將從數(shù)據(jù)庫查出來的賬號(hào)密碼封裝到UserDetails對(duì)象當(dāng)中,作為方法返回值返回。5.3.3UserDetailsService身份認(rèn)證engineeringSoftware我們不能只依賴前端去判斷用戶的權(quán)限來選擇顯示哪些菜單哪些按鈕。因?yàn)槿绻皇沁@樣,如果有人知道了對(duì)應(yīng)功能的接口地址就可以不通過前端,直接去發(fā)送請(qǐng)求來實(shí)現(xiàn)相關(guān)功能操作。所以我們還需要在后臺(tái)進(jìn)行用戶權(quán)限的判斷,判斷當(dāng)前用戶是否有相應(yīng)的權(quán)限,必須具有所需權(quán)限才能進(jìn)行相應(yīng)的操作。5.4自定義用戶授權(quán)管理engineeringSoftware實(shí)際生產(chǎn)中,網(wǎng)站訪問多是基于HTTP請(qǐng)求的,我們已經(jīng)分析出通過重寫WebSecurityConfigurerAdapter類的config(HttpSecurityhttp)方法可以對(duì)基于Http的請(qǐng)求訪問進(jìn)行控制。下面我們通過對(duì)configure(HttpSecurityhttp)方法剖析,分析自定義用戶訪問控制的實(shí)現(xiàn)過程。configure(HttpSecurityhttp)方法的參數(shù)類型是HttpSecurity類,HttpSecurity類提供了Http請(qǐng)求的限制以及權(quán)限、Session管理配置、CSRF跨站請(qǐng)求問題等方法。5.4.1授權(quán)基本流程engineeringSoftware實(shí)際生產(chǎn)中,網(wǎng)站訪問多是基于HTTP請(qǐng)求的,我們已經(jīng)分析出通過重寫WebSecurityConfigurerAdapter類的config(HttpSecurityhttp)方法可以對(duì)基于Http的請(qǐng)求訪問進(jìn)行控制。下面我們通過對(duì)configure(HttpSecurityhttp)方法剖析,分析自定義用戶訪問控制的實(shí)現(xiàn)過程。configure(HttpSecurityhttp)方法的參數(shù)類型是HttpSecurity類,HttpSecurity類提供了Http請(qǐng)求的限制以及權(quán)限、Session管理配置、CSRF跨站請(qǐng)求問題等方法。5.4.1授權(quán)基本流程engineeringSoftware(4)默認(rèn)值有的時(shí)候,我們?nèi)∫粋€(gè)值可能為空,這個(gè)時(shí)候需要做非空判斷,可以使用表達(dá)式“?:默認(rèn)值”簡寫。<spanth:text="'你的年齡是'+(${user.age}?:20)"></span>當(dāng)前面的表達(dá)式值為null時(shí),就會(huì)使用后面的默認(rèn)值。注意:

?:

之間沒有空格。3.3.6運(yùn)算

engineeringSoftware假如有用戶的java.util.List集合:users在Context中。<trth:each="user:${users}"><tdth:text="${}"></td><tdth:text="${user.age}"></td><tdth:text="${user.sex}"></td></tr>3.3.7循環(huán)

engineeringSoftwarejava.util.List類型不是可以在Thymeleaf中使?迭代的唯?值類型,下面這些類型的對(duì)象都可以通過th:each進(jìn)?迭代的:(1)任何實(shí)現(xiàn)java.util.Iterable接?的對(duì)象,其值將被迭代器返回,?不需要在內(nèi)存中緩存所有值。(2)任何實(shí)現(xiàn)java.util.Enumeration接?的對(duì)象。(3)任何實(shí)現(xiàn)java.util.Map接?的對(duì)象,迭代映射時(shí),iter變量將是java.util.Map.Entry類。(4)任何數(shù)組。(5)任何其將被視為包含對(duì)象本身的單值列表。3.3.7循環(huán)

engineeringSoftware迭代過程中,經(jīng)常會(huì)使用到它的一些迭代狀態(tài),如:當(dāng)前迭代的索引,迭代變量中的元素的總數(shù),當(dāng)前迭代的是奇數(shù)還是偶數(shù),當(dāng)前是否是第一個(gè)元素,當(dāng)前是否是最后一個(gè)元素等等。狀態(tài)變量在每個(gè)th:each屬性中定義,并包含以下數(shù)據(jù):(1)index屬性:當(dāng)前迭代索引,從0開始(2)count屬性:當(dāng)前的迭代計(jì)數(shù),從1開始(3)size屬性:迭代變量中元素的總量(4)current屬性:每次迭代的iter變量,即當(dāng)前遍歷到的元素(5)even/odd布爾屬性:當(dāng)前的迭代是偶數(shù)還是奇數(shù)。(6)first布爾屬性:當(dāng)前的迭代是否是第?個(gè)迭代(7)last布爾屬性:當(dāng)前的迭代是否是最后?個(gè)迭代。3.3.7循環(huán)

engineeringSoftware很多時(shí)候只有在滿足某個(gè)條件時(shí),才將?個(gè)模板片段顯示在結(jié)果中,否則不進(jìn)行顯示。比如只有當(dāng)用戶年齡小于18歲時(shí),才為他為未成年人,否則不顯示。th:if屬性用于滿足這個(gè)需求。<spanth:if="${age}<18">未成年</span>3.3.8邏輯判斷

engineeringSoftwareth:if屬性不僅只以布爾值作為判斷條件,它將按照如下規(guī)則判定指定的表達(dá)式結(jié)果為true:(1)如果表達(dá)式結(jié)果為布爾值,則為true或者false(2)如果表達(dá)式的值為null,th:if將判定此表達(dá)式為false(3)如果值是數(shù)字為0時(shí),判斷為false;不為零時(shí),判定為true(4)如果value是String,值為“false”、“off”、“no”時(shí),判定為false,否則判斷為true,字符串為空時(shí),也判斷為true(5)如果值不是布爾值、數(shù)字、字符或字符串的其它對(duì)象,只要不為null,則判斷為trueth:unless是th:if的反向?qū)傩?,它們判斷的?guī)則一致,只是if當(dāng)結(jié)果為true時(shí)進(jìn)行顯示,unless當(dāng)結(jié)果為false進(jìn)行顯示。3.3.8邏輯判斷

engineeringSoftwareth:switch/th:case與Java中的switch語句等效,有條件地顯示匹配的內(nèi)容。只要其中一個(gè)th:case的值為true,則同一個(gè)switch語句中的其他th:case屬性都將被視為false。當(dāng)有多個(gè)case的值為true時(shí),則只取第一個(gè)。

switch語句的default選項(xiàng)指定為th:case=“*”,即當(dāng)沒有case的值為true時(shí),將顯示default的內(nèi)容,如果有多個(gè)default,則只取第一個(gè)。3.3.9分支控制switch

engineeringSoftware

系統(tǒng)中的很多頁面有很多公共內(nèi)容,例如菜單、頁腳等,這些公共內(nèi)容可以提取放在一個(gè)稱為“模板片斷”的公共頁面里面,其它頁面可以引用這個(gè)。

模板片斷可以是html標(biāo)簽,也可以使用th:fragment屬性定義片斷。

接下來就可以在Web頁面中使用th:insert、th:replace、th:include屬性來包含頁腳片段,其中這三個(gè)有些區(qū)別。

1.th:insert:當(dāng)前標(biāo)簽里面插入模板中的標(biāo)簽

2.th:replace:替換當(dāng)前標(biāo)簽為模板中的標(biāo)簽

3.th:include:在標(biāo)簽里面插入模板的標(biāo)簽內(nèi)容3.3.10Thymeleaf模板片斷

engineeringSoftware

創(chuàng)建項(xiàng)目,選擇相應(yīng)依賴3.4實(shí)現(xiàn)基于Thymeleaf的Web應(yīng)用

engineeringSoftware項(xiàng)目創(chuàng)建成功之后,在pom.xml文件中就添加了Thymeleaf依賴,代碼如下。<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency>什么是國際化?例如我們的,進(jìn)入是一個(gè)默認(rèn)英文的網(wǎng)站,右上角有個(gè)中字,點(diǎn)一下就會(huì)幫我們切換成中文網(wǎng)站,這就是國際化。在SpringBoot的Web應(yīng)用中實(shí)現(xiàn)頁面信息國際化非常簡單,下面通過實(shí)例講解國際化的實(shí)現(xiàn)過程。3.5SpringBoot中的頁面國際化實(shí)現(xiàn)

engineeringSoftwareSpringBoot確實(shí)為我們做了很多事情,但有時(shí)候我們想要自己定義一些Handler,Interceptor,ViewResolver,該怎么做呢。SpringBoot2.0后,該類被標(biāo)記為@Deprecated。因此我們只能靠實(shí)現(xiàn)WebMvcConfigurer接口來實(shí)現(xiàn)。WebMvcConfigurer是一個(gè)接口,提供很多自定義的攔截器,例如跨域設(shè)置、類型轉(zhuǎn)化器等等??梢哉f此接口為開發(fā)者提前想到了很多攔截層面的需求,方便開發(fā)者自由選擇使用。SpringBoot推薦使用實(shí)現(xiàn)WebMvcConfigurer接口的實(shí)現(xiàn)類來實(shí)現(xiàn)代碼配置,代碼如下。@ConfigurationpublicclassMyConfigurerimplementsWebMvcConfigurer{}3.6SpringBoot集成SpringMVC

engineeringSoftwareSpringBoot確實(shí)為我們做了很多事情,但有時(shí)候我們想要自己定義一些Handler,Interceptor,ViewResolver,該怎么做呢。SpringBoot2.0后,該類被標(biāo)記為@Deprecated。因此我們只能靠實(shí)現(xiàn)WebMvcConfigurer接口來實(shí)現(xiàn)。WebMvcConfigurer是一個(gè)接口,提供很多自定義的攔截器,例如跨域設(shè)置、類型轉(zhuǎn)化器等等。可以說此接口為開發(fā)者提前想到了很多攔截層面的需求,方便開發(fā)者自由選擇使用。SpringBoot推薦使用實(shí)現(xiàn)WebMvcConfigurer接口的實(shí)現(xiàn)類來實(shí)現(xiàn)代碼配置,代碼如下。@ConfigurationpublicclassMyConfigurerimplementsWebMvcConfigurer{}3.6.1配置自定義攔截器Interceptor

engineeringSoftware以前寫SpringMVC的時(shí)候,如果需要訪問一個(gè)頁面,必須要寫Controller類,然后再寫一個(gè)方法跳轉(zhuǎn)到頁面,感覺好麻煩,如上面“/index”,其實(shí)可以重寫WebMvcConfigurer中的addViewControllers方法即可達(dá)到效果了。

addViewControllers方法可以實(shí)現(xiàn)將一個(gè)無業(yè)務(wù)邏輯的請(qǐng)求直接映射為視圖,不需要編寫控制器來實(shí)現(xiàn),從而簡化了頁面跳轉(zhuǎn)。

修改上面的MyConfigurer配置類,在其實(shí)現(xiàn)類中,重寫addViewControllers方法,3.6.2跳轉(zhuǎn)指定頁面

engineeringSoftware后臺(tái)的開發(fā)過程中不可避免的就是一系列對(duì)JSON數(shù)據(jù)的返回,需要我們進(jìn)行的就是提供各種各樣的數(shù)據(jù)。一般情況下數(shù)據(jù)類型最常用的就是JSON以及XML,在這里我們就講講在SpringBoot里面我們?cè)鯓舆M(jìn)行JSON數(shù)據(jù)的返回以及數(shù)據(jù)一些特殊情況的處理。JSON是目前主流的前后端數(shù)據(jù)傳輸方式,SpringMVC中使用消息轉(zhuǎn)化器HttpMessageConverter對(duì)JSON的轉(zhuǎn)換提供了很好的支持,在SpringBoot中對(duì)相關(guān)配置做了進(jìn)一步簡化。<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency>

3.7SpringBoot處理JSON數(shù)據(jù)

engineeringSoftwareSpringBoot處理JSON數(shù)據(jù)時(shí),需要用到兩個(gè)重要的JSON格式轉(zhuǎn)換注解,分別是@RequestBody和@ResponseBody。@ResponseBody注解的作用是將controller的方法返回的對(duì)象通過適當(dāng)?shù)霓D(zhuǎn)換器轉(zhuǎn)換為指定的格式之后,寫入到response對(duì)象的body區(qū),通常用來返回JSON數(shù)據(jù)或者是XML數(shù)據(jù)。@RequestBody是作用在形參列表上,用于將前臺(tái)發(fā)送過來固定格式的數(shù)據(jù)(xml格式或者JSON等)封裝為對(duì)應(yīng)的JavaBean對(duì)象,封裝時(shí)使用到的一個(gè)對(duì)象是系統(tǒng)默認(rèn)配置的HttpMessageConverter(消息轉(zhuǎn)換器)進(jìn)行解析,然后封裝到形參上。3.7SpringBoot處理JSON數(shù)據(jù)

engineeringSoftwareRESTful架構(gòu)風(fēng)格是目前最流行的一種架構(gòu)風(fēng)格,它機(jī)構(gòu)清晰、符合標(biāo)準(zhǔn)、易于理解、擴(kuò)展方便,所以在Web開發(fā)中經(jīng)常被使用。REST,全稱是RepresentationalStateTransfer,譯作“表現(xiàn)層狀態(tài)轉(zhuǎn)化”。RESTful架構(gòu)是對(duì)MVC架構(gòu)改進(jìn)后所形成的一種架構(gòu),通過使用事先定義好的接口與不同的服務(wù)聯(lián)系起來。在RESTful架構(gòu)中,瀏覽器使用POST,DELETE,PUT和GET四種請(qǐng)求方式分別對(duì)指定的URL資源進(jìn)行增刪改查操作。因此,RESTful是通過URI實(shí)現(xiàn)對(duì)資源的管理及訪問,具有擴(kuò)展性強(qiáng)、結(jié)構(gòu)清晰的特點(diǎn)。

3.8SpringBoot實(shí)現(xiàn)RESTful風(fēng)格Web應(yīng)用

engineeringSoftwareRESTful架構(gòu)將服務(wù)器分成前端服務(wù)器和后端服務(wù)器兩部分,前端服務(wù)器為用戶提供無模型的視圖;后端服務(wù)器為前端服務(wù)器提供接口。瀏覽器向前端服務(wù)器請(qǐng)求視圖,通過視圖中包含的AJAX函數(shù)發(fā)起接口請(qǐng)求獲取模型。

Restful是一種對(duì)URL進(jìn)行規(guī)范的編碼風(fēng)格,通常一個(gè)網(wǎng)址對(duì)應(yīng)一個(gè)資源,訪問形式類似/xx/{id}/{id}。

舉個(gè)例子,當(dāng)我們?cè)谀迟徫锞W(wǎng)站上買手機(jī)時(shí)會(huì)有很多品牌選擇,而每種品牌下又有很多型號(hào),那么/mobile/iphone/6代表了Iphone6,/mobile/iphone/7和/mobile/iphone/8分別代表了Iphone7和Iphone8。3.8SpringBoot實(shí)現(xiàn)RESTful風(fēng)格Web應(yīng)用

engineeringSoftware在做Web開發(fā)的過程中,method常用的值是get和post??墒聦?shí)上,method值還可以是put和delete等等其他值。

既然method值如此豐富,那么就可以考慮使用同一個(gè)url,但是約定不同的method來實(shí)施不同的業(yè)務(wù),這就是Restful的基本考慮。

CRUD是最常見的操作,在使用Restful風(fēng)格之前,通常的增加做法是這樣的:/addCategory?name=xxx可是使用了Restful風(fēng)格之后,增加就變成了:/categories3.8SpringBoot實(shí)現(xiàn)RESTful風(fēng)格Web應(yīng)用

engineeringSoftware

3.8SpringBoot實(shí)現(xiàn)RESTful風(fēng)格Web應(yīng)用

engineeringSoftware功能傳統(tǒng)風(fēng)格Restful風(fēng)格

urlmethodurlmethod增加/addCategory?name=xxxPOST/categoriesPOST刪除/deleteCategory?id=123GET/categories/123DELETE修改/updateCategory?id=123&name=yyyPOST/categories/123PUT獲取/getCategory?id=123GET/categories/123GET查詢/listCategoryGET/categoriesGET為了實(shí)現(xiàn)RESTfulAPI接口,SpringBoot提供了很多注解,對(duì)請(qǐng)求參數(shù)和返回?cái)?shù)據(jù)格式做了封裝,方便用戶快速開發(fā)。@RestController一般用于Controller類上,指定所有接口返回的數(shù)據(jù)都是text/json格式。@ResponseBody用于方法上,指定接口返回text/json格式,用了@RestController就沒有必要用ResponseBody。@GetMapping用于方法上,是一個(gè)組合注解,與@RequestMapping(method=RequestMethod.GET)作用一致。@PostMapping用于方法上,是一個(gè)組合注解,與@RequestMapping(method=RequestMethod.POST)作用一致。

3.8SpringBoot實(shí)現(xiàn)RESTful風(fēng)格Web應(yīng)用

engineeringSoftware@PutMapping用于方法上,是一個(gè)組合注解,與@RequestMapping(method=RequestMethod.PUT)作用一致。@DeleteMapping用于方法上,是一個(gè)組合注解,與@RequestMappmg(method=RequestMethod.DELETE)作用一致。@RequestParam用于方法上,映射請(qǐng)求參數(shù)到j(luò)ava方法的參數(shù),當(dāng)前端傳遞的參數(shù)和后臺(tái)自己定義的參數(shù)不一致時(shí),可以使用name屬性來標(biāo)記。@PathVariable用于方法上,映射URL片段到j(luò)ava方法的參數(shù)。3.8SpringBoot實(shí)現(xiàn)RESTful風(fēng)格Web應(yīng)用

engineeringSoftwareSpringBoot我們大多數(shù)的時(shí)候是當(dāng)做服務(wù)提供者來使用的,但是在一些場景中還是要用到一些文件上傳下載這種"非常規(guī)"操作的。那么怎么在SpringBoot中實(shí)現(xiàn)文件的上傳下載功能呢?想象一些我們?cè)赟pringMVC中是怎么做的。我們需要在SpringMVC的配置文件中增加文件上傳的Bean的配置,如下:<beanid="multipartResolver"class="mons.CommonsMultipartResolver"/>然后在后臺(tái)對(duì)應(yīng)的處理方法中就可以直接獲取到文件的輸入流了。而對(duì)于SpringBoot來說,我們不需要配置文件上傳的解析類了,因?yàn)镾pringBoot已經(jīng)幫我們注冊(cè)好了。3.9.1文件上傳

engineeringSoftwareJava中的文件上傳一共涉及兩個(gè)組件,一個(gè)是CommonsMultipartResolver,另一個(gè)是StandardServletMultipartResolver,其中CommonsMultipartResolver使用commons-fileupload來處理multipart請(qǐng)求,而StandardServletMultipartResolver則是基于Servlet3.0來處理multipart請(qǐng)求的,因此若使用StandardServletMultipartResolver,則不需要添加額外的Jar包。而在SpringBoot提供的文件上傳自動(dòng)化配置類MultipartAutoConfiguration中,默認(rèn)也是采用StandardServletMultipartResolver。因此,在SpringBoot中上傳文件甚至可以做到零配置。下面來看具體上傳過程。3.9.1文件上傳

engineeringSoftware在我們的SpringBoot項(xiàng)目中,可能會(huì)存在讓用戶下載文檔的需求,比如讓用戶下載readme文檔來更好地了解該項(xiàng)目的概況或使用方法。所以,就需要為用戶提供可以下載文件的API,將用戶希望獲取的文件作為下載資源返回給前端。下面來看具體完成文件下載過程。3.9.2文件下載

engineeringSoftware在Java中,程序出現(xiàn)錯(cuò)誤會(huì)拋出“不正常信息”(Throwable)。Throwable又被分為“錯(cuò)誤”(Error)和“異?!保‥xception)。有別于人為失誤造成的“故障”(Bug),異常在程序中代表的是出現(xiàn)了當(dāng)前代碼無法處理的狀況。例如:在一個(gè)對(duì)象不存在(值為Null)的情況下,調(diào)用該對(duì)象的某個(gè)方法引發(fā)了空指針;用戶輸入了一段URL,但并沒有找到對(duì)應(yīng)的資源;一段計(jì)算過程中,0被當(dāng)作除數(shù)等等情況。完善的錯(cuò)誤處理,使程序不會(huì)意外崩潰甚至能友好地提示用戶進(jìn)行正確操作,這是讓程序變得愈發(fā)健壯的重要處理步驟。在Java開發(fā)中,異常特別是檢查型異常(CheckedException),通常需要進(jìn)行try/catch處理。而在基于SpringBoot的開發(fā)過程中,異常處理有了更多處理方式。3.10SpringBoot的異常統(tǒng)一處理

engineeringSoftware使用Web應(yīng)用時(shí),在請(qǐng)求處理過程中發(fā)生錯(cuò)誤是非常常見的情況。SpringBoot為我們提供一個(gè)默認(rèn)的映射:/error,當(dāng)處理中拋出異常之后,會(huì)轉(zhuǎn)到該請(qǐng)求中處理,并且該請(qǐng)求有一個(gè)全局的錯(cuò)誤頁面來展示異常內(nèi)容。比如現(xiàn)在啟動(dòng)項(xiàng)目之后,在瀏覽器中隨便輸入一個(gè)訪問地址,由于地址不存在,SpringBoot會(huì)跳轉(zhuǎn)到錯(cuò)誤頁面。雖然SpringBoot為我們提供了默認(rèn)的錯(cuò)誤頁面映射,但是在實(shí)際應(yīng)用中,上圖所示的錯(cuò)誤頁面對(duì)用戶來說并不友好,我們需要自己來實(shí)現(xiàn)異常提示,接下來將演示自己實(shí)現(xiàn)錯(cuò)誤的提示頁面。3.10.1自定義error頁面

engineeringSoftware在SpringBoot中定制錯(cuò)誤頁面一共有三種方法,分別如下。1)將錯(cuò)誤頁面命名為“錯(cuò)誤狀態(tài)碼.html”放在模板引擎templates/error文件夾下,當(dāng)發(fā)生此狀態(tài)碼的錯(cuò)誤就會(huì)來到對(duì)應(yīng)的頁面。例如404.html,500.html。同時(shí)我們也可以使用模糊匹配的方式來定義錯(cuò)誤頁面的名稱,可以將錯(cuò)誤頁面命名為4xx.html和5xx.html,來匹配對(duì)應(yīng)類型的所有錯(cuò)誤。精確匹配的查找方式要優(yōu)先于模糊匹配的方式。2)如果templates/error目錄下沒有自定義的錯(cuò)誤頁面,那么需要在static/error目錄下定義4xx.html或5xx.html頁面。3)直接在templates目錄下創(chuàng)建error.html,這樣當(dāng)訪問錯(cuò)誤或異常時(shí),就自動(dòng)找到該頁面作為錯(cuò)誤頁面。3.10.1自定義error頁面

engineeringSoftware我們不難發(fā)現(xiàn)使用自定義error頁面并沒有真正處理異常,在本節(jié)我們可以@ExceptionHandler注解處理異常。該注解主要用于在Controller層面進(jìn)行相同類型的異常處理。在對(duì)應(yīng)Controller類中定義異常處理方法,并為其使用@ExcptionHandler注解。Spring將檢測到該注解,把該方法注冊(cè)為對(duì)應(yīng)異常類及其子類的異常處理程序。3.10.2@ExceptionHandler注解

engineeringSoftwareSpringMVC框架提供了另一種方式來為多個(gè)控制器類提供共同的方法:利用@ControllerAdvice注解來定義一個(gè)控制器增強(qiáng)類??刂破髟鰪?qiáng)類并不是控制器類的父類。在程序運(yùn)行時(shí),SpringMVC框架會(huì)把控制器增強(qiáng)類的方法代碼塊動(dòng)態(tài)注入到其他控制器類中,通過這種方式來增強(qiáng)控制器類的功能。3.10.3@ControllerAdvice注解

engineeringSoftware第6章SpringBoot消息服務(wù)本章內(nèi)容:1.掌握Thymeleaf模板引擎2.掌握SpringBoot處理JSON數(shù)據(jù)3.掌握SpringBoot處理國際化問題4.掌握SpringBoot文件的上傳和下載5.掌握SpringBoot的異常處理engineeringSoftware3.1創(chuàng)建靜態(tài)Web頁面

SpringBoot項(xiàng)目在不使用任何模板引擎的前提下,想要直接訪問html頁面,是如何做呢?我們只需要把靜態(tài)文件(html,js,css)放在resource的static文件夾里面就可以正常訪問了。下面通過實(shí)例演示SpringBoot如何訪問靜態(tài)Web頁面。engineeringSoftwareSpringBoot默認(rèn)不支持JSP,因?yàn)镴SP相對(duì)于一些模板引擎,性能都比較低,官方推薦使用thymeleaf,如果想在項(xiàng)目中使用JSP,需要進(jìn)行相關(guān)初始化工作。下面通過實(shí)例演示SpringBoot如何訪問JSP頁面。3.2SpringBoot對(duì)JSP的支持

engineeringSoftwareThymeleaf支持SpringExpressionLanguage語言作為方言,也就是SpEL,在學(xué)習(xí)JSP時(shí)我們對(duì)EL表達(dá)式都有一定的認(rèn)識(shí)了,SpEL是可以用于Spring中的一種EL表達(dá)式。Thymeleaf的主要作用是把model中的數(shù)據(jù)渲染到html中,因此其語法主要是如何解析model中的數(shù)據(jù)。在HTML頁面中引入thymeleaf命名空間,即,此時(shí)在HTML模板文件中動(dòng)態(tài)的屬性使用th:命名空間修飾。<htmllang="en"xmlns:th="">這樣才可以在其他標(biāo)簽里面使用th:*這樣的語法,這是下面語法的前提。3.3Thymeleaf的基本語法

engineeringSoftwareThymeleaf通過${}來獲取model中的變量,注意這不是EL表達(dá)式,而是OGNL表達(dá)式,但是語法非常像。示例:我們?cè)陧撁娅@取user數(shù)據(jù):<h1>歡迎您:<spanth:text="${}">請(qǐng)登錄</span></h1>3.3.1變量表達(dá)式

engineeringSoftware感覺跟el表達(dá)式幾乎是一樣的。不過區(qū)別在于,我們的表達(dá)式寫在一個(gè)名為:th:text的標(biāo)簽屬性中,這個(gè)叫做指令。Thymeleaf崇尚自然模板,意思就是模板是純正的html代碼,脫離模板引擎,在純靜態(tài)環(huán)境也可以直接運(yùn)行?,F(xiàn)在如果我們直接在html中編寫${}這樣的表達(dá)式,顯然在靜態(tài)環(huán)境下就會(huì)出錯(cuò),這不符合Thymeleaf的理念。Thymeleaf中所有的表達(dá)式都需要寫在指令中,指令是HTML5中的自定義屬性,在Thymeleaf中所有指令都是以th:開頭。因?yàn)楸磉_(dá)式${}是寫在自定義屬性中,因此在靜態(tài)環(huán)境下,表達(dá)式的內(nèi)容會(huì)被當(dāng)做是普通字符串,瀏覽器會(huì)自動(dòng)忽略這些指令,這樣就不會(huì)報(bào)錯(cuò)了!2.2全局配置

engineeringSoftware當(dāng)數(shù)據(jù)量比較多的時(shí)候,頻繁的寫user.就會(huì)非常麻煩。因此,Thymeleaf提供了自定義變量來解決:<h2th:object="${user}"><p>姓名:<spanth:text="*{name}">Jack</span></p><p>年齡:<spanth:text="*{age}">21</span></p></h2>首先在h2上用th:object="${user}"獲取user的值,并且保存。然后,在h2內(nèi)部的任意元素上,可以通過*{屬性名}的方式,來獲取user中的屬性,這樣就省去了大量的user.前綴了。th:object聲明變量一般情況下會(huì)好*{}一起配合使用,達(dá)到偷懶的效果。3.3.2自定義變量

engineeringSoftwareThymeleaf通過${}來獲取容器上下文環(huán)境中的變量,而表達(dá)式是ognl表達(dá)式。OGNL表達(dá)式本身支持方法的調(diào)用,例如:<h2th:object="${user}"><p>姓:<spanth:text="*{name.split('')[0]}">張</span></p><p>名:<spanth:text="*{name.split('')[1]}">三</span></p></h2>這里我們調(diào)用了name(是一個(gè)字符串)的split方法。3.3.3方法

engineeringSoftwareThymeleaf中提供了一些內(nèi)置對(duì)象,并且在這些對(duì)象中提供了一些方法,方便我們來調(diào)用。獲取這些對(duì)象,需要使用

#對(duì)象名

來引用。3.3.3方法

engineeringSoftware(1)一些環(huán)境相關(guān)對(duì)象#ctx、#requset、#response、#session、#servletContext(2)Thymeleaf提供的全局對(duì)象:#dates、#calendars、#numbers、#strings、#bools、#arrays、#lists、#sets、#maps有的時(shí)候,我們需要在指令中填寫基本類型如:字符串、數(shù)值、布爾等,并不希望被Thymeleaf解析為變量,這個(gè)時(shí)候稱為字面值。(1)字符串字面值:使用一對(duì)單引號(hào)引用的內(nèi)容就是字符串字面值。<p>你正在觀看<spanth:text="'thymeleaf'">template</span>的字符串常量值.</p>th:text

中的thymeleaf并不會(huì)被認(rèn)為是變量,而是一個(gè)字符串。3.3.4字面值

engineeringSoftware(2)數(shù)字字面值數(shù)字不需要任何特殊語法,寫的什么就是什么,而且可以直接進(jìn)行算術(shù)運(yùn)算。<p>今年是<spanth:text="2022"></span>.</p><p>兩年后將會(huì)是<spanth:text="2022+2"></span>.</p>

(3)布爾字面值布爾類型的字面值是true或false:<divth:if="true">你填的是true</div>3.3.4字面值

engineeringSoftware我們經(jīng)常會(huì)用到普通字符串與表達(dá)式拼接的情況:<spanth:text="'歡迎您:'+${}"></span>字符串字面值需要用單引號(hào),拼接起來非常麻煩,Thymeleaf對(duì)此進(jìn)行了簡化,使用一對(duì)|即可:<spanth:text="|歡迎您:${}|"></span>與上面是完全等效的,這樣就省去了字符串字面值的書寫。

3.3.5拼接

engineeringSoftware(1)算術(shù)運(yùn)算支持的算術(shù)運(yùn)算符:

+-*/%<spanth:text="${user.age}"></span><spanth:text="${user.age}%2==0"></span>(2)比較運(yùn)算支持的比較運(yùn)算:>、<、>=、<=、==、!=。注意==and!=不僅可以比較數(shù)值,還類似于equals的功能,對(duì)對(duì)象進(jìn)行比較。<spanth:text="'你的年齡是否小于30:'+(${user.age}<30)"></span>3.3.6運(yùn)算

engineeringSoftware(3)三元運(yùn)算三元運(yùn)算符的三個(gè)部分:conditon?then:else?condition:條件?then:條件成立的結(jié)果?else:不成立的結(jié)果其中的每一個(gè)部分都可以是Thymeleaf中的任意表達(dá)式。<spanth:text="'你的性別:'+(${user.sex}?'男':'女')"></span>3.3.6運(yùn)算

engineeringSoftware(4)默認(rèn)值有的時(shí)候,我們?nèi)∫粋€(gè)值可能為空,這個(gè)時(shí)候需要做非空判斷,可以使用表達(dá)式“?:默認(rèn)值”簡寫。<spanth:text="'你的年齡是'+(${user.age}?:20)"></span>當(dāng)前面的表達(dá)式值為null時(shí),就會(huì)使用后面的默認(rèn)值。注意:

?:

之間沒有空格。3.3.6運(yùn)算

engineeringSoftware假如有用戶的java.util.List集合:users在Context中。<trth:each="user:${users}"><tdth:text="${}"></td><tdth:text="${user.age}"></td><tdth:text="${user.sex}"></td></tr>3.3.7循環(huán)

engineeringSoftwarejava.util.List類型不是可以在Thymeleaf中使?迭代的唯?值類型,下面這些類型的對(duì)象都可以通過th:each進(jìn)?迭代的:(1)任何實(shí)現(xiàn)java.util.Iterable接?的對(duì)象,其值將被迭代器返回,?不需要在內(nèi)存中緩存所有值。(2)任何實(shí)現(xiàn)java.util.Enumeration接?的對(duì)象。(3)任何實(shí)現(xiàn)java.util.Map接?的對(duì)象,迭代映射時(shí),iter變量將是java.util.Map.Entry類。(4)任何數(shù)組。(5)任何其將被視為包含對(duì)象本身的單值列表。3.3.7循環(huán)

engineeringSoftware迭代過程中,經(jīng)常會(huì)使用到它的一些迭代狀態(tài),如:當(dāng)前迭代的索引,迭代變量中的元素的總數(shù),當(dāng)前迭代的是奇數(shù)還是偶數(shù),當(dāng)前是否是第一個(gè)元素,當(dāng)前是否是最后一個(gè)元素等等。狀態(tài)變量在每個(gè)th:each屬性中定義,并包含以下數(shù)據(jù):(1)index屬性:當(dāng)前迭代索引,從0開始(2)count屬性:當(dāng)前的迭代計(jì)數(shù),從1開始(3)size屬性:迭代變量中元素的總量(4)current屬性:每次迭代的iter變量,即當(dāng)前遍歷到的元素(5)even/odd布爾屬性:當(dāng)前的迭代是偶數(shù)還是奇數(shù)。(6)first布爾屬性:當(dāng)前的迭代是否是第?個(gè)迭代(7)last布爾屬性:當(dāng)前的迭代是否是最后?個(gè)迭代。3.3.7循環(huán)

engineeringSoftware很多時(shí)候只有在滿足某個(gè)條件時(shí),才將?個(gè)模板片段顯示在結(jié)果中,否則不進(jìn)行顯示。比如只有當(dāng)用戶年齡小于18歲時(shí),才為他為未成年人,否則不顯示。th:if屬性用于滿足這個(gè)需求。<spanth:if="${age}<18">未成年</span>3.3.8邏輯判斷

engineeringSoftwareth:if屬性不僅只以布爾值作為判斷條件,它將按照如下規(guī)則判定指定的表達(dá)式結(jié)果為true:(1)如果表達(dá)式結(jié)果為布爾值,則為true或者false(2)如果表達(dá)式的值為null,th:if將判定此表達(dá)式為false(3)如果值是數(shù)字為0時(shí),判斷為false;不為零時(shí),判定為true(4)如果value是String,值為“false”、“off”、“no”時(shí),判定為false,否則判斷為true,字符串為空時(shí),也判斷為true(5)如果值不是布爾值、數(shù)字、字符或字符串的其它對(duì)象,只要不為null,則判斷為trueth:unless是th:if的反向?qū)傩?,它們判斷的?guī)則一致,只是if當(dāng)結(jié)果為true時(shí)進(jìn)行顯示,unless當(dāng)結(jié)果為false進(jìn)行顯示。3.3.8邏輯判斷

engineeringSoftwareth:switch/th:case與Java中的switch語句等效,有條件地顯示匹配的內(nèi)容。只要其中一個(gè)th:case的值為true,則同一個(gè)switch語句中的其他th:case屬性都將被視為false。當(dāng)有多個(gè)case的值為true時(shí),則只取第一個(gè)。

switch語句的default選項(xiàng)指定為th:case=“*”,即當(dāng)沒有case的值為true時(shí),將顯示default的內(nèi)容,如果有多個(gè)default,則只取第一個(gè)。3.3.9分支控制switch

engineeringSoftware

系統(tǒng)中的很多頁面有很多公共內(nèi)容,例如菜單、頁腳等,這些公共內(nèi)容可以提取放在一個(gè)稱為“模板片斷”的公共頁面里面,其它頁面可以引用這個(gè)。

模板片斷可以是html標(biāo)簽,也可以使用th:fragment屬性定義片斷。

接下來就可以在Web頁面中使用th:insert、th:replace、th:include屬性來包含頁腳片段,其中這三個(gè)有些區(qū)別。

1.th:insert:當(dāng)前標(biāo)簽里面插入模板中的標(biāo)簽

2.th:replace:替換當(dāng)前標(biāo)簽為模板中的標(biāo)簽

3.th:include:在標(biāo)簽里面插入模板的標(biāo)簽內(nèi)容3.3.10Thymeleaf模板片斷

engineeringSoftware

創(chuàng)建項(xiàng)目,選擇相應(yīng)依賴3.4實(shí)現(xiàn)基于Thymeleaf的Web應(yīng)用

engineeringSoftware項(xiàng)目創(chuàng)建成功之后,在pom.xml文件中就添加了Thymeleaf依賴,代碼如下。<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency>什么是國際化?例如我們的,進(jìn)入是一個(gè)默認(rèn)英文的網(wǎng)站,右上角有個(gè)中字,點(diǎn)一下就會(huì)幫我們切換成中文網(wǎng)站,這就是國際化。在SpringBoot的Web應(yīng)用中實(shí)現(xiàn)頁面信息國際化非常簡單,下面通過實(shí)例講解國際化的實(shí)現(xiàn)過程。3.5SpringBoot中的頁面國際化實(shí)現(xiàn)

engineeringSoftwareSpringBoot確實(shí)為我們做了很多事情,但有時(shí)候我們想要自己定義一些Handler,Interceptor,ViewResolver,該怎么做呢。SpringBoot2.0后,該類被標(biāo)記為@Deprecated。因此我們只能靠實(shí)現(xiàn)WebMvcConfigurer接口來實(shí)現(xiàn)。WebMvcConfigurer是一個(gè)接口,提供很多自定義的攔截器,例如跨域設(shè)置、類型轉(zhuǎn)化器等等??梢哉f此接口為開發(fā)者提前想到了很多攔截層面的需求,方便開發(fā)者自由選擇使用。SpringBoot推薦使用實(shí)現(xiàn)WebMvcConfigurer接口的實(shí)現(xiàn)類來實(shí)現(xiàn)代碼配置,代碼如下。@ConfigurationpublicclassMyConfigurerimplementsWebMvcConfigurer{}3.6SpringBoot集成SpringMVC

engineeringSoftwareSpringBoot確實(shí)為我們做了很多事情,但有時(shí)候我們想要自己定義一些Handler,Interceptor,ViewResolver,該怎么做呢。SpringBoot2.0后,該類被標(biāo)記為@Deprecated。因此我們只能靠實(shí)現(xiàn)WebMvcConfigurer接口來實(shí)現(xiàn)。WebMvcConfigurer是一個(gè)接口,提供很多自定義的攔截器,例如跨域設(shè)置、類型轉(zhuǎn)化器等等。可以說此接口為開發(fā)者提前想到了很多攔截層面的需求,方便開發(fā)者自由選擇使用。SpringBoot推薦使用實(shí)現(xiàn)WebMvcConfigurer接口的實(shí)現(xiàn)類來實(shí)現(xiàn)代碼配置,代碼如下。@ConfigurationpublicclassMyConfigurerimplementsWebMvcConfigurer{}3.6.1配置自定義攔截器Interceptor

engineeringSoftware以前寫SpringMVC的時(shí)候,如果需要訪問一個(gè)頁面,必須要寫Controller類,然后再寫一個(gè)方法跳轉(zhuǎn)到頁面,感覺好麻煩,如上面“/index”,其實(shí)可以重寫WebMvcConfigurer中的addViewControllers方法即可達(dá)到效果了。

addViewControllers方法可以實(shí)現(xiàn)將一個(gè)無業(yè)務(wù)邏輯的請(qǐng)求直接映射為視圖,不需要編寫控制器來實(shí)現(xiàn),從而簡化了頁面跳轉(zhuǎn)。

修改上面的MyConfigurer配置類,在其實(shí)現(xiàn)類中,重寫addViewControllers方法,3.6.2跳轉(zhuǎn)指定頁面

engineeringSoftware后臺(tái)的開發(fā)過程中不可避免的就是一系列對(duì)JSON數(shù)據(jù)的返回,需要我們進(jìn)行的就是提供各種各樣的數(shù)據(jù)。一般情況下數(shù)據(jù)類型最常用的就是JSON以及XML,在這里我們就講講在SpringBoot里面我們?cè)鯓舆M(jìn)行JSON數(shù)據(jù)的返回以及數(shù)據(jù)一些特殊情況的處理。JSON是目前主流的前后端數(shù)據(jù)傳輸方式,SpringMVC中使用消息轉(zhuǎn)化器HttpMessageConverter對(duì)JSON的轉(zhuǎn)換提供了很好的支持,在SpringBoot中對(duì)相關(guān)配置做了進(jìn)一步簡化。<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency>

3.7SpringBoot處理JSON數(shù)據(jù)

engineeringSoftwareSpringBoot處理JSON數(shù)據(jù)時(shí),需要用到兩個(gè)重要的JSON格式轉(zhuǎn)換注解,分別是@RequestBody和@ResponseBody。@ResponseBody注解的作用是將controller的方法返回的對(duì)象通過適當(dāng)?shù)霓D(zhuǎn)換器轉(zhuǎn)換為指定的格式之后,寫入到response對(duì)象的body區(qū),通常用來返回JSON數(shù)據(jù)或者是XML數(shù)據(jù)。@RequestBody是作用在形參列表上,用于將前臺(tái)發(fā)送過來固定格式的數(shù)據(jù)(xml格式或者JSON等)封裝為對(duì)應(yīng)的JavaBean對(duì)象,封裝時(shí)使用到的一個(gè)對(duì)象是系統(tǒng)默認(rèn)配置的HttpMessageConverter(消息轉(zhuǎn)換器)進(jìn)行解析,然后封裝到形參上。3.7SpringBoot處理JSON數(shù)據(jù)

engineeringSoftwareRESTful架構(gòu)風(fēng)格是目前最流行的一種架構(gòu)風(fēng)格,它機(jī)構(gòu)清晰、符合標(biāo)準(zhǔn)、易于理解、擴(kuò)展方便,所以在Web開發(fā)中經(jīng)常被使用。REST,全稱是RepresentationalStateTransfer,譯作“表現(xiàn)層狀態(tài)轉(zhuǎn)化”。RESTful架構(gòu)是對(duì)MVC架構(gòu)改進(jìn)后所形成的一種架構(gòu),通過使用事先定義好的接口與不同的服務(wù)聯(lián)系起來。在RESTful架構(gòu)中,瀏覽器使用POST,DELETE,PUT和GET四種請(qǐng)求方式分別對(duì)指定的URL資源進(jìn)行增刪改查操作。因此,RESTful是通過URI實(shí)現(xiàn)對(duì)資源的管理及訪問,具有擴(kuò)展性強(qiáng)、結(jié)構(gòu)清晰的特點(diǎn)。

3.8SpringBoot實(shí)現(xiàn)RESTful風(fēng)格Web應(yīng)用

engineeringSoftwareRESTful架構(gòu)將服務(wù)器分成前端服務(wù)器和后端服務(wù)器兩部分,前端服務(wù)器為用戶提供無模型的視圖;后端服務(wù)器為前端服務(wù)器提供接口。瀏覽器向前端服務(wù)器請(qǐng)求視圖,通過視圖中包含的AJAX函數(shù)發(fā)起接口請(qǐng)求獲取模型。

Restful是一種對(duì)URL進(jìn)行規(guī)范的編碼風(fēng)格,通常一個(gè)網(wǎng)址對(duì)應(yīng)一個(gè)資源,訪問形式類似/xx/{id}/{id}。

舉個(gè)例子,當(dāng)我們?cè)谀迟徫锞W(wǎng)站上買手機(jī)時(shí)會(huì)有很多品牌選擇,而每種品牌下又有很多型號(hào),那么/mobile/iphone/6代表了Iphone6,/mobile/iphone/7和/mobile/iphone/8分別代表了Iphone7和Iphone8。3.8SpringBoot實(shí)現(xiàn)RESTful風(fēng)格Web應(yīng)用

engineeringSoftware在做Web開發(fā)的過程中,method常用的值是get和post??墒聦?shí)上,method值還可以是put和delete等等其他值。

既然method值如此豐富,那么就可以考慮使用同一個(gè)url,但是約定不同的method來實(shí)施不同的業(yè)務(wù),這就是Restful的基本考慮。

CRUD是最常見的操作,在使用Restful風(fēng)格之前,通常的增加做法是這樣的:/addCategory?name=xxx可是使用了Restful風(fēng)格之后,增加就變成了:/categories3.8SpringBoot實(shí)現(xiàn)RESTful風(fēng)格Web應(yīng)用

engineeringSoftware

3.8SpringBoot實(shí)現(xiàn)RESTful風(fēng)格Web應(yīng)用

engineeringSoftware功能傳統(tǒng)風(fēng)格Restful風(fēng)格

urlmethodurlmethod增加/addCategory?name=xxxPOST/categoriesPOST刪除/deleteCategory?id=123GET/categories/123DELETE修改/updateCategory?id=123&name=yyyPOST/categories/123PUT獲取/getCategory?id=123GET/categories/123GET查詢/listCategoryGET/categoriesGET為了實(shí)現(xiàn)RESTfulAPI接口,SpringBoot提供了很多注解,對(duì)請(qǐng)求參數(shù)和返回?cái)?shù)據(jù)格式做了封裝,方便用戶快速開發(fā)。@RestController一般用于Controller類上,指定所有接口返回的數(shù)據(jù)都是text/json格式。@ResponseBody用于方法上,指定接口返回text/json格式,用了@RestController就沒有必要用ResponseBody。@GetMapping用于方法上,是一個(gè)組合注解,與@RequestMapping(method=RequestMethod.GET)作用一致。@PostMapping用于方法上,是一個(gè)組合注解,與@RequestMapping(method=RequestMethod.POST)作用一致。

3.8SpringBoot實(shí)現(xiàn)RESTful風(fēng)格Web應(yīng)用

engineeringSoftware@PutMapping用于方法上,是一個(gè)組合注解,與@RequestMapping(method=RequestMethod.PUT)作用一致。@DeleteMapping用于方法上,是一個(gè)組合注解,與@RequestMappmg(method=RequestMethod.DELETE)作用一致。@RequestParam用于方法上,映射請(qǐng)求參數(shù)到j(luò)ava方法的

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論