简单易懂,看透SpringMVC原理
什么是Spring MVC
Spring MVC是Spring Framework的一部分,是基于Java实现MVC的轻量级Web框架。
官方文档:https://docs.spring.io/spring-framework/docs/4.3.24.RELEASE/spring-framework-reference/html/mvc.html
Spring MVC的特点:
-
轻量级,简单、灵活、易用。
-
高效,基于请求响应的MVC框架(发送一个请求,就会响应一个视图)
-
作为Spring的一部分,享受了Spring的所有便利。
-
约定大于配置。
-
功能强大:RESTful、数据验证(手机号码,邮箱格式验证等)、格式化、本地化、主题等。
Spring MVC原理
官方原理图如下:
中文版原理图:
SpringMVC框架是围绕DispatcherServlet设计的,对应原理图中的前端控制器。
-
DispatcherServlet本质上是一个调度Servlet。
-
DispatcherServlet的作用是将请求分发到不同的处理器。
-
Spring2.5开始,基于注解形式开发,十分简洁。
Spring MVC执行流程如下:
实线表示Spring MVC已经实现好的,只有虚线是需要自己实现的。
执行流程:
1、DispatcherServlet表示前端控制器
DispatcherServlet是整个Spring MVC的控制中心,用户发出请求,DispatcherServlet接收并拦截请求。
-
请求url为:http://localhost:8080/springmvc_war/hello ,拆成三部分:
- http://localhost:8080:服务器域名
- springmvc_war:部署在web服务器上的工程站点。
- /hello:表示控制器Controller
-
如上url表示:请求位于服务器http://localhost:8080 上的 springmvc_war 站点的 hello控制器。
2、HandlerMapping为处理器映射
DispatcherServlet调用HandlerMapping,后者根据请求url查找Handler。
3、HandlerExecution是具体的Handler
- 主要作用是根据url查找控制器
- url:http://localhost:8080/springmvc_war/hello,查找的控制器是:/hello
- HandlerExecution将解析后的信息传递给DispatcherServlet。如解析后的控制器映射等。
4、HandlerAdapter为处理器适配器
- 按照特定的规则去执行Handler
- Handler让具体的Controller执行。
- Controller将执行结果,包括数据和视图信息,封装到ModelAndView。并返回给HandlerAdapter。
- HandlerAdapter将ModelAndView传递给DispatcherServlet。
5、ViewResolver视图解析器
- DispatcherServlet调用视图解析器ViewResolver来解析ModelAndView中的视图名
- 将解析后的视图名传递给DispatcherServlet。
- DispatcherServlet根据视图名,调用具体的视图。
- 渲染视图,返回呈现。
HelloSpringMVC
Spring2.5以后,使用注解开发SpringMVC功能十分强大。但是为了更清楚了解SpringMVC原理,最佳实践是动手实现。
1、web.xml配置
- 在web.xml中配置DispatcherServlet
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<!--注册DispatcherServlet-->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--关联一个springmvc的配置文件,命名规则为:【servlet-name】-servlet.xml-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<!--/ 匹配所有的请求:不包括.jsp-->
<!--/* 匹配所有的请求:包括.jsp-->
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
2、DispatcherServlet对应sping bean文件配置
- 一个DispatcherServlet需要关联一个spring bean配置文件。
- 根据官方命名规则:【servlet-name】-servlet.xml,此处为springmvc-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 class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
<!--添加处理器适配-->
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>
<!--添加视图解析器:解析DispatcherServlet给它的ModelAndView
1、获得ModelAndView中的数据
2、解析ModelAndView中的视图名字
3、拼接视图完整文件名,找到视图 /WEB-INF/jsp/XXX.jsp
4、将数据渲染到这个视图上
-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver">
<!--前缀-->
<property name="prefix" value="/WEB-INF/jsp/"/>
<!--后缀-->
<property name="suffix" value=".jsp"/>
</bean>
</beans>
3、编写Controller
Controller负责解析用户请求,进行业务处理,并返回一个模型。
Controller通过实现接口和注解定义两种方法实现。
实现了Controller接口的类就是控制器,这是较老的方法。
一个控制器类只能有一个方法。多个方法要写多个controller。
public class MyController implements Controller {
@Override
public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
//ModelAndView 模型和视图
ModelAndView mv=new ModelAndView();
//封装对象,放在ModelAndView中
mv.addObject("msg", "Hello!SpringMVC!~~");
//封装要跳转的视图,放在ModelAndView中。
mv.setViewName("hello"); //WEB-INF/jsp/hello.jsp
return mv;
}
}
4、把Controller注册到Spring
由于处理器映射使用了BeanNameUrlHandlerMapping,必须要在Spring文件中注册Controller。
- bean的id属性值为:斜杠/+控制器Controller。此处为"/hello"。
- Controller的id与服务器域名http://localhost:8080,工程包/springmvc_war,一起组成完整的请求url。
- 在浏览器输入url:http://localhost:8080/springmvc_war/hello
- 请求/hello,直接映射到"controller.MyController"控制器。
<!--id为斜杠/+控制器Controller,HandlerMapping根据url映射到controller-->
<bean id="/hello" class="controller.MyController" />
5、编写要跳转的.jsp页面文件
此处跳转到hello.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Zuka</title>
</head>
<body>
${msg}
</body>
</html>
6、启动Tomcat测试
- 在 Tomcat部署工程
点击运行后,默认页面弹出,展示index.jsp内容。对应链接:http://localhost:8080/springmvc_war
在链接末尾加上hello,对应链接:http://localhost:8080/springmvc_war/hello 。
该URL映射到MyController处理。返回页面展示hello.jsp内容。也就是MyController中 msg字段值。