1、什么是springmvc?
它是基于mvc开发模式的框架,用来优化控制器,它是spring家族的一员,它也具备IOC和AOP。
2、什么是mvc?
它是一种开发模式,它是模型视图控制器的简称,所有的web应用都是基于mvc开发:
M :视图层,包含实体类,业务逻辑层,数据访问层
V : 视图层,html,JavaScript,Vue等都是视图层,用来显示数据
C :控制层,它是用来接收用户客户端的请求,并返回相应给客户端的组件,servlet就是组件
1、springmvc框架优点
-轻量级,基于mvc的框架
-易于上手,容易理解,功能强大
-它具备IOC和AOP
-完全基于注解开发
时序解析
springmvc执行流程
看懂工作原理得先理解springmvc的三大组件:处理器映射器(HandlerMapping)、处理器适配器(HandlerAdopter)、视图解析器(ViewResolver):
处理器映射器(HendlerMapping):可以理解为Map<URL,Handler>,它=负责把客户端的请求映射到springmvc的处理器或者我们自己定义的处理器,也就是我们创建的Controller里的方法。
处理器适配器(HandlerAdopter):它可以根据我们的处理器映射器找到的处理器Handler信息,去执行Handler。
视图解析器(ViewResolver):视图解析器首先会把逻辑视图名解析成物理视图名,也就是spring-mvc.xml文件中的加上前缀"/WEB-INF/pages/",和加上后".jsp",最终生成"/WEB-INF/pages/逻辑视图名.jsp"物理视图名,最后生成View视图对象返回。
视图执行流程:
1)客户端发送请求,请求会被DispatcherServlet前端控制器拦截。
2)DispatcherServlet会调用HandlerMapping处理器映射器。
3)处理器映射器(HandlerMapping)会根据URL找到对应的处理器(Handler)和处理器拦截器一并返回给前段控制器(DispatcherServlet)。
4)DispatcherServlet会根据返回的相应信息,选择合适的处理器适配器(HandlerAdapter),HandlerAdapter会调用处理器(Handler),也就是后端控制器(就是我们编写的controller)。
5)Handler(也就是controller)执行完后,会返回一个ModelView对象(该对象中会包含视图名或包含模型和视图名)。
6)HandlerAdapter会将M哦对了AndView对象返回给DispatcherServlet前端控制器。
7)前端控制器(DispatcherServlet)请求视图解析器(ViewResolver)根据逻辑视图名解析成真正的物理视图名(也就是"/WEB-INF/pages/逻辑视图名.jsp"形式的视图名)。
8)视图解析器(ViewResolver)解析后得到一个具体的视图对象,并把视图对象返回给前端控制器(DispatcherServlet)
9)前端控制器(DispatcherServlet)会将视图对象渲染到view中。
10)最后前端控制器(DispatcherServlet)才将结构相应给用户。
追加内容:在spring4.0后的开发可以不配做处理器映射器和处理器映射器,因为spring做了默认的配置。如果想显示并快捷地配置处理器映射器和处理器适配器,也可以在配置文件中使用<mvc:annotation-driven>元素来实现,这个元素会自动注册处理器映射器和处理器适配器。
2、springmvc的核心类和注解
自spring5.0后,注解开发就是不可缺的了,spring2.5之后也新增了基于注解的controller形式。controller注解也简化了xml文件配置,大大提高了开效率。
2.1、DispatcherServlet类
DispatcherServlet是springmvc的流程控制中心,也是springmvc的核心,也称前端控制器,它也可以拦截前端的请求。
DispatcherServlet会根据具体规则将请求交给其他组件,所有的请求都会经过DispatcherServlet,然后进行转发处理,这样就降低了其他组件之间的耦合性。
DispatcherServlet本质就是Servlet,可以在web.xml文件中完成DispatcherServlet的配置和映射。
<servlet>
<servlet-name>DispatcherServlet</servlet-name>
<!--配置spring mvc前端控制器-->
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--配置初始化参数,用于读取spring-web.xml的配置文件-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-mvc.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>
</servlet>
2.2、@Controller注解
在普通的java类上标注上@Controller注解,然后通过spring的扫描机制找到了标注了注解的java类,该java类就成了spring mvc的处理器类。这个处理处理器类就是用来处理用户发过来的请求的,它是由前端控制器拦截然后通过处理器映射器和处理器适配器进行处理选会选择到的处理器类。
@Controller
public class UserController {
........
}
为了让spring mvc能够扫描到这个处理器类,我们要在spring mvc配置文件中添加相应的扫描配置信息。(1)引入pring-context声明,用于支持<context:component-scan>元素的使用,就可以使用<context:component-scan>元素就可以指定我们要扫描的包里的所有类了,就可以扫描到那个类标注了@Controller。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:context="http://www.springframework.org/schema/context"
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--开启组件扫描-->
<context:component-scan base-package="com.ltc.controller"></context:component-scan>
</beans>
2.3、@RequestMapping注解
只用@Controller注解标注类的话,spring mvc框架是不能找到使用那个Handler处理器来处理的。这时@RequestMapping就可以为处理器方法提供必要的映射信息,将请求的URL映射到具体的处理方法上。
2.3.1、@RequestMapping注解的使用
@RequestMapping可以作用在类上,也可以作用在方法上。这就是@RequestMapping的两种用法。
1)、标注在方法上
Handler在浏览器中对应的访问地址由:项目访问路径+处理方法的映射路径共同组成。这时@RequestMapping标注在方法上,就可以提供处理方法的映射路径了。
@Controller
public class UserController {
@RequestMapping("/hello")
public String hello(){
........
return "index";
}
}
2)、标注在类上
标注在类上时,value值就相当于处理器类的命名空间,它就可以作为访问处理器方法的第一级访问目录,在访问处理器方法时都要加上这一级目录。此时浏览器的访问路径就为:项目访问路径+处理器类的映射路径+处理器的映射路径。
@Controller
@RequestMapping("/user")
public class UserController {
@RequestMapping("/hello")
public String hello(){
System.out.println("hello springmvc......");
return "index";
}
}
2.3.2、@RequestMapping注解的属性
在使用@RequestMapping注解的value是访问路径和处理器的映射,处理value外,还有6个属性。
@RequestMapping属性有:name、value、method、params/headers。
name:类型是String[],是一个可选属性,用来为映射地址指定别名的。
value:类型String[],是@RequestMapping的默认属性,当@RequestMapping只有一个value属性时,value属性名可以省略。value属性可以将一个或多个请求映射到一个方法上。
@Controller
@RequestMapping("/user")
public class UserController {
//@RequestMapping("/hello")
@RequestMapping(value = {"/hello","/userHello"})
public String hello(){
System.out.println("hello springmvc......");
return "index";
}
}
method:类型为RequestMethod[],method属性可以对处理映射的URL请求方法方式进行限定。如果加了method属性限定,不仅要URL和处理器映射成功,还要method的属性要和URL的方式方式相同,处理器才能正常处理请求。
@Controller
@RequestMapping("/user")
public class UserController {
//@RequestMapping("/hello")
@RequestMapping(value = {"/hello","/userHello"},method = RequestMethod.GET)
public String hello(){
System.out.println("hello springmvc......");
return "index";
}
@RequestMapping(value = {"/save","/userSave"},method = RequestMethod.POST)
public String save(){
System.out.println("hello springmvc......");
return "index";
}
}
如果method属性和方式的方式不匹配,会包405的错误。
params:类型为String[],params属性可以对将请求映射的定位范围缩小。也就是说,当设置了params属性的值后,请求参数的值等于params属性的值,才能执行到映射到处理器的方法上。
@Controller
@RequestMapping("/user")
public class UserController {
//@RequestMapping("/hello")
@RequestMapping(value = ("/hello"),params = "id=1")
public String hello(){
System.out.println("hello springmvc......");
return "index";
}
}
当设置了params属性后,请求的URL应为http://localhost:8080/user/hello?id=1
如果URL请求参数值与params设置的参数的值不匹配则会报400。
2.3.3、请求映射方式
请求方式不仅有基于@RequestMapping注解指定请求映射的URL路径,还有基于请求方式的URL路径映射、基于Ant风格的URL路径映射和基于REST风格的URL路径映射三种。
1)基于请求方式的URL路径映射
这种组合注解方式从spring4.3开始的,可以简化@RequestMapping方式中指定请求方式method属性,能更好地表达被注解方法的语义。
spring mvc组合注解有:
(1)、@GetMapping:匹配GET方式的请求。
(2)、@PostMaping:匹配POST方式的请求。
(3)、@PutMapping:匹配PUT方式的请求。
(4)、@DeleteMapping:匹配DELETE方式的请求。
(5)、@PatchMapping:匹配PATCH方式的请求。
2)基于Ant风格的URL路径映射
spring mvc支持Ant风格的URL路径映射,所谓的Ant风格其实就是一种通配符风格,可以在处理器映射路径中使用通配符对访问的URL路径进行关联。
Ant风格的通配符有三种:
?:匹配任何单个字符。
* :匹配0或任意数量的字符。
** :匹配0或多级目录。
3)基于RESTful风格的URL路径映射 (待补充)
REST风格是一种网络资源的访问风格,规范了网络资源的访问方式。REST访问的网络资源可以是一段文本、一张图片、一首歌曲、一种服务,总之是一个具体的存在。每个网络资源都有一个URL(统一资源标识)指向它,要获取这个资源,访问它的URL就可以,因此URL即为每个资源独一无二的标识。
RESTful按照REST风格访问网络资源,简单的说,RESTful就是把请求参数变成路径的一种风格。
Restful就是一个资源定位及资源操作的风格。不是标准也不是协议,只是一种风格。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。
例如:传统的风格访问的URL格式如下:
http://localhost:8080/user/save?id=1
而采用RESTful风格后,其访问的URL格式如下:
http://localhost:8080/user/save/id=1
从上面的对比,可以看出RESTful风格中的URL将请求参数id=1变成了请求路径的一部分。