概述
首先SpringMVC 是一个MVC构架模式的web框架,是基于Servlet的,SpringMVC依然使用多线程同步并发的方式来处理请求,从测试数据来看异步并发效率的确更好,但是其并不成熟,盲目的进行重构可能会引发更多的问题, 并且异步编程在代码结构上会产生较大的变化。
构架图:

SpringMVC在系统的位置:

可以看出
SpringMVC 并没有代替Servlet,它只是在Servlet上提供了一套封装好的组件,提高开发效率;
还使得开发出的项目更加规范;否则每个人可能有每个人不同的MVC;
SpringMVC核心组件
用一个Servlet来处理多个请求甚至是所有请求,就需要实现能根据请求路径查找处理请求方法的逻辑,这也是SpringMVC要做的第一件事情;
DispatcherServlet:前端控制器
用户请求首先到达前端控制器,它就相当于mvc模式中的c,DispatcherServlet是整个流程控制的调度中心,由它调用其它组件处理用户的请求,DispatcherServlet的存在降低了组件之间的耦合性。
Handler:处理器
Handler是继DispatcherServlet前端控制器的后端控制器,DispatcherServlet会将请求发送至对应的Handler来进行处理。Handler是处理业务逻辑的地方,需要我们自己来编写具体代码,等同于之前的Service层
HandlerMapping:处理器映射器
HandlerMapping负责根据用户请求路径找到Handler,springmvc提供了不同的映射器实现不同的映射方式,例如:BeanName映射,配置文件映射,注解映射等。
HandlAdapter:处理器适配器
通过HandlerAdapter来执行Handler,因为Handler有不同形式,意味着调用方式是不同的,这是适配器模式的应用,我们也可以扩展适配器来实现新的Handler;
ViewResolver:视图解析器
ViewResolver负责从Handler中获取数据和视图,根据逻辑视名称查找物理视图文件,并查找View对象,再生成View对象;
View:视图
View的职责就是装配数据,SpringMVC框架提供了很多的View视图类型的支持,包括:jstlView、freemarkerView、pdfView等。常用视图就是jsp。我们需要根据业务需求,通过页面标签或页面模版技术将模型数据展示给用户
其他功能:
| 类型 | 说明 |
|---|---|
HandlerExceptionResolver | Handler异常处理器 |
LocaleResolver | 提供国际化的视图。根据不同地区显示不同内容 |
ThemeResolver | 根据不同地区提供个性化的布局 |
MultipartResolver | 解析multipart请求数据,如浏览器表单文件上传 |
FlashMapManager | 常用于通过重定向将属性从一个请求传递到另一个请求 |
请求处理流程图

使用方法
添加pom.xml依赖:
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!-- SpringMVC -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.2.RELEASE</version>
</dependency>
<!--JEE相关的-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>javax.servlet.jsp-api</artifactId>
<version>2.3.3</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
</dependencies>
在resources下创建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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
</beans>
配置web.xml
我们需要让SpringMVC随着web项目启动,SpringMVC的做法是利用DIspatcherServlet;
<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>
<!-- 应用启动时加载-->
<load-on-startup>0</load-on-startup>
</servlet>
<!-- 要交给SpringMVC处理的请求-->
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
DispatcherServlet做了两个事情,1:初始化一个Spring容器,2:注册一个Servlet
SpringMVC本质上也是一个Spring容器,在不涉及WEB时使用方法和Spring没有任何区别;
注:只有请求地址能够匹配到到被DispatcherServlet的url-pattern的请求才会被SpringMVC处理,那么那些请求要交给SpringMVC处理呢,通常是除静态资源以外的请求;
常用pattern:
| pattern | 说明 |
|---|---|
| /* | 代表拦截所有 |
| / | 代表拦截除.jsp除外所有 |
| *.action | 代表拦截.action后缀的 |
| *.do | 代表拦截.do后缀的 |
创建控制类
public class MyController implements Controller {
@Override
public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
ModelAndView modelAndView = new ModelAndView();//创建一个表示模型和视图的对象
modelAndView.setViewName("index.jsp");//设置视图名称
modelAndView.addObject("msg","hello springMVC");//添加视图需要的数据
return modelAndView; //返回模型和视图给dispatcherServlet
}
}
ModelAndView,其实就是把视图资源和数据打包到一起,然后视图名称交给视图解析器,Object放到请求中;
注册控制器
在springmvc.xml中注册:
<bean name="/myController" class="com.lbb.controller.MyController"/>
DispatcherServlet是按照请求路径来查找Handler,我们必须告诉SpringMVC,这个控制器是用来处理哪个请求地址的,默认情况下,SpringMVC会查找beanName与请求地址相同的Handler来处理;
测试
在界面中取值:
${mag}
地址栏输入:资源路径/myController,比如我的是:http://localhost:8080/SpringMVC/myController

我们在Request中添加了key为msg的字符内容hello SpringMVC
看到上述内容说明SpringMVC以及成功处理了请求;
注解配置controller
上述方法每个Controller只能处理一个请求地址,不够灵活,且需要Controller实现指定接口,这是就需要使用注解来配置Controller了;
@Controller
该注解写在类上,用于注册控制器bean到容器中,这是之前以及学习过的
@RequestMapping(“url”)
该注解写在方法上时,用于为方法指定要匹配的url,该url是相对根路径的
写在类上时类上的url是相对于根路径,而类中方法则相对于类的url
案例:
@Controller
public class MyController {
@RequestMapping("/testController")
public ModelAndView testController(){
ModelAndView modelAndView = new ModelAndView();//创建一个表示模型和视图的对象
modelAndView.setViewName("index.jsp");//设置视图名称
modelAndView.addObject("msg","hello springMVC");//添加视图需要的数据
return modelAndView; //返回模型和视图给dispatcherServlet
}
}
viewName路径若不带/时则从当前请求的位置查找文件,带/则表示从根路径查找
若@Controller后有@RequestMapping("/映射") 则此controller里面的方法的url都是基于此映射下的二级映射。
请求地址:http://localhost:8080/SpringMVC/testController
默认配置
SpringMVC提供了很多默认配置,使我们可以快速的开项目,而无需繁琐的配置,在SpringMVC的包下可以找到一个DispatcherServlet.properties配置,这便是默认的配置文件了;

具体如下:
HandlerMapping
| HandlerMapping | 映射方式 |
|---|---|
| BeanNameUrlHandlerMapping | 用beanName作为url |
| RequestMappingHandlerMapping | 使用注解配置url |
HandlerAdapter
| HandlerAdapter | 处理对象: |
|---|---|
| HttpRequestHandlerAdapter | 实现HttpRequestHandler的处理器 |
| SimpleControllerHandlerAdapter | 实现Controller的处理器 |
| RequestMappingHandlerAdapter | 使用注解的handler,无需实现接口 |
| SimpleServletHandlerAdapter | Servlet类Handler,需继承HttpServlet |
SimpleServletHandlerAdapter默认是没有的,当需要使用Servlet相关API时使用,需要在配置文件中声明
<bean class="org.springframework.web.servlet.handler.SimpleServletHandlerAdapter"/>
注意:当手动添加了适配器后,系统就不会自动添加任何其他适配器了;
SimpleServletHandlerAdapter案例:
@Controller("/servletController")
public class YouController extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.getWriter().println("servlet API");
}
}
在上述4中handler中最常用的是使用注解形式的;
视图解析器
视图解析器用于查找视图文件,及生成视图对象,我们不用过多关注,唯一会用到的就是,为视图名称配置前缀和后缀从而简化,Handler中的书写
在一个实际项目中页面文件可能比较多,可以用文件夹管理,但是这导致我们在编写视图名称时更加繁琐,例如:

这时就可在配置中对视图解析器进行相关设置;
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!--指定视图类型-->
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
<!--指定前缀-->
<property name="prefix" value="/pages/jsp/"/>
<!--指定后缀-->
<property name="suffix" value=".jsp"/>
</bean>
处理器中:
@RequestMapping("/testController")
public ModelAndView testController() {
ModelAndView modelAndView = new ModelAndView();//创建一个表示模型和视图的对象
modelAndView.setViewName("index");//设置视图名称
modelAndView.addObject("msg", "hello springMVC");//添加视图需要的数据
return modelAndView; //返回模型和视图给dispatcherServlet
}
视图解析器会自动在viewName前后分别拼接前缀和后缀;如:/pages/jsp/index.jsp
启用mvc配置
SpringMVC默认会加载DispatcherServlet.properties中的配置作为默认配置,当我们需要添加额外的自定义配置时该怎么办呢?这是我们需要启用MVC配置,通过在配置文件中添加以下标签
<mvc:annotation-driven/>
为了减少配置项,该标签向容器中添加了提供MVC基础服务的Bean,并添加了json,xml,的转换器
有兴趣可以源码位置:web包下的AnnotationDrivenBeanDefinitionParser,
此时看不出该标签对系统有什么影响,但在后续自定义验证器,转换器时就不得不使用到该标签了
连接:ssm整合

本文深入探讨SpringMVC框架的工作原理,包括其架构设计、核心组件功能、请求处理流程及配置方法,帮助开发者理解如何高效地使用SpringMVC构建Web应用程序。

717

被折叠的 条评论
为什么被折叠?



