一、执行原理:
用户发送请求,到达前端控制器,执行web.xml中的DispatcherServlet(就是前端控制器,整个SpringMVC控制中心,接受用户发送的请求并拦截),也就是这里配置的<servlet-mapping>
1~4步:
DispatcherServlet根据请求去找映射器(HandlerMapping),HanderMapping根据url查找Handler,HandlerExecution就是具体的Handler,会根据具体的url查找控制器。HandlerExecution将解析后的信息传递给DispatcherServlet。
5~8步:
经过上述拿到处理器后,就去找适配器(HandlerAdapter),其按照特定的规则去执行Handler,
Handler让具体的Controller去执行。(通过Handler找到Controller)
Controller将具体的执行信息返回给Handler(第七步)。这里是将封装的数据和要跳转的视图(ModelandView)发给HandlerAdapter。
HandlerAdapter将信息发送给DispatcherServlet。(第八步)
9~11步:
DispatcherServlet调用ViewResolver(视图解析器)来解析从HandlerAdapter拿到的执行信息。(执行下图视图解析器的代码) 最后DispatcherServlet根据视图解析器的结果调用具体的视图。
视图解析器: 1.获取ModelAndView的数据 2.解析ModelAndView视图的名字 3.拼接视图名字,找到对应的视图 4.将数据渲染到视图上。
总结:
用户发起请求到DispatcherServlet(控制器),控制器根据请求去找映射器,映射器返回后。根据映射器再去找相应的适配器,调用控制器,返回模型视图,通过模型视图去配置具体的视图解析器。
二、配置步骤
理解原理:
1.在web.xml中配置DispatcherServlet(springmvc的核心,也是前端控制器,所有请求都到经过此)
<!--配置DispatcherServlet:这个是SpringMVC的核心,请求分发器,前端控制器-->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--DispatcherServlet要绑定Spring的配置文件-->
<!--springmvc-servlet.xml这个文件是要新建在resources路径下-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc-servlet.xml</param-value>
</init-param>
<!--启动级别:1 表示电脑启动的时候就启动-->
<load-on-startup>1</load-on-startup>
</servlet>
<!--在SpringMVC中,/ /* 这两个斜杠
/ :只匹配所有的请求,不会去匹配jsp页面
/* :匹配所有的请求,包括jsp页面-->
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
2.创建springmvc-servlet.xml 其中包括处理器映射器(HandlerMapper) 处理器适配器(HandlerAdapter) 视图解析器(用来解析Controller交过来的视图)
<?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"/>
<!--视图解析器,-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"
id="internalResourceViewResolver">
<!--前缀-->
<property name="prefix" value="/WEB-INF/jsp/"/>
<!--后缀-->
<property name="suffix" value=".jsp"/>
</bean>
<!--Hander-->
<bean id="/hello" class="com.wu.controller.HelloController"/>
</beans>
3.创建Controller
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class HelloController implements Controller {
public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
ModelAndView mv = new ModelAndView();
//业务代码
String result = "HelloSpringMvc";
mv.addObject("msg", result);
//视图跳转,这里的test会返回带视图解析器添加前缀和后缀
mv.setViewName("test");
return mv;
}
}
用注解方式配置(开发常用):
1.同样注册web.xml 注册DispatcherServlet 关联SpringMVC的配置文件,启动级别为1,映射路径为/
2.配置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"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!--开启注解:扫描com.qiu.controller包下的所有注解-->
<context:component-scan base-package="com.wu.controller"/>
<!--让SpringMVC不处理静态资源 .css .js .html .mp3 .mp4-->
<mvc:default-servlet-handler/>
<!--支持mvc注解驱动
在spring中一般采用@RequestMapping注解来完成映射关系
要想使@RequestMapping注解生效,必须向上下文注册DefaultAnnotationHandleMapping
和一个AnnotationMethodHandlerAdapter实例
这两个实例分别在类级别和方法级别处理
而annotation-driven配置帮助我们自动完成上述两个实例的注入-->
<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>
</beans>
3.HelloServlet中的代码:
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("/HelloController")
public class HelloController {
//真实访问地址:项目名/HelloController/hello
@RequestMapping("/hello")
public String sayHello(Model model){
//向模型中添加属性msg与值,可以在jsp页面中取出并渲染
//封装数据
model.addAttribute("msg","Hello SpringMVC");
//WEB-INF/jsp/hello.jsp
//会被视图解析器处理
return "hello";
}
}
@Controller是为了让SpringIOC 容器初始化时自动扫描到;
@RequestMapping是为了映射请求路劲,这里因为类与方法上都有映射,所以访问时应该是/HelloController/hello;
方法中声明Model类型的参数是为了把Action中的数据带到视图中;
方法返回的结果是视图的名称hello,加上配置文件中的前后缀变成WEB-INF/jsp/hello.jsp
4.创建视图层,在WEB-INF/jsp目录中创建hello.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
${msg}
</body>
</html>
三、对注解的理解
Controller代表这个类会被Spring接管,被接管的类的所有方法中若返回String,并且有具体的页面可以跳转,那么就会被视图解析器解析。
RequestMapping注解的是方法,则访问路径为:http://localhost:8080/项目名/hello,若注解了类,访问路径为:http://localhost:8080/项目名/类中注解的名/方法中注解的名。