SpringMVC实现原理及详解

1、什么是 SpringMVC ?

  在介绍什么是 SpringMVC 之前,我们先看看 Spring 的基本架构。如下图:

  我们可以看到,在 Spring 的基本架构中,红色圈起来的 Spring Web MVC ,也就是本系列的主角 SpringMVC,它是属于Spring基本架构里面的一个组成部分,属于SpringFrameWork的后续产品,已经融合在Spring Web Flow里面,所以我们在后期和 Spring 进行整合的时候,几乎不需要别的什么配置。

  SpringMVC 是类似于 Struts2 的一个 MVC 框架,在实际开发中,接收浏览器的请求响应,对数据进行处理,然后返回页面进行显示,但是上手难度却比 Struts2 简单多了。而且由于 Struts2 所暴露出来的安全问题,SpringMVC 已经成为了大多数企业优先选择的框架。

  那么多的不说,我们直接通过一个实例来看看 SpringMVC 的魔力。

2、创建 web 工程,并导入相应的 jar 包。

  这里我们加入了 Spring 3.2 的所有 jar 包,正好也佐证了上面所说的 SpringMVC 是 Spring 架构的一部分,注意:一定要包括红色椭圆圈起来的 spring-webmvc-3.2.0.RELEASE.jar

3、新建 SpringMVC 全局配置文件

  在 src 目录下新建 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: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/beanshttp://www.springframework.org/schema/beans/spring-beans-4.2.xsdhttp://www.springframework.org/schema/mvchttp://www.springframework.org/schema/mvc/spring-mvc-4.2.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop-4.2.xsdhttp://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx.xsd"></beans>

  4、在 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/javaeehttp://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"><display-name>SpringMVC_01</display-name><!-- 配置前端控制器DispatcherServlet --><servlet><servlet-name>springmvc</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>springmvc</servlet-name><url-pattern>*.do</url-pattern></servlet-mapping>
</web-app>

5、编写处理器 Handler

