SpringMVC的架构流程
1. 用户请求到达前端控制器DispatcherServlet,DispatcherServlet将请求发送到处理器映射器
2. 处理器映射器HandlerMapping,根据请求url查询到具体的处理器handller以及拦截器,并返回会前端控制器
3. 前端控制器不是直接调用controller,而是请求处理器适配器执行处理器handler
4. 处理器handler将处理请求,并返回Modeview(视图名和数据),将ModelView送会给前端控制器
5. 前端控制器将ModelView发给视图解析器ViewResolver生成视图view,返回给前端控制器
6. 前端控制器渲染视图,返回给客户端
组件说明
* DispatcherServlet:前端控制器
是spring MVC的核心,将处理请求发送到各个组件。
* HandlerMapping:处理器映射器
处理器映射器的作用根据请求的URL找到对应的处理器
* Handler:处理器
具体对请求处理的地方,返回视图名和数据。
* HandlAdapter:处理器适配器
通过HandlerAdapter对处理器进行执行,这是适配器模式的应用,通过扩展适配器可以对更多类型的处理器进行执行。
* viewResolve:视图解析器
将处理结果ModelAndView ,生成View视图对象,并对视图渲染 将结果展示给用户
* 视图view
一般指的就是jsp页面,也有其他,比如freemarkerview
关于DispatcherServlet的说明
DispatcherServlet主要完成了两件事情
* 初始化Spring 的Web上下文容器,并且可能设置父容器的上下文
* 初始化Spring MVC的组件,如handlermapping,handleradaptor
注解映射器和适配器
1. 配置处理器映射器
注解式映射器对类中标记了@RequestMapping的方法进行映射,根据请求的url匹配到对应的@RequestMapping注解标记的方法。也就是注解@RequestMapping定义了请求URL到处理器的映射
匹配成功返回HandlerMethod对象给前端控制器。
SpringMVC.xml中配置如下:
<!-- 配置注解处理器映射器 --> <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"></bean>
2. 配置注解是处理器适配器
对@RequestMapping标记的方法的进行调用
<!-- 配置注解处理器适配器 --> <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"></bean>
3.注解驱动加载适配器和映射器
前面直接配置适配器和映射器比较麻烦,可以直接使用注解驱动,默认加载适配器和映射器替换。
<!-- 注解驱动 --> <mvc:annotation-driven></mvc:annotation-driven>
视图解析器配置
使用默认的视图解析器,可以在xml中配置视图解析器的属性,指定视图的前缀和后缀
<!-- 配置视图解析器 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/jsp"></property> <property name="suffix" value=".jsp"></property> </bean>
最后,返回的物理地址:前缀+视图名+后缀
控制器配置
用注解@Controller表示一个类是处理器,这个注解是基于@Component的,因而在xml中可以使用
元素<component-scan>将它实例化到容器内
@Target({java.lang.annotation.ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Component public @interface Controller { String value() default ""; }
<!-- 配置controller扫描包 --> <context:component-scan base-package="cn.bing.controller" />
最后,一个小案例实现一个简单的demo
package cn.bing.controller; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.List; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.ModelAndView; import cn.bing.pojo.Item; @Controller public class ItemController { @RequestMapping("/itemList.action") public ModelAndView itemList(){ SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd HH:mm:ss"); List<Item> list = new ArrayList<Item>(); list.add(new Item(1, "小米1", sdf.format(new Date()), "千元神机!")); list.add(new Item(2, "小米2", sdf.format(new Date()), "千元神机!")); list.add(new Item(3, "小米3", sdf.format(new Date()), "千元神机!")); list.add(new Item(4, "小米4", sdf.format(new Date()), "千元神机!")); list.add(new Item(5, "小米5", sdf.format(new Date()), "千元神机!")); ModelAndView mav = new ModelAndView(); mav.setViewName("itemList"); mav.addObject("list", list); return mav; } }
itemList.jsp
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> <%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <!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>Insert title here</title> </head> <body> <table cellpadding="0" border="1" cellspacing="0"> <c:if test="${not empty list }"> <c:forEach items="${list }" var="obj"> <tr> <td>${obj['id']}</td> <td>${obj.name }</td> <td>${obj.time }</td> <td>${obj.remark }</td> <td><a style="color: red;" href="">修改</a></td> </tr> </c:forEach> </c:if> </table> </body> </html>
web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> <display-name>goldSpringDemo</display-name> <servlet> <servlet-name>dispatcherServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:springMVC.xml</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>dispatcherServlet</servlet-name> <url-pattern>*.action</url-pattern> </servlet-mapping> </web-app>
注意到:url-pattern 可以配置为 *.do ,*.action这种拦截不包含jsp ,/*则是拦截所有,包括静态资源和页面
SpringMVC.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:p="http://www.springframework.org/schema/p" 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-4.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"> <!-- 配置controller扫描包 --> <context:component-scan base-package="cn.bing.controller" /> <!-- 注解驱动 --> <mvc:annotation-driven></mvc:annotation-driven> <!-- 配置视图解析器 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/jsp/"></property> <property name="suffix" value=".jsp"></property> </bean> </beans>