深入了解Spring MVC

一、分析Spring MVC执行流程

  1. DispatcherServlet表示前置控制器,是整个Spring MVC的控制中心。用户发出请求,DispatcherServlet接收请求并拦截请求

假设请求的url为:http://localhost:8080/SpringMVC/hello

该url表示为请求位于服务器localhost:8080上的Spring MVC站点的hello控制器

  1. DispatcherServlet调用HandlerMapping(处理器映射),根据请求url查找Handler。
  2. HandlerExecution表示具体的Handler,其主要作用是根据url查找控制器,如上的hello
  3. HandlerExecution将解析后的信息传递给DispatcherServlet,如解析控制器映射等
  4. HandlerAdapter表示处理器适配器,其按照特定的规则去执行Handler
  5. Handler让具体的Controller执行
  6. Controller将具体的执行信息返回给HandlerAdapter,如ModelAndView
  7. HandlerAdapter将ModelAndView传递给DispatcherServlet
  8. DispatcherServlet调用视图解析器(ViewResolver)来解析ModelAndView
  9. ViewResolver解析后返回具体View给DispatcherServlet
  10. DispatcherServlet对View进行渲染视图
  11. 最终视图呈现给用户

二、使用注解开发Spring MVC

2.1 准备工作

1.新建模块SpringMVC-03-annotation,右键模块添加web项目支持

2.打开项目结构,在WEB_INF目录下添加依赖(否则会出现404报错)

2.2 编写代码

1.配置web.xml,注册DispatcherServlet

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?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的配置文件:【servet-name】-servlet.xml-->
<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>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
  1. 编写关联的springmvc配置文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<?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
https://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">

<!--自动扫描包,让指定包下的注解生效,由IOC容器统一管理-->
<context:component-scan base-package="xyz.yolin.controller"/>
<!--让Spring MVC不处理静态资源-->
<mvc:default-servlet-handler/>
<!--支持mvc注解驱动-->
<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>
  1. 创建对应的控制类Controller:HelloController
1
2
3
4
5
6
7
8
9
10
@Controller
public class HelloController {
@RequestMapping("/h")
public String hello(Model model){
//封装数据
model.addAttribute("msg","Hello,SpringMVCAnnotation");

return "hello";
}
}
  1. 完善前端视图和Controller之间的对应

在WEB-INF下新建 jsp / hello.jsp 文件

1
2
3
4
5
6
7
8
9
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
${msg}
</body>
</html>
  1. 测试

通常,我们只需要手动配置视图解析器,而处理器映射器和处理器适配器只需要开启注解驱动即可,而省去了大量xml配置

三、@Controller注解的作用

前面我们了解到控制器Controller负责处理由DispatcherServlet分发的请求,它把用户请求的数据经过业务处理层处理后封装成一个Model,然后再把该Model返回给对应的View进行展示。在Spring MVC中可以无需继承特定类或实现特定接口,只需使用@Controller标记一个类是Controller,然后使用@RequestMapping@RequestParam等注解用以定义URL请求和Controller方法之间的映射,这样Controller就能被外界访问到。

此外Controller不会直接依赖于HttpServlet对象,它们可以通过Controller的方法参数灵活的获取到。

单使用@Controller只是定义了一个控制器类,而使用@RequestMapping注解的方法才是真正处理请求的处理器。

我们还需要把这个控制器类交给Spring来管理。有两种方式:

  • 在Spring MVC的配置文件中定义MyController 的bean对象
1
2
<!--Handler-->
<bean id="/hello" class="xyz.yolin.controller.HelloController"/>
  • 在Spring MVC的配置文件中告诉Spring该到哪里去找标记为@Controller的Controller的Controller控制器
1
2
<!--自动扫描包,让指定包下的注解生效,由IOC容器统一管理-->
<context:component-scan base-package="xyz.yolin.controller"/>

四、@RequestMapping注解的作用

RequestMapping是一个用来处理请求地址映射的注解,可用于类或方法上。用在类上表示类中的所有响应请求的方法都是以该地址作为父路径

RequestMapping注解有六个属性:

  • value:指定请求的实际地址
  • method:指定请求类型,如GET、POST、PUT、DELETE等
  • consumes:指定处理请求的提交内容类型(Content-Type),例如application/json,text/html
  • produces:指定返回的内容类型,仅当request请求头中的(Accept)类型中包含该指定类型才返回
  • params:指定request中必须包含某些参数值时,才让该方法处理
  • header:指定request中必须包含某些指定的header值,才能让该方法处理请求。

详细可参考下面的文章

@RequestMapping的参数和用法

五、RestFul风格

1. 概念

RestFul就是一个资源定位及资源操作风格。基于这个风格设计的软件可以更简洁,更安全,易于实现缓存机制

2. 传统方式操作资源

通过不同的参数来实现不同的效果

-   http://127.0.0.1/item/queryItem.action?id=1 查询,GET
-   http://127.0.0.1/item/updateItem.action 更新,POST

3.使用RESTful操作资源

可以通过不同的请求方式来实现不同的效果!如请求地址一样,但是功能可以不同

-   http://127.0.0.1/item/1 查询,GET
-   http://127.0.0.1/item/1 删除,DELETE

同样的地址实现不同的效果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@Controller
public class RestfulController {
@RequestMapping(value = "/add/{a}/{b}",method = RequestMethod.GET)
public String test(@PathVariable int a,@PathVariable int b, Model model){
int res=a+b;
model.addAttribute("msg","get方式计算"+a+"+"+b+"结果为"+res);
return "test";
}

@RequestMapping(value = "/add/{a}/{b}",method = RequestMethod.POST)
public String test2(@PathVariable int a,@PathVariable int b, Model model){
int res=a+b;
model.addAttribute("msg","post方式计算"+a+"+"+b+"的结果为"+res);
return "test";
}
}

请我喝杯咖啡吧~

支付宝
微信