本節課介紹了 ThinkPHP 框架的應用范圍,介紹了 ThinkPHP 框架兩個版本的新特性,并對 ThinkPHP、Laravel、Yii 框架做了簡單的對比。對于剛入門的 PHP 程序員來說,ThinkPHP 框架是最適合學習的一款 MVC 框架,但在學習本套教程之前需要掌握 PHP 基礎知識、Linux 基礎知識、MySQL 基礎知識。Tips:想要學習更多 ThinkPHP 相關知識,可以點擊Excel 導入學生信息Excel 導出學生信息后臺處理數據
本節課和大家一起講解了 Spring MVC 的地址請求映射,認識了 @RequestMapping 注解。此注解最主要的功能就是使用一個邏輯名把內部控制器或控制器中的方法暴露給使用者。@RequestMapping 提供了很靈活的映射方案,也提供了相應的內部方法對請求 URL 進一步過濾、篩選。記住這個注解的使用,你便能變著花樣把控制器映射出去。
Spring MVC 內部提供了很多優雅的異常處理機制。其中之一就是把不同的異常映射成 HTTP 狀態碼。如下面實例:首先定義一個異常類:@ResponseStatus(value = HttpStatus.FORBIDDEN, reason = "數字范圍不符合要求!(不能是 20)")public class NumberException extends RuntimeException { }如果在方法中拋出的異常已經被映射成了狀態嗎。則在瀏覽器中顯示出來的異常信息會明確很多。@RequestMapping("/exception")public String test(@RequestParam("num") int num) { if (num == 20) { throw new NumberException(); } return "success";}在瀏覽器中輸入 http://localhost:8888/sm-demo/exception?num=13 ??梢钥吹剑憾ㄖ苹男畔⒁呀浻兴纳?,但是,還是不夠友好。
打開項目的 pom.xml 文件,在其中添加如下內容:<dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>2.0.1</version></dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.2</version></dependency><!-- 數據庫驅動包 --><dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.21</version> <scope>compile</scope></dependency><dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-dbcp2</artifactId> <version>2.1.1</version></dependency><dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>5.1.13.RELEASE</version> <scope>compile</scope></dependency>Tips:Spring MVC 連接數據庫時,需要添加 spring-jdbc 依賴包。
打開項目中的 pom.xml 文件,添加項目對 Thymeleaf 包的依賴;<dependency> <groupId>org.thymeleaf</groupId> <artifactId>thymeleaf-spring5</artifactId> <version>3.0.11.RELEASE</version></dependency>打開項目中的 WebConfig 配置類。在類中添加一個 ApplicationContext 類型的屬性。并讓 Spring 自動注入進來;@Autowiredprivate ApplicationContext applicationContext;Tips: Thymeleaf 相關組件需要依賴上下文容器對象。在 WebConfig 配置類中配置 Thymeleaf 模板組件信息,并指定模板文件存放位置;@Beanpublic SpringResourceTemplateResolver templateResolver() { SpringResourceTemplateResolver templateResolver = new SpringResourceTemplateResolver(); templateResolver.setApplicationContext(this.applicationContext); templateResolver.setPrefix("/WEB-INF/templates/"); templateResolver.setSuffix(".html"); templateResolver.setTemplateMode(TemplateMode.HTML); templateResolver.setCacheable(true); //templateResolver.setOrder(1); return templateResolver;}Tips: Spring MVC 項目中可以使用多視圖技術。可以使用模板對象的 setOrder ( ) 指定查找順序。本章節主要講解 Thymeleaf 視圖技術。所以,請大家注釋掉配置過的其它視圖技術的相關信息。在 WebConfig 配置類中指定模板引擎對象;先配置 SpringTemplateEngine 組件: 從字面上很好理解,模板引擎組件。@Beanpublic SpringTemplateEngine templateEngine() { SpringTemplateEngine templateEngine = new SpringTemplateEngine(); templateEngine.setTemplateResolver(templateResolver()); templateEngine.setEnableSpringELCompiler(true); return templateEngine;}Tips: 這里有組件與組件的依賴關系。? 配置 ThymeleafViewResolver 組件: 視圖解析組件,依賴于模板引擎,模板引擎依賴模板資源。@Beanpublic ViewResolver viewResolver(SpringTemplateEngine templateEngine) { ThymeleafViewResolver viewResolver = new ThymeleafViewResolver(); viewResolver.setTemplateEngine(templateEngine); viewResolver.setCharacterEncoding("UTF-8"); return viewResolver;}經過上述配置后,Spring MVC 就具有了對 Thymeleaf 的支持。
本節將會引入一個全新的概念——適配器,這個名字很形象,和電源適配器的功能類似,從程序設計的角度出發,它可以將不同類型、不同結構的數據適配到一起。在 Android 中,適配器是 UI 組件和數據之間的橋梁,它幫助我們將數據填充到 UI 組件當中,實現了一個典型的 MVC 模式。我們可以分別編寫獨立的 UI 樣式和數據模型,至于數據如何與 UI 組件綁定都由 Adapter 幫我們完成,這樣的好處就是做到 UI 和數據的解耦。Android 系統為我們提供了多種 Adapter,今天就來介紹幾種常見同場景下 Adapter 的基本用法。
GridView 在 Android App 中運用非常廣泛,比如我們手機的系統相冊將我們的照片及照片名稱按照網格的樣式排列起來,并且可以上下滾動,這種效果非常適合用 GridView 實現。為了實現 MVC 模式,更方便的管理數據與 UI,GridView 通過 Adapter 完成數據的填充,Adapter 的使用幾乎和 ListView 一樣,另外系統提供了幾種簡單的 Adapter,具體可以參考 23 節和 24 節的內容。
無論是基于原生 Servlet 、還是基于 Spring MVC 開發,中文亂碼總是一件讓人頭痛的事情。當用戶在網頁中輸入中文信息提交給服務器后,服務器端解析時得到可能是一個亂碼?;蛘弋敺掌靼l送中文數據給客戶端時,瀏覽器中顯示出來的也可能是亂碼。為什么會產生中文亂碼?服務器端在解析客戶端數據時,默認情況下使用的并不是中文編碼。同理,在服務器端把數據放入響應包中時,使用的也不是中文編碼。知道事情原因后,就好辦了,只需要在服務器端解析數據或向數據包中寫入數據時選擇正確的中文編碼就可以了。在登錄頁面輸入用戶名和密碼時,如下圖所示輸入中文:在控制器中解析數據時,得到的是亂碼,既然是亂碼,后面的邏輯想都不用想,肯定是通不過的。瀏覽器封裝數據到請求包時,使用的是支持中文的如 UTF-8 編碼。但是,在服務器解碼數據時,使用的并不是 UTF-8 編碼。編碼與解碼的前后不一致,導致中文亂碼的出現。知道原因后,問題就不再是問題。無論 Spring MVC 顯得多么高級,但解析數據還是由 HttpServletRequest 對象完成的,最直接的解決方案就是讓 Spring 注入原生的 HttpServletRequest 對象,再重設解析數據的編碼即可。當然,為了保證中文數據能正確的寫入響應包,也需要注入 HttpServletResponse 。@RequestMapping(value="/login") public String login01(HttpServletRequest request,HttpServletResponse response) throws UnsupportedEncodingException { request.setCharacterEncoding("utf-8"); response.setContentType("text/html;charset=utf-8"); String userName=request.getParameter("userName"); String userPassword=request.getParameter("userPassword"); if("慕課".equals(userName) && "123".equals(userPassword)) { return "index"; } return "fail"; }}再次在瀏覽器中發起中文登錄請求,控制器能正確解析中文,驗證通過,跳轉到 “index” 視圖。問題是得到了解決,但有種共產主義社會又回到原始社會的感覺,Spring MVC 的優勢蕩然無存。這種方案只能說是一種方案,而不能說是一種企業級的快速解決方案。
下面,使用純 JAVA 方式為 Spring MVC 的初次運行提供必備的配置信息 。先認識一個組件,做好思想準備,這個組件名字很長,別嚇到你了:AbstractAnnotationConfigDispatcherServletInitializer。名字雖然有點長,但是很體貼,怕你不知道它的作用,名字本身就告訴了你:基于注解的初始化 DispatcherServlet 的抽象組件,簡單說就是一個 WEB 初始化組件,用來替代 web.xml 的功能。該動手了!構建一個繼承了AbstractAnnotationConfigDispatcherServletInitializer 的類:package com.mk.config;import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;public class WebInitializer extends AbstractAnnotationConfigDispatcherServletInitializer{ @Override protected Class<?>[] getRootConfigClasses() { return null; } @Override protected Class<?>[] getServletConfigClasses() { return null; } @Override protected String[] getServletMappings() { return null; }}嘿!居然有 3 個方法強制性要求實現,那么,這 3 個方法分別是干嘛用的?WebInitializer 這個類會自動創建 Spring MVC 的 DispatcherServlet 核心組件,并且創建 2 個 WebApplication 上下文對象。Spring 不能白學,是吧,工廠再厲害,你也得告訴它你要創建什么吧。大家還記得這些信息你原來是放在哪里的嗎?想起來了吧,你是放在 XML 文件中的,本文則是放在 JAVA 類中。所以這 3 個方法中有 2 個方法是用來指定這 2 個上下文對象分別對應的配置類是誰。知道原因了,立馬準備好 2 個配置類。//web 上下文對象的配置類@Configuration@ComponentScan(basePackages = { "com.mk.web" }, excludeFilters = { @Filter(type = FilterType.ANNOTATION, value = EnableWebMvc.class) })public class RootConfig {}// Root 上下文對象的配置類@Configuration@EnableWebMvc@ComponentScan(basePackages = { "com.mk.web.action" })public class WebConfig {}這里有 3 個注解需要說明 一下:@Configuration 注解:說明這個類是配置類;Tips: 配置類用來替代 XML 配置文件。@EnableWebMvc 注解: 很好理解,啟動 Spring MVC 相關功能;@ComponentScan 注解: 指定上下文對象各自負責的組件所在包。Tips: Root 配置類中需要排除 Web 配置類負責的區域。在重新完善 WebInitializer 類之前,說明一下,另一個方法是用來指定前端控制器可以響應的請求地址。OK!讓我們再來看看這 3 個方法本來應該的樣子:@Overrideprotected Class<?>[] getRootConfigClasses() { return new Class[] { RootConfig.class};}@Overrideprotected Class<?>[] getServletConfigClasses() {return new Class[] { WebConfig.class};}//接受所有請求@Overrideprotected String[] getServletMappings() { return new String[] {"/"};}
數據驗證是對數據進行邏輯處理之前需要進行的一個很重要環節,如果不合要求的數據進入邏輯處理環節后,會導致程序的崩潰。WEB 應用程序中,驗證用戶提交的表單數據的合法性既可以在客戶端實現,也可以在服務器端實現。客戶端驗證: 表單提交之前,通過客戶端的 JS 腳本對表單中預提交的數據進行驗證;服務器端驗證: 數據提交到服務器后,由服務器端的的代碼進行驗證。對于非敏感性的數據可以在客戶端驗證,如一些常規性的輸入格式要求驗證、類似于密碼長度要多少、信息不能為空等。服務器端相比較于客戶端驗證,會多出網絡流量消耗。但是,對于一些敏感性的數據,比如身份證信息、銀行卡信息…… 還是需要交給服務器的。Spring MVC 提供的有驗證框架,能夠在綁定請求包中的數據時,按開發者提出的格式驗證規則對數據進行驗證。Spring MVC 驗證框架的使用非常便利,只需要幾個注解就能輕松解決問題。使用之前,有幾個概念先要交代清楚。
如下面的實例:@RequestMapping("/response02")public String response02(ModelMap model) throws IOException { //發送給客戶端的響應數據 String hello="Hello"; model.addAttribute("data", hello); return "hello";}上面代碼是一個典型的 Spring MVC 控制器代碼:變量 hello 中保存的就是要發送給瀏覽器的數據。ModelMap 類型的數據模型可以說是一個中間載體,用來臨時保存 hello 中的數據;return 后面的 “hello” 是視圖的邏輯名,由視圖解析器解析并找到真正的頁面。下面是一個標準的視圖模板,頁面中已經提供了樣式,只等數據的到來。 <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <div style="color:red"> ${data} </div> </body> </html>有了這些信息后,視圖解析器把數據和視圖合二為一后進行渲染,得到純 HTML 后寫入響應包,發送給瀏覽器。這便于轉發或者叫派發。默認情況下,控制器的響應方式使用的是轉發。轉發是在一次請求中一氣呵成完成的。如上代碼,在瀏覽器輸入請求:http://localhost:8888/sm-demo/response02。服務端響應包中的數據這就是響應給客戶端的最終數據。Tips: Spring MVC 的整個請求和響應過程是由多個組件協作完成的,這里不深究細節。
上一章節提到了 Spring MVC 的幾大核心組件,并對前端控制器、用戶控制器、映射器 3 大組件做了較全方面的講解,相信大家一定對它們有了更理性的認識。本節課繼續講解適配器、視圖解析器組件。通過本節課,你將了解到:適配器的功能及配置;視圖解析器的基本功能及配置;組件之間是如何協作完成用戶的請求的。這個是本章節的重點,也是對各組件的歸納和總結。
Spring Security 的核心特性包括:認證和授權、常規攻擊防范、與 Servlet 接口集成、與 Spring MVC 集成等。認證和授權的目的是,讓系統知道使用者是誰(認證)?是什么樣的身份?允許他做什么?禁止他做什么?通常的做法是要求用戶輸入自己的用戶名和密碼,來實現登錄和鑒權的過程。常規攻擊防范在 Spring Security 安全框架中是默認開啟的,常見的威脅抵御方式有:防止偽造跨站請求(CSRF)安全響應頭(HTTP Response headers)HTTP 通訊安全作為 Spring 大家族的一員,Spring Security 在與 Spring 引用,尤其是與 Spring boot 應用的結合時,顯得極為便利。Spring Security 三大功能
application.xml 是 Spring 上下文容器所關聯的配置文件,可稱其為全局上下文對象的關聯配置文件。<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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <context:annotation-config></context:annotation-config> <context:component-scan base-package="com.mk.web"> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" /> </context:component-scan></beans>元素解釋說明:context:annotation-config: 啟動注解支持,建議需要全局上下文對象創建、維護的對象使用注解的方式;context:component-scan: 掃描位置,需要排除開 Spring MVC 容器對象掃描的位置。Tips: application.xml 文件中一般用來配置業務層邏輯組件、數據層邏輯組件、通用組件、第三方組件相關的信息。
OOP 代碼中經常會出現類似于 A 對象引用 B 對象,B 對象引用 C 對象的現象。 類似于現實生活中的小王有一輛汽車,汽車有一把鑰匙……如果每一個用戶都有一輛汽車,用 OOP 描述,意味著 User 類中有一個對 Car 的引用類型屬性。public class User { private String userName; private String userPassword; private Car car; //……}假設 Car 類結構如下:public class Car {private String carType;private String carColor;//……}在注冊時,除了要輸入用戶信息之外,還需要指定用戶所擁有的汽車類型、顏色。那么,控制器是否能自動綁定用戶以及汽車數據?Tips: 為什么注冊時要輸入汽車信息,不要糾結,只是一個用來說明問題的例子。答案是肯定的。只需要在表單頁面中添加如下代碼,控制器端不做任何修改。如此,除了能接收用戶數據外,還能接收汽車的信息。<form action="user/register" method="post"> 用戶名:<input type="text" value="" name="userName" /> <br /> 密碼:<input type="password" value="" name="userPassword" /> <br /> 汽車類型:<input type="text" value="" name="car.carType" /> <br /> 汽車顏色:<input type="text" value="" name="car.carColor" /> <br /> <input type="submit" value="注冊" name="btnRegister" /> <input type="reset" value="重置" name="btnReset" /></form>也就是說,Spring MVC 支持對象級聯自動數據綁定。Spring MVC 支持多層級的對象級聯。
在控制器的方法中聲明 InputStream 作為入參,Spring MVC 就能注入你想要的 InputStream 對象。@RequestMapping(value = "/testApi04",method = RequestMethod.POST)public void hello(InputStream inputStream) throws IOException { byte[] buff=new byte[128]; int read= inputStream.read(buff); System.out.println(new String(buff,0,read));}上面的實例,能讀取到請求包中的數據,但過于低級,可讀性并不是很好。Tips: 控制器方法的映射機制有只接受 POST 方法的限制,如果是 GET 方法的請求包,直接使用 InputStream 對象無法獲取到請求包中的數據。GET 方法的請求數據是附加在 URL 上的,InputStream 只能讀取實體部分的數據。
本節課程和大家一起講解了如何在控制器中把 OOP 數據轉換成 JSON 格式后傳遞給瀏覽器。開發者可以自己編碼把對象數據轉換成特定格式的字符串后響應給瀏覽器,但是,這個過程很勞心勞力。使用 Spring MVC 框架提供的 JSON 序列化轉換組件,開發者不用關心底層具體轉換過程便能達到目的??蚣軒烷_發者解決了很多共性的問題,讓開發者可以有更多時間關注自己的核心邏輯。記住!@ResponseBody 注解很重要。
2.2.1 驗證前的準備打開項目中的 pom.xml 文件,添加 validation-api 依賴包,大家需要注意一下,包名是以 javax 開頭的。因為 Spring MVC 并沒有實現 JSR 接口規范,這里選擇 hibernate-validator ;Tips: hibernate-validator 是 Hibernate 提供的 JSR 具體實現模塊。<dependency> <groupId>javax.validation</groupId> <artifactId>validation-api</artifactId> <version>2.0.1.Final</version></dependency><dependency> <groupId>org.hibernate.validator</groupId> <artifactId>hibernate-validator</artifactId> <version>6.1.0.Final</version></dependency>打開 WebConfig 配置類,通知 Spring MVC 創建 LocalValidatorFactoryBean 對象。可以使用這個工廠對象創建具體的實現了 JSR 規范的驗證器。@Beanpublic LocalValidatorFactoryBean validator() { LocalValidatorFactoryBean localValidatorFactoryBean = new LocalValidatorFactoryBean(); localValidatorFactoryBean.setProviderClass(HibernateValidator.class); return localValidatorFactoryBean;}2.2.2 JSR 驗證流程先設定一個需求:添加老師信息。構建一個 Teacher 類,并在 Teacher 類的相關屬性上添加對應注解;public class Teacher {@NotNull(message = "姓名不能為空")private String name; @Min(value = 22,message = "年齡不能小于 22 歲")private Integer age;Tips: JSR 注解有一個 message 屬性,用來保存錯誤提示信息。編寫 teacher.html 頁面;<form action="teacher/save" method="post"> 老師姓名:<input type="text" value="" name="name"/> <br/> 老師年齡:<input type="text" value="" name="age"/> <br/> <input type="submit" value="添加" name="btnSave"/> <input type="reset" value="重置" name="btnReset"/></form>編寫響應控制器;@Controller@RequestMapping("/teacher")public class TeacherAction { @RequestMapping(value = "/save",method = RequestMethod.POST) public String register(@Valid Teacher teacher,BindingResult result) { if (result.hasErrors()) { return "fail"; } return "success"; }}Tips: @Valid 注解表示在綁定數據之后對數據進行驗證。BindingResult 組件用來保存驗證過程中的錯誤信息。除了可以使用 BindingResult ,此處還可以使用 Errors 替代。在瀏覽器中訪問到 teacher.html 頁面,輸入不符合規則的數據后提交(年齡小于 22 歲);最后會在瀏覽器中看到。如此,整個驗證過程完畢。
模型是一個用的很廣的概念。本課程中數據模型應該有 2 層含義:WEB 程序中封裝數據的組件;此模型對象會有自己特定作用域。上一小節中,向大家介紹了 Map 模型對象,其本質是對 HttpServletRequest 對象中的存儲功能的引用。Map 還是比較原始和天然的。Spring MVC 為了展現自己的特色服務,對 Map 進行了多層面的封裝,提供了更豐富的數據模型對象。Tips: 重要的事情強調一下,你將認識或使用到的數據模型會很多,但其本質是:如果是請求作用域,你只是在間接使用 HttpServletRequest 對象;如果是會話作用域,你只是在間接使用 HttpSession 對象。
通過對幾大核心組件的介紹,相信大家對它們各自的功能有所了解。但是,你知道它們之間是如何協作一起完成用戶的一次請求的嗎?當用戶在瀏覽器發出請求的那一刻起,這些組件就緊密地團結在一起,為用戶的請求保駕護航。如上圖所述,簡要描述一下它們是如何協調一致完成工作的:瀏覽器的請求到達前端控制器(DispatcherServlet);前端控制器解析出請求路徑后詢問映射器,咱們是否提供的有用戶需要的用戶控制器,映射器把查詢結果返回給前端控制器;適配器的作用就是統一不同類型的用戶控制器(也體現了 Spring MVC 中用戶控制器的多樣性和靈活性);用戶控制器開始工作(具體的響應邏輯);用戶控制器返回視圖邏輯名和視圖中所需要的數據(ModelAndView);前端控制器詢問視圖解析器,你能夠根據邏輯名找到物理視圖嗎?視圖解析器開始工作并找到物理視圖;前端控制器渲染物理視圖和數據,生成瀏覽器能夠識別的數據格式;響應瀏覽器,并在瀏覽器中顯示最終請求結果。Spring MVC 中,用戶的每一次請求都是眾多組件通力合作完成的,它們是相親相愛的一家人。
本章節和大家一起講解 Spring MVC 框架如何實現轉發和重定向,從實現角度來講,沒有太多難度。默認情況下就是轉發,加上 redirect 關鍵字后就能實現重定向。需要注意的是,redirect 后面需要指定視圖文件的完整路徑。轉發和重定向都是一種響應方式,其內在區別就在于一個是尋找視圖的方式是不同的。一個是控制器幫著找,一個是瀏覽器通過再次發起請求尋找,所以,重定向和轉發對數據模型的作用域要求是不同的。
以字節數組的方式接收上傳的文件數據,過于原始、低級,很難獲取到文件的元數據。Spring MVC 提供有 MultipartFile 接口。查看 MultipartFile 接口源代碼,可以知道 MultipartFile 接口提供了很多方法,能解析出上傳文件的更多元數據,包括文件名、文件大小等,方便開發者更靈活地處理數據。public interface MultipartFile extends InputStreamSource { String getName(); @Nullable String getOriginalFilename(); @Nullable String getContentType(); boolean isEmpty(); long getSize(); byte[] getBytes() throws IOException; @Override InputStream getInputStream() throws IOException; default Resource getResource() { return new MultipartFileResource(this); } void transferTo(File dest) throws IOException, IllegalStateException; default void transferTo(Path dest) throws IOException, IllegalStateException { FileCopyUtils.copy(getInputStream(), Files.newOutputStream(dest)); }}MultipartFile 最常用的是 transferTo 方法,用來把上傳文件存儲到指定位置。重構上面的控制器代碼。 @RequestMapping("/upload") public String upload(@RequestPart("upFile") MultipartFile file) throws IOException { String path = System.getProperty("webapp.root"); String filePath = path + "\\upload\\"+file.getOriginalFilename(); System.out.println(filePath); file.transferTo(new File(filePath)); return "success"; }如上面一樣測試文件上傳,結果沒有什么不一樣。
在控制器的方法中注入 OutputStream 對象,只需要在方法中添加參數聲明。如下實例:可使用 OutputStream 對象讀取指定文件中的內容后直接響應給瀏覽器。@RequestMapping(value = "/testApi05")public void hello(OutputStream outputStream) throws IOException { Resource res = new ClassPathResource("/test.txt"); FileCopyUtils.copy(res.getInputStream(), outputStream);}test.txt 文件的內容是”this is a test’。文件直接放在項目的 src/main/java 目錄下。在瀏覽器中輸入請求路徑 http://localhost:8888/sm-demo/testApi05 。你將在瀏覽器中看到:有句話叫做 “條條道路通羅馬”,用在 Spring MVC 中真的是合適,依靠 Spring 強大的注入功能,只要原生開發中能有的對象基本上都能注入進去。
Spring MVC 還可以使用注解的方式集中處理異常。@ExceptionHandler 注解:此注解所標注的方法能夠處理同一個控制器中所有方法所拋出的異常。如下面實例:@ExceptionHandler(Exception.class)public String exception() { return "exception";}@RequestMapping("/exception04")public String exception04(String userName) throws Exception { if (StringUtils.isEmpty(userName)) { throw new Exception("用戶名不能為空"); } return "index";}當控制器中的方法拋出異常后,會由 exception() 方法統一捕獲,然后跳到指定頁面。@ControllerAdvice 注解:此注解放在類的前面,且類中可以包含一個或多個如下類型的方法。Tips: 由 @ControllerAdvice 注解標注的類本質上就是一個基于 AOP 思想的攔截器。@ExceptionHandler 注解標注的方法;@InitBinder 注解標注的方法;@ModelAttribute 注解標注的方法。@ControllerAdvice 實現案例如下:@ControllerAdvicepublic class ExceptionAdviceAction { @ExceptionHandler(Exception.class) public String exception() { return "exception"; }}無論哪一個控制器中拋出異常,都會由 ExceptionAdviceAction 類中的 exception() 方法統一響應處理。