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>