SpringMVC详细流程(一)
Spring Web MVC是一种基于Java的实现了Web MVC设计模式的请求驱动类型的轻量级Web框架,即使用了MVC架构模式的思想,将web层进行职责解耦,基于请求驱动指的就是使用请求-响应模型,框架的目的就是帮助我们简化开发,Spring Web MVC也是要简化我们日常Web开发的。
与之相反的是基于组件的、事件驱动的Web框架,如Tapestry、JSF等。
Spring Web MVC也是服务到工作者模式的实现,但进行可优化。前端控制器是DispatcherServlet;应用控制器其实拆为处理器映射器(Handler Mapping)进行处理器管理和视图解析器(View Resolver)进行视图管理;页面控制器/动作/处理器为Controller接口(仅包含ModelAndView handleRequest(request, response) 方法)的实现(也可以是任何的POJO类);支持本地化(Locale)解析、主题(Theme)解析及文件上传等;提供了非常灵活的数据验证、格式化和数据绑定机制;提供了强大的约定大于配置(惯例优先原则)的契约式编程支持。
SpringMVC在Web应用中充当控制层(Controller)的角色,对请求进行分发处理。
一、Spring请求流程
1. 整体流程
具体步骤:
- 首先用户发送请求到前端控制器,前端控制器根据请求信息(如 URL)来决定选择哪一个页面控制器进行处理并把请求委托给它,即以前的控制器的控制逻辑部分;图中的 1、2 步骤;
- 页面控制器接收到请求后,进行功能处理,首先需要收集和绑定请求参数到一个对象,这个对象在 Spring Web MVC 中叫命令对象,并进行验证,然后将命令对象委托给业务对象进行处理;处理完毕后返回一个 ModelAndView(模型数据和逻辑视图名);图中的 3、4、5 步骤;
- 前端控制器收回控制权,然后根据返回的逻辑视图名,选择相应的视图进行渲染,并把模型数据传入以便视图渲染;图中的步骤 6、7;
- 前端控制器再次收回控制权,将响应返回给用户,图中的步骤 8;至此整个结束。
2. 核心流程
具体步骤:
- 第一步:发起请求到前端控制器(DispatcherServlet)
- 第二步:前端控制器请求HandlerMapping查找 Handler (可以根据xml配置、注解进行查找)
- 第三步:处理器映射器HandlerMapping向前端控制器返回Handler,HandlerMapping会把请求映射为HandlerExecutionChain对象(包含一个Handler处理器(页面控制器)对象,多个HandlerInterceptor拦截器对象),通过这种策略模式,很容易添加新的映射策略
- 第四步:前端控制器调用处理器适配器去执行Handler
- 第五步:处理器适配器HandlerAdapter将会根据适配的结果去执行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) 视图解析器ViewResolver(不需要程序员开发)。
作用:进行视图解析,根据逻辑视图名解析成真正的视图(view)
(6) 视图View(需要程序员开发jsp)。
注意:View是一个接口,实现类支持不同的View类型(jsp、freemarker、pdf…)
ps:不需要程序员开发的,需要程序员自己做一下配置即可。
可以总结出:需要我们开发的工作只有处理器 Handler 的编写以及视图比如JSP页面的编写。可能你还对诸如前端控制器、处理器映射器等等名词不太理解,那么接下来我们对其进行详细的介绍。
二、SpringMVC组件配置或开发说明
根据前面所说,部分组件需要配置,部分组件需要程序员开发,接下来就介绍下如何配置和开发相关的组件。
1. 配置前端控制器(DispatcherServlet)
在web project的web.xml中配置:
<!-- 配置前端控制器DispatcherServlet -->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--springmvc.xml 是自己创建的SpringMVC全局配置文件,用contextConfigLocation作为参数名来加载
如果不配置 contextConfigLocation,那么默认加载的是/WEB-INF/servlet名称-servlet.xml,在这里也就是
springmvc-servlet.xml 参数多个值使用逗号隔开,如:a.xml,b.xml -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:springmvc.xml</param-value>
</init-param>
</servlet> <servlet-mapping>
<servlet-name>springmvc</servlet-name>
<!--第一种配置:*.do,还可以写*.action等等,表示以.do结尾的或者以.action结尾的URL都由前端控制器DispatcherServlet来解析
第二种配置:/,所有访问的 URL 都由DispatcherServlet来解析,但是这里最好配置静态文件不由DispatcherServlet来解析,需要对静态资源单独处理
错误配置:/*,注意这里是不能这样配置的,因为如果这样写,最后转发到 jsp 页面的时候,仍然会由DispatcherServlet进行解析, 而这时候会找不到对应的Handler,从而报404!!! -->
<url-pattern>*.do</url-pattern>
</servlet-mapping>
2. 配置处理器映射器(HandlerMapping)
在 springmvc.xml 文件中配置。通俗来讲就是请求的 URL 怎么能被 SpringMVC 识别,从而去执行我们编写好的 Handler。
(1) 第一种方法
<!-- 配置Handler -->
<bean name="/hello.do" class="com.asiainfo.spring.controller.HelloController" /> <!-- 配置处理器映射器 将bean的name作为url进行查找,需要在配置Handler时指定bean name(就是url)-->
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping" />
这样配置的话,那么请求的 URL,必须为 http://ip:port/项目名/hello.do
(2) 第二种方法
<!-- 配置Handler -->
<bean id="hello" class="com.asiainfo.spring.controller.HelloController" />
<bean id="hello2" class="com.asiainfo.spring.controller.HelloController2" />
<!-- 简单URL配置处理器映射器 -->
<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="/hello.do">hello</prop>
<prop key="/hello2.do">hello2</prop>
</props>
</property>
</bean>
这种配置请求的 URL可以为 http://ip:prot/项目名/hello.do,或者http://ip:port/项目名/hello2.do
注:上面两种处理器映射器配置可以并存,前端控制器会正确的去判断 url 用哪个 Handler 去处理。
3. 配置处理器适配器(HandlerAdapter)
在 springmvc.xml 文件中配置。用来约束我们所需要编码的 Handler类。
第一种配置:编写 Handler 时必须要实现 Controller,否则不能被适配器解析。
<!-- 配置处理器适配器,所有适配器都得实现 HandlerAdapter接口 -->
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter" />
第二种配置:编写 Handler 时必须要实现 HttpRequestHandler
<!-- 配置处理器适配器第二种方法,所有适配器都得实现 HandlerAdapter接口 ,这样配置所有Handler都必须实现 HttpRequestHandler接口-->
<bean class="org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter" />
4. 开发处理器(Handler,即我们的Controller)
在 springmvc.xml 文件中配置。通俗来讲,就是请求的 URL 到我们这里所编写的 Handler 类的某个方法进行一些业务逻辑处理。
我们在上面讲解了两个处理器适配器来约束 Handler,那么我们就通过上面两种配置分别编写两个 Handler:
(1) 第一种:实现Controller 接口
public class HelloController implements Controller { public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
ModelAndView modelView = new ModelAndView();
modelView.setViewName("/WEB-INF/jsp/index.jsp");
return modelView;
}
}
(2) 第二种:实现 HttpRequestHandler 接口
public class HelloController2 implements HttpRequestHandler {
public void handleRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setAttribute("name", "harvey");
request.getRequestDispatcher("/WEB-INF/jsp/index.jsp").forward(request, response);
}
}
通常我们使用第一种方式来编写 Handler ,但是第二种没有返回值,我们可以通过 response 修改相应内容,比如返回 json 数据:
response.setCharacterEncoding("utf-8");
response.setContentType("application/json;charset=utf-8");
response.getWriter().write("json字符串");
所以具体使用哪一种根据实际情况来判断。
5. 配置视图解析器(ViewResolver)
第一种配置:
<!-- 配置视图解析器 进行jsp解析,默认使用jstl标签,classpath下得有jstl的包-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" />
如果这样配,那么在 Handler 中返回的必须是路径+jsp页面名称+".jsp"
第二种配置:
<!--配置视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 返回视图页面的前缀 -->
<property name="prefix" value="/WEB-INF/jsp/"></property>
<!-- 返回页面的后缀 -->
<property name="suffix" value=".jsp"></property>
</bean>
如果这样配,那么在 Handler 中只需要返回在 jsp 文件夹下的jsp 页面名就可以了。
6. DispatcherServlet.properties
上面我们讲解了各种配置,可能有人会问这么多配置,万一少配置了一样,那不就不能运行了,那我们能不能不配置呢?答案是肯定的,SpringMVC 给我们提供了一个 DispatcherServlet.properties 文件。系统会首先加载这里面的配置,如果我们没有配置,那么就默认使用这个文件的配置;如果我们配置了,那么就优先使用我们手动配置的。
在 SpringMVC 运行之前,会首先加载 DispatcherServlet.properties 文件里面的内容
①、处理器适配器默认:org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter
②、处理器映射器默认:org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping
③、视图解析器默认:org.springframework.web.servlet.view.InternalResourceViewResolver
SpringMVC详细流程(一)的更多相关文章
- SpringMVC工作流程 --通透较详细
SpringMVC工作流程 SpringMVC工作流程 流程说明(重要): (1)客户端发送一个http请求给前端控制器(DispatcherServlet): (2)前端控制器(DispacherS ...
- springmvc执行流程详细介绍
1.什么是MVC MVC是Model View Controller的缩写,它是一个设计模式 2.springmvc执行流程详细介绍 第一步:发起请求到前端控制器(DispatcherServlet) ...
- SpringMVC 工作流程
版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/baidu_36697353/article/details/64444147 SpringMVC 工 ...
- SpringMVC执行流程及源码分析
SpringMVC流程及源码分析 前言 学了一遍SpringMVC以后,想着做一个总结,复习一下.复习写下面的总结的时候才发现,其实自己学的并不彻底.牢固.也没有学全,视频跟书本是要结合起来一起, ...
- iOS-申请邓白氏编码的超详细流程介绍
导读 11.22号要申请苹果公司开发者账号,所以当天下午申请了邓白氏编码,昨天邓白氏编码下来了,这里就做一下记录,分享给大家. 概览 11.22提交的邓白氏编码申请,11.28(礼拜一)华夏邓白氏发来 ...
- SpringMVC详细示例
一.SpringMVC基础入门,创建一个HelloWorld程序 0.框架结构 1.首先,导入SpringMVC需要的jar包. 2.添加Web.xml配置文件中关于springmvc的配置 < ...
- 巩固一下:SpringMVC详细示例实战教程
一.SpringMVC基础入门,创建一个HelloWorld程序 1.首先,导入SpringMVC需要的jar包. 2.添加Web.xml配置文件中关于SpringMVC的配置 1 2 3 4 5 6 ...
- 史上最全最强SpringMVC详细示例实战教程
一.SpringMVC基础入门,创建一个HelloWorld程序 1.首先,导入SpringMVC需要的jar包. 2.添加Web.xml配置文件中关于SpringMVC的配置 1 2 3 4 5 6 ...
- SpringMVC详细示例实战教程
一.SpringMVC基础入门,创建一个HelloWorld程序 1.首先,导入SpringMVC需要的jar包. 2.添加Web.xml配置文件中关于SpringMVC的配置 1 2 3 4 5 6 ...
随机推荐
- 超实用的Java web面试题
Java web面试题 1.Tomcat的优化经验 答:去掉对web.xml的监视,把jsp提前编辑成Servlet. 有富余物理内存的情况,加大tomcat使用的jvm的内存 2.HTTP请求的GE ...
- IDEA的@Override下面有红色波浪线怎么去掉
测试了 , 不会影响运行 ! 去掉红线 ! file - seting - java compiler - 把两个version都改成1.8 ! ( 因为我的jdk是1.8) file - pr ...
- <Matrix> 311 378
311. Sparse Matrix Multiplication 稀疏矩阵的计算.稀疏矩阵的特点是有大量的0,如果采用暴力算法则比然会有很多无意义的计算. C[ i ][ j ] += A[ i ] ...
- django执行源生的mysql语句
执行源生sql在python中我们可以借助pymysql模块来进行执行源生sql关于pymysql执行源生sql可以看我的另外一篇博文:pymysql应用 本篇博客只介绍django中执行的源生sql ...
- workbook数据相关操作
访问单个单元格 c = ws['A4'] #返回单元格A4,如果单元格不存在,则会自动创建 ws['A4'] = 4 #为单元格A4赋值为4 d = ws.cell(row=4, column=2, ...
- CentOS 7 firewalld详解,添加删除策略
一.CentOS7中firewall防火墙 修改防火墙配置文件之前,需要对之前防火墙[/etc/firewalld/zones/public.xml]做好备份 重启防火墙后,需要确认防火墙状态和防火墙 ...
- Linux常用命令之文件编辑命令vim
vi命令 vi命令是UNIX操作系统和类UNIX操作系统中最通用的全屏幕纯文本编辑器.Linux中的vi编辑器叫vim,它是vi的增强版(vi Improved),与vi编辑器完全兼容,而且实现了很多 ...
- Eclipse导入SpringBoot项目pom.xml第一行报错Unknown error
1.网上搜的都说是将SpringBoot2.1.5版本降级到SpringBoot2.1.4版本,感觉这治标不治本啊,以后想升级不是玩完了. 错误如下所示: 参考:https://ask.csdn.ne ...
- 2-How nginx processes a request
原文:http://nginx.org/en/docs/http/request_processing.html server_name directive 参考:http://nginx.org/e ...
- GO与PHP的AES交互,key长度问题
今天在使用go与php的AES加解密交互中,一直有个问题那就是在go中加密后,在php端始终都是无法解密,经过排查最后发现是加密key长度引起的问题, 这里简单记录下. go的AES使用的是第三方的库 ...