SpringMVC_原理(转)
在整个Spring MVC框架中,DispatcherServlet处于核心位置,它负责协调和组织不同组件完成请求处理并返回响应的工作。具体流程为:
1)客户端发送http请求,web应用服务器接收到这个请求,如果匹配DispatcherServlet的映射路径(在web.xml中配置),web容器将请求转交给DispatcherServlet处理;
2)DispatcherServlet根据请求的信息及HandlerMapping的配置找到处理该请求的Controller;
3)Controller完成业务逻辑处理后,返回一个ModelAndView给DispatcherServlet;
4)DispatcherServlet借由ViewResolver完成ModelAndView中逻辑视图名到真实视图对象View的解析工作;
5)DispatcherServlet根据ModelAndView中的数据模型对View对象进行视图渲染,最终客户端得到的响应消息可能是一个普通的html页面,也可能是一个xml或json串,甚至是一张图片或一个PDF文档等不同的媒体形式。
Spring提供了DispatcherServlet,这个类不仅负责实现请求转发,还负责启动一个WebApplicationContext容器。 按照Spring一贯的IoC哲学,所有的Controller都是JavaBean,并由IoC容器统一管理。对于View,则采取了更灵活的处理方 式,Spring MVC允许使用不同的View实现,除了JSP外,还可以使用Velocity、Freemaker、XSLT等多种View技术。
总的来讲,要使用Spring MVC框架,需要以下步骤。
① 在web.xml中配置DispatcherServlet及URL映射。
② 编写IoC容器需要的XML配置文件,命名为<servlet-name>-servlet.xml,放到/WEB-INF目录下。例如,如果DispatcherServlet在web.xml中的配置名称为dispatcher,则Spring将寻找dispatcher- servlet.xml配置文件。
③ 在XML配置文件中定义URL映射方式和使用哪种View技术。
我们仍以SimpleMVC为基础,用Spring MVC框架来实现这个Web应用程序。在Eclipse中创建一个SpringMVC项目,结构如图7-21所示。
/web/WEB-INF/lib目录下的jstl.jar和standard.jar是JSP标准标签库,将在JSP视图中用到,/web/WEB-INF/c.tld是标签库的声明文件,稍后我们会在JSP视图文件中用到它们。
一、 配置DispatcherServlet
首先,在web.xml中配置DispatcherServlet,并将所有以“.html”结尾的URL全部映射到DispatcherServlet上,这样,用户仅从URL地址上无法得知服务器端后台使用了何种技术。
<?xml version="1.0" encoding="UTF-8"?>
<!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>
<!-- spring dispatch servlet -->
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</ servlet-class>
<load-on-startup>0</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>*.html</url-pattern>
</servlet-mapping>
<!-- 申明taglib,将在JSP中使用 -->
<taglib>
<taglib-uri>http://java.sun.com/jsp/jstl/core</taglib-uri>
<taglib-location>/WEB-INF/c.tld</taglib-location>
</taglib>
</web-app>
和普 通的Spring应用程序稍有不同,对于Web应用程序,Spring的ApplicationContext是由DispatcherServlet加 载的,它会在/WEB-INF/下查找一个名称为<servletName> -servlet.xml的XML配置文件来初始化Spring Web应用程序的ApplicationContext。对于上例,我们在web.xml中定义DispatcherServlet的名称为 dispatcher,因此,相应的XML配置文件就必须是/WEB-INF/dispatcher-servlet.xml。
下一步便是编写dispatcher-servlet.xml配置文件,首先定义URL的映射方式(HandlerMapping)。Spring提供了几种常用的HandlerMapping。
1.使用SimpleUrlHandlerMapping
SimpleUrlHandlerMapping提供了最简单的URL映射,通过Properties将URL和Controller对应起来,配置示例如下。
<bean id="simpleUrlHandlerMapping" class="org.springframework.web.servlet. handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="/a.html">controllerA</prop>
<prop key="/b.html">controllerB</prop>
</props>
</property>
</bean>
这种方式和Struts的配置类似。当用户请求一个URL时,Spring就在SimpleUrl HandlerMapping注入的Properties中查找对应的Controller。
2.使用BeanNameUrlHandlerMapping
BeanNameUrlHandlerMapping的实现更为简单,每个Controller的URL与其name属性对应,因此,只需要对每个Controller以URL作为name,就可以实现URL映射。配置示例如下。
<bean id="beanNameUrlHandlerMapping" class="org.springframework.web.servlet. handler.BeanNameHandlerMapping" />
<bean name="/a.html" class="example.chapter7.ControllerA" />
<bean name="/a.html" class="example.chapter7.ControllerB" />
之所以用Bean的name作为URL而不是id,是因为XML规范不允许在id标识中使用特殊字符“/”。当用户请求一个URL时,Spring将直接查找name为URL的Controller。
使用 SimpleUrlHandlerMapping的麻烦之处在于,添加或删除Controller时必须要对 SimpleUrlHandlerMapping做相应的修改,而BeanNameUrlHandlerMapping则无需手工编写映射,只需要在每个 Controller中仔细定义name属性。如果使用XDoclet自动生成配置文件,则可以将name在Controller的注释中定义,维护起来 更加方便。因此,我们推荐首先考虑使用BeanNameUrlHandlerMapping。事实上,如果没有在XML配置文件中定义任何 UrlHandlerMapping,则Spring MVC默认使用BeanNameUrlHandlerMapping。
Spring还提供了一个 ControllerClassNameHandlerMapping,它和BeanName UrlHandlerMapping类似,不过是将Controller的ClassName和对应的URL关联起来,由于这种方式灵活性欠佳,实际使用 较少。
也可以混合使用多种 UrlHandlerMapping,但是必须为每个UrlHandlerMapping指定order属性来表示优先级,order值越小优先级越高, Spring会先查询优先级高的UrlHandlerMapping。若找到了对应的Controller,就不再继续查询,否则,按照优先级依次查询, 直到找到为止。若所有的UrlHandlerMapping都无法返回一个合适的Controller,并且没有设置默认的Controller时,就会 返回给客户端一个“404 Not Found”错误,表示不存在这个URL。
下一步需要为Spring MVC指定一个ViewResolver(视图解析器),指示使用何种视图技术,以及如何解析ModelAndView返回的逻辑视图名称。
这里我们直接给出使用JSP视图的配置,对于其他的视图技术将会在后面讲到。
<bean id="viewResolver" class="org.springframework.web.servlet.view. InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet. view.JstlView" />
<property name="prefix" value="/" />
<property name="suffix" value=".jsp" />
</bean>
prefix和suffix将和逻辑视图名称一起组合成为实际视图的路径。例如,对于上例,若返回一个new ModelAndView("test", model),则实际的视图路径由prefix+逻辑视图名+suffix这3部分构成。
/test.jsp
定义 前缀(prefix)使得视图文件无论放在何处都可以通过修改前缀来实现位置无关性(当然,必须在web目录内),许多应用程序将其放在/WEB-INF 目录下,使得用户无法通过URL直接访问视图文件以保证视图文件的安全;定义后缀(suffix)可以在将来用另一种视图技术(例如,Velocity) 取代现在的JSP视图,只需将后缀从“.jsp”更改为“.vm”即可,而不必更改源代码中的逻辑视图名。总之,一切目标都是为了实现最大限度的解耦。
二、实现Controller
实现了org.springframework.web.servlet.mvc.Controller接口的Bean都可以作为有效的Controller来处理用户请求。例如,一个最简单的TestController。
public class TestController implements Controller {
public ModelAndView handleRequest(HttpServletRequest request, HttpServlet Response response) throws Exception {
String name = request.getParameter("name");
if(name==null)
name = "spring";
Map model = new HashMap();
model.put("name", name);
model.put("time", new Date());
return new ModelAndView("test", model);
}
}
注 意,上例的Controller接口和返回值ModelAndView都是在Spring框架中定义的,这和SimpleMVC项目中我们自己定义的 Controller接口和ModelAndView类所在的包是不同的。在SimpleMVC项目中,我们并没有使用Spring MVC,而是借用Spring MVC的概念自定义接口。在现在的SpringMVC项目中,我们没有自定义任何接口,而是直接使用Spring MVC框架来实现Web应用程序,这一点请读者务必区分清楚。
另外需要注意的是,ModelAndView返回的逻辑视图是“test”,还记得在viewResolver中定义的prefix和suffix吗?实际的视图名称由这3部分构成便是“/test.jsp”。
最后将这个TestController作为Bean定义在dispatcher-servlet.xml中,由于我们准备使用默认的BeanNameUrlHandlerMapping,因此,需要在Bean的name中指定URL。
<bean name="/test.html" class="example.chapter7.TestController" />
完整的dispatcher-servlet.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean name="/test.html" class="example.chapter7.TestController" />
<bean id="viewResolver" class="org.springframework.web.servlet.view. InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet. view.JstlView" />
<property name="prefix" value="/" />
<property name="suffix" value=".jsp" />
</bean>
</beans>
注意,我们没有指定UrlHandlerMapping,Spring会自动使用默认的BeanNameUrl HandlerMapping。
三、 实现View
到目前为止,我们已经编写了 Controller的实现和配置文件,最后一步是编写一个JSP文件作为视图。由于采用了MVC架构,视图的任务只有一个,就是将Controller 返回的Model渲染出来。Spring MVC会将Model中的所有数据全部绑定到HttpServlet Request中,然后将其转发给JSP,JSP只需将数据显示出来即可。
通过JSTL标签库能进一步简化显示逻辑,我们看看如何显示TestController返回的Model。test.jsp文件的内容如下。
<%@ page contentType="text/html; charset=utf-8" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jstl/core" %>
<html>
<head>
<title>SpringMVC</title>
</head>
<body>
<h3>Hello, <c:out value="${name}" />,
it is <c:out value="${time}" /></h3>
</body>
</html>
现在,Spring MVC所需的所有组件都已编写并配置完毕,我们先来回顾一下Spring MVC的处理流程,如图7-22所示。
将SpringMVC工程的编译输出目录设置为/web/WEB-INF/classes,然后编译工程,打开浏览器,测试我们编写的SpringMVC,结果如图7-23所示。
图7-23
现在,读者对Spring的MVC框架应该有了一个初步的认识。实际上,除了基本的MVC标准流程外,Spring MVC还提供了相当多的功能,下面我们将逐一介绍Spring MVC提供的各种丰富的Controller、拦截器和异常处理机制。
SpringMVC_原理(转)的更多相关文章
- SpringMVC_执行原理
什么是SpringMVC 概述 Spring MVC是Spring Framework的一部分,是基于Java实现MVC的轻量级Web框架. 查看官方文档:https://docs.spring.io ...
- 奇异值分解(SVD)原理与在降维中的应用
奇异值分解(Singular Value Decomposition,以下简称SVD)是在机器学习领域广泛应用的算法,它不光可以用于降维算法中的特征分解,还可以用于推荐系统,以及自然语言处理等领域.是 ...
- node.js学习(三)简单的node程序&&模块简单使用&&commonJS规范&&深入理解模块原理
一.一个简单的node程序 1.新建一个txt文件 2.修改后缀 修改之后会弹出这个,点击"是" 3.运行test.js 源文件 使用node.js运行之后的. 如果该路径下没有该 ...
- 线性判别分析LDA原理总结
在主成分分析(PCA)原理总结中,我们对降维算法PCA做了总结.这里我们就对另外一种经典的降维方法线性判别分析(Linear Discriminant Analysis, 以下简称LDA)做一个总结. ...
- [原] KVM 虚拟化原理探究(1)— overview
KVM 虚拟化原理探究- overview 标签(空格分隔): KVM 写在前面的话 本文不介绍kvm和qemu的基本安装操作,希望读者具有一定的KVM实践经验.同时希望借此系列博客,能够对KVM底层 ...
- H5单页面手势滑屏切换原理
H5单页面手势滑屏切换是采用HTML5 触摸事件(Touch) 和 CSS3动画(Transform,Transition)来实现的,效果图如下所示,本文简单说一下其实现原理和主要思路. 1.实现原理 ...
- .NET Core中间件的注册和管道的构建(1)---- 注册和构建原理
.NET Core中间件的注册和管道的构建(1)---- 注册和构建原理 0x00 问题的产生 管道是.NET Core中非常关键的一个概念,很多重要的组件都以中间件的形式存在,包括权限管理.会话管理 ...
- python自动化测试(2)-自动化基本技术原理
python自动化测试(2) 自动化基本技术原理 1 概述 在之前的文章里面提到过:做自动化的首要本领就是要会 透过现象看本质 ,落实到实际的IT工作中就是 透过界面看数据. 掌握上面的这样的本领 ...
- CRC、反码求和校验 原理分析
3月份开始从客户端转后台,算是幸运的进入全栈工程师的修炼阶段.这段时间一边是老项目的客户端加服务器两边的维护和交接,一边是新项目加加加班赶工,期间最长经历了连续工作三天只睡了四五个小时的煎熬,人生也算 ...
随机推荐
- Spring Initializr生成的demo测试404错误
体验Spring Initializr生成的spring boot工程,启动成功, 目录结构如下: 添加了一个简单的controller后,启动成功但访问报404错误: 原因: springboot默 ...
- npm与yarn命令
npm 1. 查看npm版本 node -v npm -v 2. 更新npm至最新版 npm install npm@latest -g 3. npm install:安装依赖 # 在本地node_m ...
- Linux下使用matlab在后台默默的运行.m文件(无界面形式)
Linux下使用matlab在后台默默的运行.m文件(无界面形式)本主在Ubuntu18.04LTS上已经安装了matlab直接运行Matlab$ matlab会启动 matlab,出现启动界面但想要 ...
- SQL Server 将数据导出为XML和Json
有时候需要一次性将SQL Server中的数据导出给其他部门的也许进行关联或分析,这种需求对于SSIS来说当然是非常简单,但很多时候仅仅需要一次性导出这些数据而建立一个SSIS包就显得小题大做,而SQ ...
- 使用 Redis 的 sorted set 实现用户排行榜
要求:实现一个用户排行榜,用户数量有很多,排行榜存储的是用户玩游戏的分数,对排行榜的读取压力比较大,如何实现? 思路分析: 实现排行榜,可以考虑使用 Redis 的 zset 结构: 用户数量很多的话 ...
- 个人GitHub资源分享仓库
个人GitHub资源分享仓库 门牌号:https://github.com/ZeroPhong/Learning-Resource 2019年10月27日 注册GitHub账号,仓库建立: 当天上 ...
- 女性对DeepNude脱衣技术的防护
写在前面的话 本文不提供下载方式,开源部分只是社区逆向后公开的部分源码 这篇文章有些人看了可能会比较极端,但不从技术角度分析又谈何防护?攻与防一直存在,不管是安全还是AI都是一样 你极端不极端,它就在 ...
- Spring-Boot之Admin服务监控-9
一.Spring Boot Admin用于管理和监控一个或者多个Spring Boot程序.Spring Boot Admin分为Server端和Client 端,Client端可以通过向Http S ...
- selenium浏览器自动化测试框架文档(修正版)
写在最前面:目前自动化测试并不属于新鲜的事物,或者说自动化测试的各种方法论已经层出不穷,但是,能够在项目中持之以恒的实践自动化测试的团队,却依旧不是非常多.有的团队知道怎么做,做的还不够好:有的团队还 ...
- 【BBED】bbed常用命令
[BBED]bbed常用命令 一.1 相关知识点扫盲 BBED(Oracle Block Browerand EDitor Tool),用来直接查看和修改数据文件数据的一个工具,是O ...