package com.ys.controller;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;public class HelloController implements Controller{@Overridepublic ModelAndView handleRequest(HttpServletRequest request,HttpServletResponse response) throws Exception {ModelAndView modelView = new ModelAndView();//类似于 request.setAttribute()modelView.addObject("name","张三");modelView.setViewName("/WEB-INF/view/index.jsp");return modelView;}}

6、在 springmvc.xml 文件中配置 Handler,处理器映射器,处理器适配器,以及视图解析器 

在 springmvc.xml 文件中添加如下代码:

<!-- 配置Handler -->   
<bean name="/hello.do" class="com.ys.controller.HelloController" /><!-- 配置处理器映射器将bean的name作为url进行查找,需要在配置Handler时指定bean name(就是url)-->
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping" /><!-- 配置处理器适配器,所有适配器都得实现 HandlerAdapter接口 --><bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter" /><!-- 配置视图解析器进行jsp解析,默认使用jstl标签,classpath下得有jstl的包-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" />

 7、在  /WEB-INF/view 目录下创建 index.jsp 文件

<%@ page language="java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%>
<!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>
hello:${name}
</body>
</html>

 8、在浏览器输入 http://localhost:8080/SpringMVC_01/hello.do

1、SpringMVC 详细介绍 

通过入门实例,我们大概知道 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)解析及文件上传等;提供了非常灵活的数据验证、格式化和数据绑定机制;提供了强大的约定大于配置(惯例优先原则)的契约式编程支持。

2、SpringMVC 处理请求流程

第一步:用户发送请求到前端控制器(DispatcherServlet)。

第二步:前端控制器请求 HandlerMapping 查找 Handler,可以根据 xml 配置、注解进行查找。

第三步: 处理器映射器 HandlerMapping 向前端控制器返回 Handler

第四步:前端控制器调用处理器适配器去执行 Handler

第五步:处理器适配器执行 Handler

第六步:Handler 执行完成后给适配器返回 ModelAndView

第七步:处理器适配器向前端控制器返回 ModelAndView

    ModelAndView 是SpringMVC 框架的一个底层对象,包括 Model 和 View

第八步:前端控制器请求试图解析器去进行视图解析

    根据逻辑视图名来解析真正的视图。

第九步:试图解析器向前端控制器返回 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页面的编写。可能你还对诸如前端控制器、处理器映射器等等名词不太理解,那么接下来我们对其进行详细的介绍。

3、配置前端控制器 

在 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/javaeehttp://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"><display-name>SpringMVC_01</display-name><!-- 配置前端控制器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--><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,从而报错!!!--><url-pattern>*.do</url-pattern></servlet-mapping>
</web-app>

4、配置处理器适配器

在 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" />

5、编写 Handler

  在 springmvc.xml 文件中配置。通俗来讲,就是请求的 URL 到我们这里所编写的 Handler 类的某个方法进行一些业务逻辑处理。

  我们在上面讲解了两个处理器适配器来约束 Handler,那么我们就通过上面两种配置分别编写两个 Handler

第一种:实现Controller 接口

package com.ys.controller;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;public class HelloController implements Controller{@Overridepublic ModelAndView handleRequest(HttpServletRequest request,HttpServletResponse response) throws Exception {ModelAndView modelView = new ModelAndView();//类似于 request.setAttribute()modelView.addObject("name","张三");modelView.setViewName("/WEB-INF/view/index.jsp");return modelView;}}

第二种:实现 HttpRequestHandler 接口

package com.ys.controller;import java.io.IOException;import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;import org.springframework.web.HttpRequestHandler;public class HelloController2 implements HttpRequestHandler{@Overridepublic void handleRequest(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {request.setAttribute("name", "张三");request.getRequestDispatcher("/WEB-INF/view/index.jsp").forward(request, response);}}

总结:通常我们使用第一种方式来编写 Handler ,但是第二种没有返回值,我们可以通过 response 修改相应内容,比如返回 json 数据。

所以具体使用哪一种根据实际情况来判断。

5、配置处理器映射器 

 在 springmvc.xml 文件中配置。通俗来讲就是请求的 URL 怎么能被 SpringMVC 识别,从而去执行我们上一步所编写好的 Handler

   第一种方法:

<!-- 配置Handler -->   
<bean name="/hello.do" class="com.ys.controller.HelloController2" /><!-- 配置处理器映射器将bean的name作为url进行查找,需要在配置Handler时指定bean name(就是url)-->
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping" />

这样配置的话,那么请求的 URL,必须为 http://localhost:8080/项目名/hello.do

  第二种方法:

<!-- 配置Handler -->   
<bean id="hello1" class="com.ys.controller.HelloController" />
<bean id="hello2" class="com.ys.controller.HelloController" />
<!-- 第二种方法:简单URL配置处理器映射器 -->
<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"><property name="mappings"><props><prop key="/hello1.do">hello1</prop><prop key="/hello2.do">hello2</prop></props></property>
</bean>

 这种配置请求的 URL可以为 http://localhost:8080/项目名/hello1.do,或者http://localhost:8080/项目名/hello2.do

 总结:上面两种处理器映射器配置可以并存,前端控制器会正确的去判断 url 用哪个 Handler 去处理。

6、配置视图解析器 

  第一种配置:

<!-- 配置视图解析器进行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/view"></property><!-- 返回页面的后缀 --><property name="suffix" value=".jsp"></property></bean>

如果这样配,那么在 Handler 中只需要返回在 view 文件夹下的jsp 页面名就可以了。

7、DispatcherServlet.properties

上面我们讲解了各种配置,可能有人会问这么多配置,万一少配置了一样,那不就不能运行了,那我们能不能不配置呢?答案是肯定的,SpringMVC 给我们提供了一个 DispatcherServlet.properties 文件。系统会首先加载这里面的配置,如果我们没有配置,那么就默认使用这个文件的配置;如果我们配置了,那么就优先使用我们手动配置的。

  在 SpringMVC 运行之前,会首先加载 DispatcherServlet.properties 文件里面的内容,那么我们来看看这里面都是什么。

# Default implementation classes for DispatcherServlet's strategy interfaces.
# Used as fallback when no matching beans are found in the DispatcherServlet context.
# Not meant to be customized by application developers.org.springframework.web.servlet.LocaleResolver=org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolverorg.springframework.web.servlet.ThemeResolver=org.springframework.web.servlet.theme.FixedThemeResolverorg.springframework.web.servlet.HandlerMapping=org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping,\org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMappingorg.springframework.web.servlet.HandlerAdapter=org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter,\org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter,\org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapterorg.springframework.web.servlet.HandlerExceptionResolver=org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerExceptionResolver,\org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver,\org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolverorg.springframework.web.servlet.RequestToViewNameTranslator=org.springframework.web.servlet.view.DefaultRequestToViewNameTranslatororg.springframework.web.servlet.ViewResolver=org.springframework.web.servlet.view.InternalResourceViewResolverorg.springframework.web.servlet.FlashMapManager=org.springframework.web.servlet.support.SessionFlashMapManager

  我们可以从上面得出,如果我们不手动进行各种配置,那么也有会默认的

  ①、处理器适配器默认:org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter

  ②、处理器映射器默认:org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping

  ③、视图解析器默认:org.springframework.web.servlet.view.InternalResourceViewResolver

  项目结构为:

1、在 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/javaeehttp://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"><display-name>SpringMVC_01</display-name><!-- 配置前端控制器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--><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,从而报错!!!--><url-pattern>/</url-pattern></servlet-mapping>
</web-app>

2、在 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: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/beanshttp://www.springframework.org/schema/beans/spring-beans-4.2.xsdhttp://www.springframework.org/schema/mvchttp://www.springframework.org/schema/mvc/spring-mvc-4.2.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop-4.2.xsdhttp://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx.xsd"><!--注解处理器映射器  -->   <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"></bean><!--注解处理器适配器  -->   <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"></bean>  <!--使用mvc:annotation-driven可以代替上面的映射器和适配器这里面会默认加载很多参数绑定方法,比如json转换解析器就默认加载,所以优先使用下面的配置--><!-- <mvc:annotation-driven></mvc:annotation-driven> --><!--单个配置Handler  --><!-- <bean class="com.ys.controller.HelloController"></bean> --><!--批量配置Handler,指定扫描的包全称  --><context:component-scan base-package="com.ys.controller"></context:component-scan><!--配置视图解析器  --><bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"><!-- 返回视图页面的前缀 --><property name="prefix" value="/WEB-INF/view/"></property><!-- 返回页面的后缀 --><property name="suffix" value=".jsp"></property></bean>
</beans>

3、编写 Handler 

package com.ys.controller;import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;//使用@Controller注解表示这个类是一个Handler
@Controller
public class HelloController {//@RequestMapping注解括号里面的表示访问的URL@RequestMapping("hello")public ModelAndView hello(){ModelAndView modelView = new ModelAndView();//类似于 request.setAttribute()modelView.addObject("name","张三");//配置返回的视图名,由于我们在springmvc.xml中配置了前缀和后缀,这里直接写视图名就好modelView.setViewName("index");//modelView.setViewName("/WEB-INF/view/index.jsp");return modelView;}}

  注意@Controller注解和@RequestMapping注解的用法

4、编写 视图 index.jsp 

<%@ page language="java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%>
<!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>
hello:${name}
</body>
</html>

1、Spring mvc介绍

SpringMVC框架是以请求为驱动,围绕Servlet设计,将请求发给控制器,然后通过模型对象,分派器来展示请求结果视图。其中核心类是DispatcherServlet,它是一个Servlet,顶层是实现的Servlet接口。

2、SpringMVC使用

需要在web.xml中配置DispatcherServlet。并且需要配置spring监听器ContextLoaderListener

<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 如果不设置init-param标签,则必须在/WEB-INF/下创建xxx-servlet.xml文件,其中xxx是servlet-name中配置的名称。 -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/springmvc-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
3、SpringMVC运行原理

如图所示:

 

 

流程说明:

(1)客户端(浏览器)发送请求,直接请求到DispatcherServlet。

(2)DispatcherServlet根据请求信息调用HandlerMapping,解析请求对应的Handler。

(3)解析到对应的Handler后,开始由HandlerAdapter适配器处理。

(4)HandlerAdapter会根据Handler来调用真正的处理器开处理请求,并处理相应的业务逻辑。

(5)处理器处理完业务后,会返回一个ModelAndView对象,Model是返回的数据对象,View是个逻辑上的View。

(6)ViewResolver会根据逻辑View查找实际的View。

(7)DispaterServlet把返回的Model传给View。

(8)通过View返回给请求者(浏览器)

4、DispatcherServlet详细解析

首先看下源码:

package org.springframework.web.servlet;

@SuppressWarnings("serial")
public class DispatcherServlet extends FrameworkServlet {

public static final String MULTIPART_RESOLVER_BEAN_NAME = "multipartResolver";
public static final String LOCALE_RESOLVER_BEAN_NAME = "localeResolver";
public static final String THEME_RESOLVER_BEAN_NAME = "themeResolver";
public static final String HANDLER_MAPPING_BEAN_NAME = "handlerMapping";
public static final String HANDLER_ADAPTER_BEAN_NAME = "handlerAdapter";
public static final String HANDLER_EXCEPTION_RESOLVER_BEAN_NAME = "handlerExceptionResolver";
public static final String REQUEST_TO_VIEW_NAME_TRANSLATOR_BEAN_NAME = "viewNameTranslator";
public static final String VIEW_RESOLVER_BEAN_NAME = "viewResolver";
public static final String FLASH_MAP_MANAGER_BEAN_NAME = "flashMapManager";
public static final String WEB_APPLICATION_CONTEXT_ATTRIBUTE = DispatcherServlet.class.getName() + ".CONTEXT";
public static final String LOCALE_RESOLVER_ATTRIBUTE = DispatcherServlet.class.getName() + ".LOCALE_RESOLVER";
public static final String THEME_RESOLVER_ATTRIBUTE = DispatcherServlet.class.getName() + ".THEME_RESOLVER";
public static final String THEME_SOURCE_ATTRIBUTE = DispatcherServlet.class.getName() + ".THEME_SOURCE";
public static final String INPUT_FLASH_MAP_ATTRIBUTE = DispatcherServlet.class.getName() + ".INPUT_FLASH_MAP";
public static final String OUTPUT_FLASH_MAP_ATTRIBUTE = DispatcherServlet.class.getName() + ".OUTPUT_FLASH_MAP";
public static final String FLASH_MAP_MANAGER_ATTRIBUTE = DispatcherServlet.class.getName() + ".FLASH_MAP_MANAGER";
public static final String EXCEPTION_ATTRIBUTE = DispatcherServlet.class.getName() + ".EXCEPTION";
public static final String PAGE_NOT_FOUND_LOG_CATEGORY = "org.springframework.web.servlet.PageNotFound";
private static final String DEFAULT_STRATEGIES_PATH = "DispatcherServlet.properties";
protected static final Log pageNotFoundLogger = LogFactory.getLog(PAGE_NOT_FOUND_LOG_CATEGORY);
private static final Properties defaultStrategies;
static {
try {
ClassPathResource resource = new ClassPathResource(DEFAULT_STRATEGIES_PATH, DispatcherServlet.class);
defaultStrategies = PropertiesLoaderUtils.loadProperties(resource);
}
catch (IOException ex) {
throw new IllegalStateException("Could not load 'DispatcherServlet.properties': " + ex.getMessage());
}
}

/** Detect all HandlerMappings or just expect "handlerMapping" bean? */
private boolean detectAllHandlerMappings = true;

/** Detect all HandlerAdapters or just expect "handlerAdapter" bean? */
private boolean detectAllHandlerAdapters = true;

/** Detect all HandlerExceptionResolvers or just expect "handlerExceptionResolver" bean? */
private boolean detectAllHandlerExceptionResolvers = true;

/** Detect all ViewResolvers or just expect "viewResolver" bean? */
private boolean detectAllViewResolvers = true;

/** Throw a NoHandlerFoundException if no Handler was found to process this request? **/
private boolean throwExceptionIfNoHandlerFound = false;

/** Perform cleanup of request attributes after include request? */
private boolean cleanupAfterInclude = true;

/** MultipartResolver used by this servlet */
private MultipartResolver multipartResolver;

/** LocaleResolver used by this servlet */
private LocaleResolver localeResolver;

/** ThemeResolver used by this servlet */
private ThemeResolver themeResolver;

/** List of HandlerMappings used by this servlet */
private List<HandlerMapping> handlerMappings;

/** List of HandlerAdapters used by this servlet */
private List<HandlerAdapter> handlerAdapters;

/** List of HandlerExceptionResolvers used by this servlet */
private List<HandlerExceptionResolver> handlerExceptionResolvers;

/** RequestToViewNameTranslator used by this servlet */
private RequestToViewNameTranslator viewNameTranslator;

private FlashMapManager flashMapManager;

/** List of ViewResolvers used by this servlet */
private List<ViewResolver> viewResolvers;

public DispatcherServlet() {
super();
}

public DispatcherServlet(WebApplicationContext webApplicationContext) {
super(webApplicationContext);
}

@Override
protected void onRefresh(ApplicationContext context) {
initStrategies(context);
}

protected void initStrategies(ApplicationContext context) {
initMultipartResolver(context);
initLocaleResolver(context);
initThemeResolver(context);
initHandlerMappings(context);
initHandlerAdapters(context);
initHandlerExceptionResolvers(context);
initRequestToViewNameTranslator(context);
initViewResolvers(context);
initFlashMapManager(context);
}
}
DispatcherServlet类中的属性beans:

HandlerMapping:用于handlers映射请求和一系列的对于拦截器的前处理和后处理,大部分用@Controller注解。

HandlerAdapter:帮助DispatcherServlet处理映射请求处理程序的适配器,而不用考虑实际调用的是 哪个处理程序。

HandlerExceptionResolver:处理映射异常。

ViewResolver:根据实际配置解析实际的View类型。

LocaleResolver:解决客户正在使用的区域设置以及可能的时区,以便能够提供国际化视野。

ThemeResolver:解决Web应用程序可以使用的主题,例如提供个性化布局。

MultipartResolver:解析多部分请求,以支持从HTML表单上传文件。

FlashMapManager:存储并检索可用于将一个请求属性传递到另一个请求的input和output的FlashMap,通常用于重定向。

在Web MVC框架中,每个DispatcherServlet都拥自己的WebApplicationContext,它继承了ApplicationContext。WebApplicationContext包含了其上下文和Servlet实例之间共享的所有的基础框架beans。

HandlerMapping:


HandlerMapping接口处理请求的映射

HandlerMapping接口的实现类:

SimpleUrlHandlerMapping类通过配置文件把URL映射到Controller类。

DefaultAnnotationHandlerMapping类通过注解把URL映射到Controller类。

HandlerAdapter:


HandlerAdapter接口-处理请求映射

AnnotationMethodHandlerAdapter:通过注解,把请求URL映射到Controller类的方法上。

HandlerExceptionResolver:


HandlerExceptionResolver接口-异常处理接口

SimpleMappingExceptionResolver通过配置文件进行异常处理。

AnnotationMethodHandlerExceptionResolver:通过注解进行异常处理。

ViewResolver:


ViewResolver接口解析View视图。

UrlBasedViewResolver类 通过配置文件,把一个视图名交给到一个View来处理。

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/633479.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

被忽视的暗面:客户端应用漏洞挖掘之旅

被忽视的暗面&#xff1a;客户端应用漏洞挖掘之旅 前言 在2023年12月15日&#xff0c;我有幸参加了由“字节跳动安全中心”举办的“安全范儿”沙龙活动。作为“中孚信息元亨实验室”的一员&#xff0c;我被邀请分享名为“被忽视的暗面&#xff1a;客户端应用漏洞挖掘之旅”的…

unocss+iconify技术在vue项目中使用20000+的图标

安装依赖 npm i unocss iconify/json配置依赖 vue.config.js文件 uno.config.js文件 main.js文件 使用 <i class"i-fa:user"></i> <i class"i-fa:key"></i>class名是 i- 开头&#xff0c;跟库名:图标名&#xff0c;那都有什么库…

mysql函数group_concat()返回结果不全

目录 一、场景二、原因三、排查1、查看group_concat_max_len配置2、修改group_concat_max_len配置a) 如果不方便重启mysql&#xff0c;可以通过以下命令进行配置修改b) 修改mysql配置文件&#xff0c;永久生效 一、场景 mysql使用group_concat()函数拼接返回字段时&#xff0c…

《游戏-01_2D-开发》

首先利用安装好的Unity Hub创建一个unity 2D&#xff08;URP渲染管线&#xff09;项目 选择个人喜欢的操作格局&#xff08;这里采用2 by 3&#xff09; 在Project项目管理中将双栏改为单栏模式&#xff08;个人喜好&#xff09; 找到首选项&#xff08;Preferences&#xff09…

Docker(二)安装指南:主要介绍 Docker 在 Linux 、Windows 10 和 macOS 上的安装

作者主页&#xff1a; 正函数的个人主页 文章收录专栏&#xff1a; Docker 欢迎大家点赞 &#x1f44d; 收藏 ⭐ 加关注哦&#xff01; 安装 Docker Docker 分为 stable test 和 nightly 三个更新频道。 官方网站上有各种环境下的 安装指南&#xff0c;这里主要介绍 Docker 在…

CentOS 7安装 NVIDIA 独立显卡驱动(禁用nouveau)

1.禁用nouveau 安装nvidia显卡驱动首先需要禁用nouveau&#xff0c;不然会碰到冲突的问题&#xff0c;导致无法安装nvidia显卡驱动。 禁用步骤 1.使用su命令切换到root用户下: su root查看nouveau是否禁用 lsmod | grep nouveau如果像这样输出一堆信息&#xff0c;则表示没…

allegro画PCB如何倒板框圆弧角

对板框进行倒圆角:Manufacture-Drafting-Fillet 对板框进行倒圆角:Manufacture-Drafting-Fillet 上图中的25对应的就是弧度半径&#xff0c;默认单位是mil&#xff0c;也可以设置成mm 最后点击相邻的边框线就可以倒成圆弧角了。 效果如下图&#xff1a;

SD卡出现乱码文件怎么修复?

SD卡出现乱码文件的问题是用户在使用过程中经常会遇到的故障。这些乱码文件的出现&#xff0c;可能是由于多种原因引起的&#xff0c;例如文件系统损坏、病毒攻击、设备兼容性问题等。本文将深入分析SD卡出现乱码文件的背后原因&#xff0c;并提供相应的解决方案&#xff0c;帮…

Python数据分析案例36——基于神经网络的AQI多步预测(空气质量预测)

案例背景 不知道大家发现了没&#xff0c;现在的神经网络做时间序列的预测都是单步预测&#xff0c;即(需要使用X的t-n期到X的t-1期的数据去预测X的t期的数据)&#xff0c;这种预测只能预测一个点&#xff0c;我需要预测X的t1期的数据就没办法了&#xff0c;有的同学说可以把预…

C++设计模式(李建忠)笔记4(完结)

C设计模式&#xff08;李建忠&#xff09; 本文是学习笔记&#xff0c;如有侵权&#xff0c;请联系删除。 参考链接 Youtube: C设计模式 Gtihub源码与PPT&#xff1a;https://github.com/ZachL1/Bilibili-plus 豆瓣: 设计模式–可复用面向对象软件的基础 总结23种设计模式…

5-数组-矩阵置零

这是数组的第5篇算法&#xff0c;力扣链接。 给定一个 m x n 的矩阵&#xff0c;如果一个元素为 0 &#xff0c;则将其所在行和列的所有元素都设为 0 。请使用 原地 算法。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,1,1],[1,0,1],[1,1,1]] 输出&#xff1a;[[1,0,1],[0…

VMware 安装 CentOS7

目录 镜像下载VMware创建创建新的虚拟机直接自定义了选择镜像所在位置更改虚拟机的名称和存储位置&#xff08;尽量不要使用默认位置&#xff09;设置虚拟机的配置&#xff08;根据自己的情况而定&#xff09;设置虚拟机的内存&#xff08;根据自己情况而定&#xff09;设置网络…

浅谈2023-2024年中国人工智能计算力发展

2023年是人工智能发展的重要转折年&#xff0c;企业正加速从业务数字化迈向业务智能化。大模型和生成式人工智能的发展将引发计算范式之变、产业动量之变&#xff0c;以及算力服务格局之变。从感知智能到生成式智能&#xff0c;人工智能算力需求快速增长。大模型和生成式人工智…

投资有道:分析、交易与等待的艺术

投资过程可以分为分析、交易和等待三个阶段。在这三个阶段中&#xff0c;分析和交易是相互联系的&#xff0c;而等待则是连接这两端的关键。分析的核心在于具备商业理解力和概率思维&#xff0c;而交易的核心则在于掌握赔率和逆向思维。在这三个阶段中&#xff0c;等待是最难把…

机器视觉系统在汽车车轮毂检测上的应用

将机器视觉用于轮毂检测&#xff0c;可以利用图像分析的方法来测量轮毂特征尺寸、判断轮毂形状&#xff0c;并获取其位置坐标等信息&#xff0c;从而能够辨识流水生产线上的各种款式和型号的汽车轮毂。 市面上对汽车车轮毂具体检测要求如下 &#xff1a; 1.为了分辨流水线上…

ARM day5、day6 硬件编程

一、硬件 fs4412 sd卡 串口线 电源 二、根据原理图点灯 1、确定需求&#xff1a; 点灯&#xff08;亮 or 灭&#xff09; 2、查看原理图 2.1 外设原理图 devboard 查找LED2->CHG_COK(核心板) 2.2 核心板原理图 coreboard 查找CHG_COK->XEINT23/KP_ROW7/ALV_DBG…

golang面试题大全

go基础类 1、与其他语言相比&#xff0c;使用 Go 有什么好处&#xff1f; 与其他作为学术实验开始的语言不同&#xff0c; Go 代码的设计是务实的。每个功能和语法决策都旨在让程序员的生活更轻松。Golang 针对并发进行了优化&#xff0c;并且在规模上运行良好。由于单一的标…

蓝桥杯(C++ 矩形总面积 错误票据 分糖果1 三国游戏 分糖果2)

目录 一、矩形总面积 思路&#xff1a; 代码&#xff1a; 二、错误票据 思路&#xff1a; 代码&#xff1a; 三、分糖果1 思路&#xff1a; 代码&#xff1a; 四、三国游戏 思路&#xff1a; 代码&#xff1a; 五、分糖果2 思路&#xff1a; 代码&#xff1a;…

uniapp 微信小程序自带实时线上日志

找个位置建上js文件 var log wx.getRealtimeLogManager ? wx.getRealtimeLogManager() : nullmodule.exports {info() {if (!log) returnlog.info.apply(log, arguments)},warn() {if (!log) returnlog.warn.apply(log, arguments)}, error() {if (!log) returnlog.error.a…

2018年认证杯SPSSPRO杯数学建模C题(第二阶段)机械零件加工过程中的位置识别全过程文档及程序

2018年认证杯SPSSPRO杯数学建模 基于轮廓提取与图像配准的零件定位问题研究 C题 机械零件加工过程中的位置识别 原题再现&#xff1a; 在工业制造自动生产线中&#xff0c;在装夹、包装等工序中需要根据图像处理利用计算机自动智能识别零件位置&#xff0c;并由机械手将零件…