Spring MVC
也叫 Spring Web MVC
,屬於展現層框架,是 Spring
框架的一部分。html
MVC
模式做用在於分離應用程序的不一樣方面(業務邏輯、 UI 邏輯、輸入邏輯),而 Spring MVC
框架分別對應爲其提供了 模型(Model)、視圖(View)、控制器(Controller) 三層架構和用於開發靈活和鬆散耦合的 Web 應用程序的組件,同時提供這些元素之間的鬆散耦合的實現。java
POJO
類組成。HTML
輸出。Spring MVC
框架是圍繞 DispatcherServlet
設計的,它處理全部的 HTTP
請求和響應。web
Spring MVC
的請求處理工做流以下圖所示:spring
如下是對應於到 DispatcherServlet
的傳入 HTTP
請求的事件順序:express
HTTP
請求後,DispatcherServlet
會查詢 HandlerMapping
以調用相應的 Controller
。Controller
接受請求並根據使用的 GET 或 POST 方法調用相應的服務方法。 服務方法將基於定義的業務邏輯設置模型數據,並將視圖名稱返回給 DispatcherServlet
。DispatcherServlet
將從 ViewResolver
獲取請求的定義視圖。DispatcherServlet
將模型數據傳遞到最終的視圖,並在瀏覽器上呈現。上述的組件 HandlerMapping
、Controller
和 ViewResolver
是 WebApplicationContext
的一部分,它是普通 ApplicationContext
的擴展,帶有 Web
應用程序所需的一些額外功能。json
在 pom.xml
中添加主要依賴 org.springframework:spring-webmvc
瀏覽器
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>4.3.17.RELEASE</version> </dependency>
在 web.xml
中配置 DispatchServlet
處理全部的 HTTP
請求和響應:spring-mvc
<servlet> <servlet-name>springServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath*:/spring-mvc*.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>springServlet</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>
在 web.xml
中還需配置字符集過濾器,用於解決中文編碼問題:架構
<filter> <filter-name>encodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> <init-param> <param-name>forceEncoding</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>encodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
建立一個 spring-mvc
配置文件,用於配置 MVC
:mvc
<?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"> <description>Spring MVC Configuration</description> <!-- 使用 Annotation 自動註冊 Bean,只掃描 @Controller --> <context:component-scan base-package="com.lusifer.myshop" use-default-filters="false"> <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/> </context:component-scan> <!-- 註解映射的支持 --> <mvc:annotation-driven /> <!-- 定義視圖文件解析 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/views/"/> <property name="suffix" value=".jsp"/> </bean> <!-- 靜態資源映射 --> <mvc:resources mapping="/static/**" location="/static/" cache-period="31536000"/> </beans>
上述配置說明:
context:component-scan
:當前配置文件爲 MVC 相關,故只須要掃描包含 @Controller
的註解便可,因爲 spring-context.xml
配置文件中也配置了包掃描,因此還須要排除 @Controller
的註解掃描。InternalResourceViewResolver
:視圖文件解析器的一種,用於配置視圖資源的路徑和須要解釋的視圖資源文件類型,這裏有兩個須要配置的屬性 prefix
(前綴)以及 suffix
(後綴)。
prefix
:配置視圖資源路徑,如:/WEB-INF/views/
。suffix
:配置視圖資源類型,如:.jsp
。mvc:resources
:靜態資源映射,主要用於配置靜態資源文件存放路徑,如:JS、CSS、IMG 等。建立 IndexController
類
@Controller public class IndexController { @Autowired private HelloSpringService helloSpringService; @RequestMapping(value = {"", "/index"}, method = RequestMethod.GET) public String index() { return "index"; } @RequestMapping(value = "login", method = RequestMethod.POST) public String login(@RequestParam(required = true) String email, @RequestParam(required = true) String password) { return "redirect:/main"; } }
在 Spring MVC
中,控制器 Controller
負責處理由 DispatcherServlet
分發的請求,它把用戶請求的數據通過業務處理層處理以後封裝成一個 Model
,而後再把該 Model
返回給對應的 View
進行展現。
在 Spring MVC
中提供了一個很是簡便的定義 Controller
的方法,你無需繼承特定的類或實現特定的接口,只需使用 @Controller
標記一個類是控制器,而後使用 @RequestMapping
和 @RequestParam
等一些註解用以定義 URL
請求和 Controller
方法之間的映射,這樣的 Controller
就能被外界訪問到。此外 Controller
不會直接依賴於 HttpServletRequest
和 HttpServletResponse
等 HttpServlet
對象,它們能夠經過 Controller
的方法參數靈活的獲取到。
但 @Controller
只是定義了一個控制器類,而使用 @RequestMapping
註解的方法纔是真正處理請求的處理器。
@RequestMapping
是一個用來處理請求地址映射的註解,可用於類或方法上。用於類上,表示類中的全部響應請求的方法都是以該地址做爲父路徑。
@RequestMapping
註解有六個屬性:
value
:指定請求的實際地址。method
:指定請求的類型,如 GET、POST、PUT、DELETE 等。consumes
:指定處理請求的提交內容類型(Content-Type),如 application/json
和 text/html
。produces
: 指定返回的內容類型。params
:指定請求的參數值。headers
:指定請求中的 header
值。該註解用於將 Controller
的方法返回的對象,經過適當的 HttpMessageConverter
轉換爲指定格式後,直接寫入 HTTP
響應正文中。
若是須要返回自定義對象爲 JSON
格式,須要添加如下依賴:
<!-- Json Begin --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>2.9.5</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.9.5</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-annotations</artifactId> <version>${jackson.version}</version> </dependency> <!-- Json End -->
Spring MVC
的處理器攔截器,相似於 Servlet
開發中的過濾器 Filter
,用於對處理器進行預處理和後處理。
Spring MVC
攔截器須要實現 HandlerInterceptor
接口,該接口定義了 3 個方法,分別爲 preHandle()
、postHandle()
和 afterCompletion()
,須要經過重寫這 3 個方法來對用戶的請求進行攔截處理的。
preHandle()
:該方法在請求處理以前進行調用。該方法的返回值是布爾值 Boolean
類型的,當它返回爲 false
時,表示請求結束,後續的 Interceptor
和 Controller
都不會再執行;當返回值爲 true
時,就會繼續調用下一個攔截器的 preHandle
方法,若是已是最後一個攔截器的時候,就會是調用當前請求的 Controller
中的方法。postHandle()
:只能在當前所屬攔截器的 preHandle()
的返回值爲 true
的時候,才能被調用。postHandle()
在當前請求進行處理以後,也就是在 Controller
中的方法調用以後執行,可是它會在 DispatcherServlet
進行視圖返回渲染以前被調用,因此在這個方法中對 Controller
處理以後的 ModelAndView
對象進行操做。afterCompletion()
:也是須要當前對應的當前的 preHandle()
的返回值爲 true
時纔會執行。所以,該方法將在整個請求結束以後,也就是在 DispatcherServlet
渲染了對應的視圖以後執行,這個方法的主要做用是用於進行資源清理的工做。這裏以登陸攔截器做爲演示示例。當未登陸時是沒法直接訪問須要登陸權限的操做的,爲了作到這個效果,咱們使用登陸攔截器來判斷用戶是否登陸,若是用戶已登陸則放行讓用戶繼續操做,不然就將其跳轉到登陸頁。
建立 LoginInterceptor
攔截器類
public class LoginInterceptor implements HandlerInterceptor { public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception { User user = (User) httpServletRequest.getSession().getAttribute("user"); // 判斷用戶是否登陸 if (user == null) { // 用戶未登陸,重定向到登陸頁 httpServletResponse.sendRedirect("/login"); return false; } // 放行 return true; } public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception { // 若是請求來自登陸頁 if (modelAndView.getViewName().endsWith("login")) { // 則直接重定向到首頁再也不顯示登陸頁 httpServletResponse.sendRedirect("/main"); } } public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception { } }
攔截器定義後還須要在 spring-mvc.xml
文件中配置攔截器,代碼以下:
<!-- 攔截器配置,攔截順序:先執行後定義的,排在第一位的最後執行。--> <mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/**"/> <mvc:exclude-mapping path="/static/**"/> <mvc:exclude-mapping path="/login"/> <bean class="com.antoniopeng.springmvc.web.interceptor.LoginInterceptor"/> </mvc:interceptor> </mvc:interceptors>
相關配置說明:
mvc:interceptor
:定義一個攔截器
mvc:mapping
:映射路徑,須要攔截的請求路徑
mvc:exclude-mapping
:須要排除的請求路徑,好比登陸頁自己是不須要攔截的,這裏還包括了靜態資源路徑也是不須要攔截的
bean
:配置指定的攔截器對象
文章做者:彭超
版權聲明:本博客全部文章除特別聲明外,均採用 CC BY-NC-SA 4.0 許可協議。轉載請註明來自 彭超 | Blog!