一、簡介
Spring MVC是Spring框架中用于web應用開發的一個模塊,是Spring提供的一個基于MVC設計模式的優秀web開發框架,本質相當于是Servlet,Spring MVC作為控制器(Controller)來建立模型與視圖的數據交互。
Spring MVC框架采用松耦合可插拔的組件結構,具有高度可配置性,相對比其他MVC框架更具擴展性和靈活性。而且其本身就作為Spring框架的一部分,所以與Spring的整合更是無縫銜接。 在Spring MVC框架中,Controller替代Servlet來擔負控制器的職責,負責接收請求并調用相應的Model處理,處理器完成業務處理返回處理結果,再調用相應的View對處理結果進行渲染,最終傳送響應消息到客戶端。
二、工作原理解析
在整個SpringMVC框架中,處于核心地位的是前端控制器(DispatcherServlet),由它來接收所有的請求,并將具體工作委托給其他組件進行處理,負責協調組織不同組件完成請求處理并返回響應。
————————根據具體步驟來解析:
注:以下步驟都對應上圖的步驟,讀者可對照著學習,以下是具體的解釋
1. 首先用戶發送HTTP請求到web服務器,若匹配DispatcherServlet的請求映射路徑(在web.xml中指定),則web容器就將該請求轉交給DispatcherServlet處理。
2. 前端控制器DispatcherServlet根據請求信息(如URL、請求參數、HTTP方法等)及HandelerMapping的配置(在<servlet-name>-servlet.xml中配置)找到處理請求的處理器(Handler)。
3. 通過HandlerAdapter對Handler進行封裝,再以統一的適配器接口調用Handler。HandlerAdapter接口可以理解為具體使用Handler來干活的人。接口里只有3個方法,如下。supports(Object handler)方法:判斷是否可以使用某個Handler。
handler方法:具體使用Handler處理請求。
getLastModified方法:獲取資源的Last-Modified。4. 在請求信息到達真正調用Handler的處理方法之前,Spring MVC還會完成許多工作,它會將請求信息以一定方式轉換并綁定到請求方法的入參中,對于入參的對象會進行數據轉換、數據格式化和數據校驗等操作。當這些做完之后才真正調用Handler的處理方法進行相應的業務邏輯處理,處理器完成業務處理后返回一個ModelAndView對象給DispatcherServlet,ModelAndView對象包含了邏輯視圖名和模型數據信息。
5. ModelAndView對象中包含的“邏輯視圖名”并不是真正的視圖對象,DispatcherServlet會通過一個叫ViewResolver將邏輯視圖名解析成真正的視圖對象View。注:Spring MVC 可靈活配置數據顯示的視圖是JSP還是其他模板語言如velocity。
6. 當得到真實的視圖對象View后,DispatcherServlet會使用ModelAndView對象中的模型數據對View進行數據渲染。
7. 最終客戶端獲得響應消息。
————————至此運行原理解析,大功告成。
Spring MVC 特點:
- 清晰的角色劃分,從Model、Controller、View這三方面各司其職。
- 靈活的配置功能,因為Spring的核心是IoC,所以Spring MVC也可以把各種類當做Bean來通過XML進行配置。
- 提供了大量的控制器接口和實現類。
- 真正做到了View層的實現無關,完全可以根據需求使用velocity或者jsp技術開發。
- 國際化支持和面向接口編程
三、小Demo起步
1、創建一個maven工程,springMVC主要需要spring-webmvc
和spring-web
這2個jar包。
2、配置web.xml,主要是加載配置DispatcherServlet前端控制器
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<display-name>Archetype Created Web Application</display-name>
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--通過設置contextConfigLocation來指定springMVC的配置文件-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc-cfg.xml</param-value>
</init-param>
<!--表示容器一旦啟動就加載此DispatcherServlet-->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
3、配置springmvc-cfg.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/tx
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!--包掃描,實現注解驅動bean定義,同時將bean自動注入容器中使用-->
<context:component-scan base-package="com.xiaojiang.controller"/>
<!--該配置會自動注冊處理器映射和處理器適配器這兩個bean,springMVC需要這兩個bean來完成對@Controller和@RequestMapping等注解的支持-->
<mvc:annotation-driven/>
<!--配置視圖解析器,注意前綴和后綴最后拼接起來的完整路徑有無錯誤,尤其是/和少了上一級文件夾-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/views/"/>
<property name="suffix" value=".jsp"/>
</bean>
</beans>
4、編寫控制器來處理請求
/**
* FileName: IndexController
* Author: 小江
* Date: 2019/3/21 11:56
* History:
*/
package com.xiaojiang.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;
@Controller
@RequestMapping("/test")
public class IndexController {
//入門
@RequestMapping("/index")
public String index(){
return "index";
}
//傳參,控制器傳給視圖參數,注意參數名都要一致,否則注入不進去值
@RequestMapping("/send")
public ModelAndView sendParam(String username){
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("username",username);
modelAndView.setViewName("index");
return modelAndView;
}
//傳參,視圖傳給控制器參數
@RequestMapping("/welcome")
public String welcome(@RequestParam(value="user",required=false) String user){
System.out.println("視圖傳給控制器的參數:"+user);
return "welcome";
}
}
5、最后在自己編寫對應想要的jsp頁面去顯示信息就好了,起步完畢。
傳參可通過ModelAndView和Model方式來傳參,ModelAndView通過addObject(key,value)這個方法傳參,Model通過addAttribute(key,value)這個方法傳參。