1.1 SpringMVC简介
SpringMVC 也叫Spring web mvc。是Spring 框架的一部分,在Spring3.0 后发布的。
1.2 SpringMVC的优点
-
基于MVC 架构
基于 MVC 架构,功能分工明确。解耦合。
-
容易理解,上手快,使用简单
就可以开发一个注解的 SpringMVC 项目,SpringMVC 也是轻量级的,jar 很小。不依赖的特定的接口和类。
-
作为Spring框架一部分,能够使用Spring的IOC和AOP
方便整合Strtus,MyBatis,Hiberate,JPA 等其他框架。
4. SpringMVC 强化注解的使用
在Controller, Service, Dao 都可以使用注解。方便灵活。使用@Controller 创建处理器对象,@Service 创建业务对象,@Autowired 或者@Resource 在控制器类中注入 Service,在Service 类中注入 Dao。
5.可适配性好
可适配性好,通过HandlerAdapter就可以支持任意一个类作为处理器。
1.3 SpringMVC优化的方向
1.4 SpringMVC执行的流程
执行流程说明:
1) 向服务器发送HTTP请求,请求被前端控制器 DispatcherServlet 捕获。
2) DispatcherServlet 根据<servlet-name>中的配置对请求的URL进行解析,得到请求资源标识符(URI)。然后根据该URI,调用 HandlerMapping 获得该Handler配置的所有相关的对象(包括Handler对象以及Handler对象对应的拦截器),最后以 HandlerExecutionChain 对象的形式返回。
3) DispatcherServlet 根据获得的Handler,选择一个合适的 HandlerAdapter。
4) 提取Request中的模型数据,填充Handler入参,开始执行Handler(Controller)。
在填充Handler的入参过程中,根据你的配置,Spring将帮你做一些额外的工作:
HttpMessageConveter:将请求消息(如Json、xml等数据)转换成一个对象,将对象转换为指定的响应信息。
数据转换:对请求消息进行数据转换。如String转换成Integer、Double等。
数据格式化:对请求消息进行数据格式化。如将字符串转换成格式化数字或格式化日期等。
数据验证:验证数据的有效性(长度、格式等),验证结果存储到BindingResult或Error中。
5) Handler(Controller)执行完成后,向 DispatcherServlet 返回一个 ModelAndView 对象。
6) 根据返回的ModelAndView,选择一个适合的 ViewResolver(必须是已经注册到Spring容器中的ViewResolver)返回给DispatcherServlet。
7) ViewResolver 结合Model和View,来渲染视图。
8) 视图负责将渲染结果返回给客户端
1.5 基于XML的SpringMVC程序
项目案例功能:用户提交一个请求,服务端处理器在接收到这个请求后,给出一条欢迎信息,在响应页面中显示该信息,采用传统的配置式开发方式。
创建步骤:
1)新建maven_web项目
2)添加依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.5.RELEASE</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope> <!--切记要加scope,否则tomcat插件启动时会报错-->
</dependency>
3)删除web.xml文件重新添加,因为自动生成的web.xml文件版本太低了。
4)在web.xml中配置DispatcherServlet核心控制器,url-pattern设置为"/"表示, 客户端发出的所有请求都会被DispatcherServlet核心控制器(中央调度器)拦截, DispatcherServlet再交给springmvc.xml进行处理,springmvc.xml接下来会 为客户端的url请求找到对应的控制器Controller类进行处理。
如果<url-pattern>*.do</url-pattern>,则表示拦截以“.do”结尾的URL请求。
中央调度器的全限定性类名在导入的 Jar 文件 spring-webmvc-x.x.x.RELEASE.jar 的第一个包org.springframework.web.servlet下可找到。
<servlet>
<servlet-name>springmvc</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>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<param-value>classpath:springmvc.xml</param-value>表示从类路径下加载SpringMVC的配置文件。
<init-param>节点是可选项,可以省略。
问题来了,Spring拦截所有的请求后,下一步交给谁进行解释呢,即到哪里找Spring MVC配置文件呢?答案是应用程序在启动时会默认到WEB-INF目录下查找命名格式为“ServletName-servlet.xml”的MVC配置文件。
其中ServletName应与web.xml中的<servlet-name>中的一致。
此外核心配置器还可选用<load-on-startup>1</load-on-startup>表示Servlet容器在服务器启动时立即加载。如果没有这条配置,则表示应用程序在第一个Servlet请求时加载该Servlet。
5)编写一个Controller类
在com.foxbill.controller包下,新建一个FirstController,实现Controller接口。
public class FirstController implements Controller {
@Override
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
ModelAndView mav = new ModelAndView();
mav.addObject("hello","Hello My First SpringMVC!");
mav.setViewName("main");
return mav;
}
}
FirstController -->控制器(相当于以前的servlet)
类中的方法的作用:创建一个ModelAndView对象,在对象中添加一个名叫“hello”的字符串对象,并设置逻辑视图为main。这个逻辑视图本身还不是完整的视图路径,将在下述有关步骤(视图解析器)进一步解释为完整路径。
此方法意味着程序将携带hello对象数据,跳转到名为main的逻辑视图。
6)完成springmvc.xml文件的配置。在工程的类路径即resources目录下创建 SpringMVC 的配置文件 springmvc.xml。该文件名可以任意命名。推荐使用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">
<!--1.配置处理器映射器,确定一种请求-相应的映射规则-->
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"></bean>
<!--2.配置处理器适配器,配置对处理器的handleRequest()方法的调用-->
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"></bean>
<!--3.配置自定义控制器,一条具体的映射关系,name对应客户端URL请求,class对应服务端响应程序-->
<bean name="/first" class="com.foxbill.controller.FirstController" />
<!--上述类型的1.处理器映射器是默认的,同样上述类型的2.处理器适配器也是默认的,两者均可省略不要-->
<!--4.配置视图解析器-->
<!--说明:视图解析器不是必须的,如果没有,则控制层的返回值需要从"main"改为"/WEB-INF/jsp/main.jsp",即必须写完整路径的视图名称。-->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
</beans>
(1)配置处理器映射器。
创建一种类型为BeanNameUrlHandlerMapping的处理器映射器,即定义一种“请求/响应”映射规则,客户端的URL请求如果跟某一个Bean的name属性匹配,则由该Bean的class属性指定的控制器Controller类进行响应处理。
(2)配置处理器适配器
创建一种处理器适配器,类型为SimpleControllerHandlerAdapter,用于对上述指定的控制器Controller类的handleRequest()方法的调用与执行。
(3)配置自定义控制器
定义一条具体的“请求/响应”映射关系,表示假如客户端发出的URL请求的是/first,则指定由服务端的com.foxbill.controller.FirstController来处理,通过这行代码确定了一条具体的“请求/响应”映射关系,是一对一的对应关系,即name属性对应客户端URL请求,class对应服务端响应程序。
【注意:这个Bean的配置要有效,前提是要配置类型为BeanNameUrlHandlerMapping的映射器和类型为SimpleControllerHandlerAdapter的适配器,它们相当于制定了一个规则,如乒乓球比赛的“男女混合双打”,而自定义控制器则是这个规则下的具体某某男和某某女进行配对,进行混合双打。】
(4)配置视图解析器
视图解析器用来解析控制器返回的逻辑视图的真实路径,这样更方便,易于扩展。
视图解析器不是必须的,如果没有,则控制层的返回值需要从"main"改为"/WEB-INF/jsp/main.jsp",即必须写完整路径的视图名称。
上述类型的处理器映射器是默认的,同样上述类型的处理器适配器也是默认的,两者均可省略不要,因此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">
<!--1.配置自定义控制器,一条具体的映射关系,name对应客户端URL请求,class对应服务端响应程序-->
<bean name="/first" class="com.foxbill.controller.FirstController" />
<!--2.配置视图解析器-->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
</beans>
7)删除index.jsp页面,重新建index.jsp页面,因为自动生成的页面缺失指令设置。
开发页面,发出请求。
<a href="${pageContext.request.contextPath}/first">访问控制器FirstController</a>
8)在webapp/WEB-INF目录上新添目录/jsp。
9)在/jsp目录下新建main.jsp页面。用来进行服务器处理完毕后数据的回显。
在<body></body>之间输入如下代码:
<h1>${hello}</h1>
10)运行项目
1.6 基于注解的SpringMVC程序
所谓 SpringMVC 的注解式开发是指,在代码中通过对类与方法的注解,便可完成处理器在 springmvc 容器的注册。注解式开发是重点。
项目案例功能:用户提交一个请求,服务端处理器在接收到这个请求后,给出一条欢迎信息,在响应页面中显示该信息。
创建步骤:
1)新建maven_web项目
同上
2)添加依赖
此处比上一个项目,多了一个aop的依赖。
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>5.3.26</version>
</dependency>
3)配置web.xml
配置方法及内容同上。
4)配置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"
xmlns:context="http://www.springframework.org/schema/context"
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">
<!--1.配置组件扫描器-->
<context:component-scan base-package="com.foxbill.controller" />
<!--2.配置视图解析器-->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
</beans>
与配置式开发的相比,少了一大堆配置,无须配置处理器映射器和处理器适配器,但问题来了,“请求/响应”的映射关系在哪定义呢?客户端的URL请求从哪里可以找到对应的服务端处理器来处理呢?可以发现上面代码中多了一个配置组件扫描器,表示通过扫描指定的包下面的类中的注解从而获取映射关系。
5)创建控制器,无须实现任何接口,代码如下:
package com.foxbill.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
@Controller
public class FirstController {
@RequestMapping("/first")
public ModelAndView doHello() {
ModelAndView mav = new ModelAndView();
mav.addObject("hello","Hello My First SpringMVC!");
mav.setViewName("main");
return mav;
}
}
第一个注解@Controller表示将本类定义为一个控制器类,这个无须再实现Controller接口。
第二个注解@RequestMapping("/first")表示定义一种“请求/响应”的映射关系,即如果客户端浏览器发出“/first”的URL请求,则由该注解下面的doHello()方法来响应。即客户端的请求,被映射到控制器类的方法上,大大减少了配置工作量。
6)index.jsp和main.jsp
同上
7)运行项目