文章目录
1. 什么是SpringMVC
1.1 什么是MVC
MVC全名是Model View Controller,是模型(model)视图(view)控制器(controller)的缩写,是一种用于设计创建Web应用程序表现层的模式。MVC中每个部分各司其职:
- Model(模型):通常指的就是我们的数据模型,作用一般情况下用于封装数据。
- View(视图):通常指的就是我们的jsp或者html,作用一般就是展示数据的,通常视图是依据模型数据创建的。
- Controller(控制器):是应用程序中处理用户交互的部分,作用一般就是处理程序逻辑的。
1.2 什么是SpringMVC
SpringMVC是一种基于Java的实现MVC设计模型的请求驱动类型的轻量级Web框架,属于Spring FrameWork的后续产品,已经融合在Spring Web Flow里面。Spring框架提供了构建Web应用程序的全功能MVC模块。使用Spring可插入的MVC架构,从而在使用Spring进行WEB开发时,可以选择使用Spring的Spring MVC框架或集成其他MVC开发框架,如Struts2等。
SpringMVC已经成为目前最主流的MVC框架之一,并且随着Spring3.0的发布,全面超越Struts2,成为最优秀的MVC框架。它通过一套注解,让一个简单的Java类成为处理请求的控制器,而无须实现任何接口。同时它还支持RESTful编程风格的请求。
2. SpringMVC快速入门
2.1 编写控制器类
@Controller("/helloController")
public class HelloController {
@RequestMapping("/hello")
public String sayHello() {
System.out.println("HelloController的sayHello方法执行了!");
return "success";
}
}
2.2 编写SpringMVC的配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context" 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
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 配置创建 spring容器要扫描的包 -->
<context:component-scan base-package="com.joker"></context:component-scan>
<!-- 配置视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/pages/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
</beans>
2.3 配置核心控制器
<!-- web.xml中配置 SpringMVC核心控制器 -->
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<!-- 配置 SpringMVC的核心控制器 -->
<servlet>
<servlet-name>SpringMVCDispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 配置初始化参数,用于读取 SpringMVC的配置文件 -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:SpringMVC.xml</param-value>
</init-param>
<!-- 配置 servlet的对象的创建时间点:应用加载时创建。
取值只能是非 0正整数,表示启动顺序 -->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>SpringMVCDispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
2.4 测试
localhost:8080/springMVC_demo/hello,即可跳转至我们编写的success.jsp页面。
2.5 运行流程分析
从上面的案例中可以看到的是HelloController和InternalResourceViewResolver,但是远不止这些。浏览器发送请求,被DispatherServlet捕获,该Servlet并不处理请求,而是把请求转发出去。转发的路径是根据请求URL,匹配@RequestMapping中的内容。匹配到了后,执行对应方法。该方法有一个返回值。根据方法的返回值,借助InternalResourceViewResolver找到对应的结果视图。最后渲染结果视图,响应浏览器。
3. SpringMVC的组件及工作流程
-
用户请求发送给前端控制器(DispatcherServlet),前端控制器收到请求路径,但不知道请求的是哪个Controller中的哪个方法。
-
于是DispatcherServlet找到处理器映射器(HandlerMapping),实际上处理器映射器存放了一个Map(key-value这种形式),key就是请求的url,value就是处理的Handler。通过请求的url地址就能找到对应的处理器及自定义的拦截器等。
-
前端控制器依然不能处理这个业务请求,因为它也不知道这个Handler是什么类型,因为在SpringMVC中Handler除了可以是注解形式的之外,其实还可以是非注解形式的(非注解形式我们一般不用),所以前端控制器并不知道这个Handler到底是什么类型的,那就没办法执行它。那总得找个东西执行,这时它就会把这个事交给另外一个组件来处理,这个组件就叫处理器适配器(HandlerAdapter),这个处理器适配器就是来适配不同类型的Handler。它就会根据你不同类型的Handler来选择不同类型的适配器来执行它。
-
处理器适配器拿到处理器,执行对应的Controller中被@RequestMapping注解标注的方法,执行成功返回ModelAndView。处理器适配器拿到这个结果是没有用的,它的作用就是执行这个Handler,把这个Handler执行完之后,它的事就做完了。做完之后,拿到这个返回结果,那么它会原封不动地把这个返回结果扔给前端控制器,这时处理器适配器的事就做完了。
-
前端控制器拿到这个ModelAndView,它还是没有办法处理,通过对应的视图解析器(如jsp视图解析器,Thymeleaf视图解析器)请求解析视图,视图解析器把这个视图解析,解析完了之后它会返回一个View对象给前端控制器。
-
最后再由前端控制器进行视图渲染,并向用户响应结果。
4. SpringMVC的常用注解
4.1 @RequestMapping
作用:用于建立请求URL和处理请求方法之间的对应关系。
出现位置:
- 类上:请求URL的第一级访问目录。此处不写的话,就相当于应用的根目录,写的话需要以/开头。它出现的目的是为了使我们的URL可以按照模块化管理。
- 方法上:请求URL的第二级访问目录。
属性:
- value:用于指定请求的URL,它和path属性的作用是一样的。
- method:用于指定请求的方式。
- headers:用于指定限制请求消息头的条件。
@Controller("/helloController")
public class HelloController {
@RequestMapping(value = "/test1", method = RequestMethod.GET)
public String test1() {
System.out.println("HelloController的test1方法执行了!");
return "success";
}
}
4.2 @RequestParam
作用:把请求中指定名称的参数给控制器中的形参赋值。
属性:
- value:请求参数中的名称。
- required:请求参数中是否必须提供此参数,默认值:true,表示必须提供,如果不提供将报错。
@Controller("/helloController")
public class HelloController {
@RequestMapping("/test2")
public String test2(@RequestParam("name") String username,
@RequestParam(value="age", required=false) Integer age) {
System.out.println(username+","+age);
return "success";
}
}
4.3 @RequestBody
作用:用来接收前端传递给后端的json字符串中的数据的(请求体中的数据的),GET方式无请求体,所以使用@RequestBody接收数据时,前端不能使用GET方式提交数据,而是用POST方式进行提交。
@RequestBody与@RequestParam的区别:在后端的同一个接收方法里,@RequestBody与@RequestParam可以同时使用,@RequestBody最多只能有一个,而@RequestParam可以有多个。
属性:
- required:是否必须有请求体,默认值是:true。
@Controller("/helloController")
public class HelloController {
@RequestMapping("/test3")
public String test3(@RequestBody(required=false) String body) {
System.out.println(body);
return "success";
}
}
4.4 @PathVaribale
作用:用于绑定url中的占位符。例如:请求url中/delete/{id},这个{id}就是url占位符。url支持占位符是spring3.0之后加入的,是SpringMVC支持RESTful风格URL的一个重要标志。
属性:
- value:用于指定url中占位符名称。
- required:是否必须提供占位符。
@Controller("/helloController")
public class HelloController {
@RequestMapping("/test4/{id}")
public String test4(@PathVariable("id") Integer id) {
System.out.println(id);
return "success";
}
}