什麼是SpringMVC?
一般剛開始學習一個框架的時候,肯定都會這麼問,首先上一張老圖。
Spring web mvc和Struts2都屬於表現層的框架,它是Spring框架的一部分,我們可以從Spring的整體結構中看得出來。
SpringMVC是一個基於MVC的web框架
既然提到了mvc這種開發設計模式,那麼我們就看看在b/s系統下,mvc模式的應用情況:
1、 用戶發起request請求至控制器(Controller)
控制接收用戶請求的數據,委託給模型進行處理
2、 控制器通過模型(Model)處理數據並得到處理結果
模型通常是指業務邏輯
3、 模型處理結果返回給控制器
4、 控制器將模型數據在視圖(View)中展示
web中模型無法將數據直接在視圖上顯示,需要通過控制器完成。如果在C/S應用中模型是可以將數據在視圖中展示的。
5、 控制器將視圖response響應給用戶
通過視圖展示給用戶要的數據或處理結果。
SpringMVC架構圖
架構流程:
第一步:發起請求到前端控制器(DispatcherServlet)
第二步:前端控制器請求HandlerMapping查找 Handler
可以根據xml配置、註解進行查找
第三步:處理器映射器HandlerMapping向前端控制器返回Handler
第四步:前端控制器調用處理器適配器去執行Handler
第五步:處理器適配器去執行Handler
第六步:Handler執行完成給適配器返回ModelAndView
第七步:處理器適配器向前端控制器返回ModelAndView
ModelAndView是springmvc框架的一個底層對象,包括 Model和view
第八步:前端控制器請求視圖解析器去進行視圖解析
根據邏輯視圖名解析成真正的視圖(jsp)
第九步:視圖解析器向前端控制器返回View
第十步:前端控制器進行視圖渲染
視圖渲染將模型數據(在ModelAndView對象中)填充到request域
第十一步:前端控制器向用戶響應結果
組件介紹:
1、前端控制器DispatcherServlet(不需要程序員開發)
作用接收請求,響應結果,相當於轉發器,中央處理器。
有了DispatcherServlet減少了其它組件之間的耦合度。
2、處理器映射器HandlerMapping(不需要程序員開發)
作用:根據請求的url查找Handler
3、處理器適配器HandlerAdapter
作用:按照特定規則(HandlerAdapter要求的規則)去執行Handler
4、處理器Handler(需要程序員開發)
注意:編寫Handler時按照HandlerAdapter的要求去做,這樣適配器纔可以去正確執行Handler
5、視圖解析器View resolver(不需要程序員開發)
作用:進行視圖解析,根據邏輯視圖名解析成真正的視圖(view)
6、視圖View(需要程序員開發jsp)
View是一個接口,實現類支持不同的View類型(jsp、freemarker、pdf...)
入門程序:
需求:實現之前mybatis學習中的商品列表查詢
環境準備:數據庫mysql5.1,mybatis學習中的四張表,jdk1.7.0_72,springmvc3.2,spring3.2(一定包括spring-webmvc-3.2.0.RELEASE.jar)
1,首先在web.xml 中配置前端控制器
<!--springmvc前端控制器 -->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--contextConfigLocation配置springmvc加載的配置文件(配置處理器映射器,適配器等等,如果不配置contextConfigLocation,默認加載的是/WEB-INF/servlet名稱=servlet.xml(springmvc-servlet.xml)) -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<!--有三種配置方式:
第一種:*.action,訪問以.action結尾 由DispatcherServlet進行解析
第二種:/,所以訪問的地址都由DispatcherServlet進行解析,對於靜態文件的解析需要配置不讓DispatcherServlet進行解析使用此種方式可以實現 RESTful風格的url
第三種:/*,這樣配置不對,使用這種配置,最終要轉發到一個jsp頁面時, 仍然會由DispatcherServlet解析jsp地址,不能根據jsp頁面找到handler,會報錯。 -->
<url-pattern>*.action</url-pattern>
</servlet-mapping>
2,在classpath下創建springmvc.xml文件
根據上面的springmvc架構圖可以發現,我們需要在springmvc.xml配置文件中配置:1,處理器映射器(根據請求的URL找到對應的Handler),2處理器適配器(根據對應的規則去執行相應的Handler),3,視圖解析器(進行視圖解析)
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.2.xsd ">
<!-- 配置適配器和映射器 -->
<mvc:annotation-driven></mvc:annotation-driven>
<!--可以掃描controller,service 這裏讓掃描controller 配置組件掃描controller -->
<context:component-scan base-package="com.travelsky.cn.ssm.controller"></context:component-scan>
<!-- 配置解析JSP的視圖解析器 prefix和suffix查找視圖頁面的前綴和後綴,最終視圖地址爲:前綴+邏輯視圖名+後綴 邏輯視圖需要在Controller中返回ModelAndView指定,比如邏輯視圖名爲hello,則最終返回的jsp視圖地址爲:"jsp/items/hello.jsp"-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!--前綴 -->
<property name="prefix" value="/jsp/items/"/>
<!--後綴 -->
<property name="suffix" value=".jsp"/>
</bean>
</beans>
3,創建/WEB-INF/jsp/itemsList.jsp視圖頁面:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>查詢商品列表</title>
</head>
<body>
商品列表:
<table width="100%" border=1>
<tr>
<td>商品名稱</td>
<td>商品價格</td>
<td>商品描述</td>
</tr>
<c:forEach items="${itemsList }" var="item">
<tr>
<td>${item.name }</td>
<td>${item.price }</td>
<td>${item.detail }</td>
</tr>
</c:forEach>
</table>
</body>
</html>
4,開發Handler
使用註解的映射器和註解的適配器。(註解的映射器和註解的適配器必須配對使用)
//使用Controller標識 它是一個控制器
@Controller
public class ItemsController3 {
//商品查詢列表
//@RequestMapping實現 對queryItems方法和url進行映射,一個方法對應一個url
//一般建議將url和方法寫成一樣
@RequestMapping("/queryItems")
public ModelAndView queryItems()throws Exception{
//調用service查找 數據庫,查詢商品列表,這裏使用靜態數據模擬
List<Items> itemsList = new ArrayList<Items>();
//向list中填充靜態數據
Items items_1 = new Items();
items_1.setName("聯想筆記本");
items_1.setPrice(6000f);
items_1.setDetail("ThinkPad T430 聯想筆記本電腦!");
Items items_2 = new Items();
items_2.setName("蘋果手機");
items_2.setPrice(5000f);
items_2.setDetail("iphone6蘋果手機!");
itemsList.add(items_1);
itemsList.add(items_2);
//返回ModelAndView
ModelAndView modelAndView = new ModelAndView();
//相當 於request的setAttribut,在jsp頁面中通過itemsList取數據
modelAndView.addObject("itemsList", itemsList);
//指定視圖
modelAndView.setViewName("/WEB-INF/jsp/items/itemsList.jsp");
return modelAndView;
}
5,部署調試
通過請求http://localhost:8080/springmvc/queryItems.action如果頁面展示出了商品列表,則表明入門程序運行成功!
源碼分析:
通過前端控制器源碼分析springmvc的執行過程
第一步:前端控制器接收請求
調用doDiapatch
第二步:
1. DispatherServlet調用HandlerMapping(處理器映射器)根據url查找Handler
第三步:DispatherServlet調用HandlerAdapter(處理器適配器)對HandlerMapping找到Handler進行包裝、執行。HandlerAdapter執行Handler完成後,返回了一個ModleAndView(springmvc封裝對象)
DispatherServlet 找一個合適的適配器:
適配器執行Hanlder
第四步:視圖渲染 DispatherServlet拿着ModelAndView調用ViewResolver(視圖解析器)進行視圖解析,解析完成後返回一個View(很多不同視圖類型的View)
視圖解析,得到view:
調用view的渲染方法,將model數據填充到request域
渲染方法: