初识SpringMvc
mvc
MVC模式(Model–view–controller)是软件工程中的一种软件架构模式,把软件系统分为三个基本部分:模型(Model)、视图(View)和控制器(Controller)。 Mvc是一种软件架构,而Spring是一种思想或框架.不同的语言都有对应的Mvc实现方法. MVC 维基百科

Model
用于封装与应用程序的业务逻辑相关的数据以及对数据的处理方法。
“ Model ”有对数据直接访问的权力,例如对数据库的访问。
“Model”不依赖“View”和“Controller”.
- 个人理解为dao层及相关的实现.
View
能够实现数据有目的的显示.
在 View 中一般没有程序上的逻辑。
- 类似jsp页面这种展示数据的东西
Controller
起到不同层面间的组织作用,用于控制应用程序的流程。
它处理事件并作出响应。“事件”包括用户的行为和数据 Model 上的改变。
- servlet等
SpringMvc执行流程

-
DispatcherServlet表示前置控制器,是整个SpringMVC的控制中心。用户发出请求,DispatcherServlet接收请求并拦截请求。
-
HandlerMapping为处理器映射。DispatcherServlet调用HandlerMapping,HandlerMapping根据请求url查找Handler。
-
HandlerExecution表示具体的Handler,其主要作用是根据url查找控制器.
-
HandlerExecution将解析后的信息传递给DispatcherServlet,如解析控制器映射等。
-
HandlerAdapter表示处理器适配器,其按照特定的规则去执行Handler。
-
Handler让具体的Controller执行。
-
Controller将具体的执行信息返回给HandlerAdapter,如ModelAndView。
-
HandlerAdapter将视图逻辑名或模型传递给DispatcherServlet。
-
DispatcherServlet调用视图解析器(ViewResolver)来解析HandlerAdapter传递 的逻辑视图名。
-
视图解析器将解析的逻辑视图名传给DispatcherServlet。
-
DispatcherServlet根据视图解析器解析的视图结果,调用具体的视图。 最终视图呈现给用户。
看一下代码
代码结构

- web.xml
这里,仅配置了一个servlet即DispatcherServlet,所有的请求都会被拦截和处理. 由下图可以看到,DispatcherServlet通过层层的继承最终会实现Servlet接口,这也是它能在web.xml中注册的原因. 它本质上就是一个servlet,只是功能更强大.

<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--关联一个springmvc的配置文件:springmvc-servlet.xml-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc-servlet.xml</param-value>
</init-param>
<!--启动级别-1,表示随tomcat一起启动-->
<load-on-startup>1</load-on-startup>
</servlet>
<!--映射,拦截所有请求-->
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
- springmvc-controller.xml是Spring项目的配置文件,注册了一些bean.前两个分别是处理器映射器和处理器适配器,第三个是视图解析器.最后是我们的Controller实现类.
<!--这个bean省略也可以,此处为展示流程注册了进来-->
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
<!--这个bean省略也可以,此处为展示流程注册了进来-->
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>
<!--视图解析器:DispatcherServlet给他的ModelAndView-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="InternalResourceViewResolver">
<!--前缀-->
<property name="prefix" value="/WEB-INF/jsp/"/>
<!--后缀-->
<property name="suffix" value=".jsp"/>
</bean>
<bean id="hello" class="com.wang.controller.controller"/>
- Controller类
首先我们实现了Controller接口并实现了handleRequest方法
class controller implements Controller {
@Override
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) {
ModelAndView modelAndView = new ModelAndView();
//封装对象,放在ModelAndView中。Model
modelAndView.addObject("msg", "HelloSpringMVC!");
//封装要跳转的视图,放在ModelAndView中
modelAndView.setViewName("hello");
//: /WEB-INF/jsp/hello.jsp
return modelAndView;
}
}
- hello.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>hello</title>
</head>
<body>
${msg}
</body>
</html>
到这里已经可以运行的,但是在打包的时候一定要注意将所有的依赖都放进去.如下图:

web-inf 目录下一定要有lib目录并且有相关依赖,否则会404报错.
SpringMvc 分析

发起请求
当我们在浏览器中输入 http://localhost:8080/hello 后,浏览器会发送请求到前端控制器,对应图上的步骤1.前端控制器可以理解为 DispatcherServlet.
委托给处理器
我们的Controller类实现了Controller接口,因此Controller类就是一个简单的处理器.但是并没有和model层产生交互,直接返回了一个modelandview到DispatcherServlet.
// 可以理解为与model层进行交互,获得了数据 "HelloSpringMVC"
modelAndView.addObject("msg", "HelloSpringMVC!");
// 设置了要跳转的视图
modelAndView.setViewName("hello");
//返回这个modelAndView到 DispatcherServlet
return modelAndView;
将model交给相应的view渲染
结束
整个流程以 DispatcherServlet 为中心
解析映射器是将DispatcherServlet传来的请求进行解析,判断出具体调用的是哪个Controller
然后由DispatcherServlet调用相关的Controller.
Controller完成mode层的交互之后返回一个 modeAndView 给DispatcherServlet
DispatcherServlet 根据携带的View信息配置相应的视图解析器
最后由视图解析器进行mode数据的渲染

使用注解实现SpringMvc
项目结构一览:

配置 web.xml
这一步与生变步骤没有任何不同,注册 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:beans.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>DispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
配置 Spring 配置文件
beans.xml
通过注解实现Mvc可以大大简化开发,但是 Spring 配置文件需要做一些修改.
<!--自动扫描包-->
<context:component-scan base-package="com.wang.controller"/>
<!--设置静态过滤,不处理MP3 MP4这些静态文件,可选项目-->
<mvc:default-servlet-handler/>
<!--开启注解支持-->
<mvc:annotation-driven/>
<!--视图解析器仍需手动配置-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
实现Controller
通过注解不需要实现Controller接口.
/**
* beans的自动扫描,与
* @Repository
* @Service
* @Controller
* 仅有命名上的区别
*/
@Controller
public class controller {
//设置接受的url
@RequestMapping("/hello")
public String hello(Model model) {
//model层
model.addAttribute("msg", "helloMvc");
//view层,返回值即视图的名称,由视图解析器处理
return "hello";
}
}
一些零碎配置
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>hello</title>
</head>
<body>
${msg}
${msg}
</body>
</html>
特别提示
- Spring 对 Java 13注解开发支持不好,如果用的是Java13,需在早maven配置一下即可. 参考这里
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>13</source>
<target>12</target>
</configuration>
</plugin>
</plugins>
参考: 秦疆