原理
发起请求时被前置控制器拦截到,这个其实就是一个DispatcherServlet,然后根据请求的参数生成代理请求,找到请求对应的实际控制器,控制器处理请求,创建数据模型,访问数据库,将模型响应给中心控制器,控制器使用模型与视图渲染试图结果,将结果返回中央控制器,然后返回给请求者。
运行步骤
简要分析:
- DispatcherServlet表示前置控制器,是整个SpringMVC的控制中心,用户发出请求,DispatcherServlet接收请求并拦截请求。
- 我们假设请求的URL为http://loclahost:8080/springmvc/hello
- http://localhost:8080是服务器的域名
- springmvc部署在服务器上的web站点
- hello表示为控制器
- 所以URL表示为请求服务器下的springmvc站点的hello控制器
- HandleMapping为处理器器映射。DispatcherServlet调用HandleMapping,HandleMapping根据URL查找到Handle
- HandleAdapter表示为处理器适配器,按照特定的规则去执行Handle
- Handle让具体的controller执行
- 如果设置了拦截器的话,不满足添加会被拦截下来
- controller将具体的执行信息返回给handleadapater,如modleandview
- 返回的时候也会被拦截器所拦截,同样需要满足条件
- handleadapter将试图逻辑名传递给dispatcherservlet
- dispatcherservlet调用ViewResolve来解析handleadapter传递的逻辑视图名
- ViewResolve将解析的视图名传给dispatcherservlet
- dispatcherservlet根据ViewResolve解析的视图结果,调用具体的视图
- 最终视图返回给用户
使用步骤:
xml版本:
-
配置dispatcherservlet中央处理器
需要在web,xml中配置<?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"> <!-- 配置中央处理器 配置路径用/,表示所有的请求都要经过这里 /*:表示匹配所有请求,包括jsp页面 /:表示只匹配所有的请求,不会去匹配jsp页面--> <servlet> <servlet-name>dispatcherServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!-- dispatcherservlet要绑定Spring配置文件,必须是集成所以配置文件的那个--> <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> <servlet-mapping> <servlet-name>dispatcherServlet</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>
-
SpringMVC三要素的配置
分别是处理器映射器(HandleMapping)、处理器适配器(handleadapter)、视图解析器(ViewResolve)<?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.获取modeladnview中的数据 2.解析了modleandview的视图名字 3.拼接视图名字,找到相应的视图 4.将数据渲染到视图上--> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/jsp/"/> <property name="suffix" value=".jsp"/> </bean> </beans>
-
编写controller
package com.yu.controller; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.mvc.Controller; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * @Description: TODO * @Author : yu * Date : 3/25/2020 1:58 PM */ public class HelloController implements Controller { @Override public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception { ModelAndView mv = new ModelAndView(); //业务代码 String result = "hellospringmvc"; mv.addObject("msg",result); //视图跳转 mv.setViewName("test");//: /WEB-INF/jsp/test.jsp return mv; } }
注意:如果代码没有问题,还是找不到目标,那么可以去查看一些依赖的问题
WEB-INF是否有lib目录,里面的配置是否有
缺点:一个controller只能有一个类,并且要配置一个bean
注意:
在将controller注册到spring中的时候,前面需要加/,否则就会404
<bean id="/t1" class="com.yu.controller.ControllerTest1"/>
可以省略处理器映射以及处理器适配器。结果不会改变,只需要视图解析器就行,因为mvc中默认有这两个东西。
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
注意前缀哪里是jsp/,因为是将viewname拼接到这个里面,如果缺少/或者多/,那么就会出现url路径不正确,不能匹配的问题。
注解版:
-
在web中配置中央处理器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"> <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-servlet.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> </web-app>
-
在spring配置中开启注解
<?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:cotext="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 https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd"> <!-- 这个是扫描包,不用再自己配置bean--> <cotext:component-scan base-package="com.yu.controller"/> <!-- 让Spring MVC不在处理静态资源 .css .js .html .mp3等等--> <mvc:default-servlet-handler/> <!-- 开启mvc注解 相当于与注入一个处理器映射 一个处理器适配器--> <mvc:annotation-driven/> <!-- 视图解析器--> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/jsp"/> <property name="suffix" value=".jsp"/> </bean> </beans>
-
编写controller
package com.yu.controller; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; /** * @Description: TODO * @Author : yu * Date : 3/25/2020 3:01 PM */ @Controller public class HelloController { @RequestMapping("/h1") public String hello(Model model){ //封装数据 model.addAttribute("msg","hellow springmvcannatation"); return "hello"; //会被视图解析器处理,这个/到底是为什么?要说和前面xml里面的id一样 } }
注意:
- 每次都要配置lib文件夹,因为好像是idea的问题,经常没有将依赖导进去。
- controller返回的字符串需要看看和视图解析器的前后缀拼接起来后是不是一个完整的url,缺少/就添,多了就去掉。