目录
4.SpringConfig和SpringMvcConfig的融合
一、概述:
SpringMvc主要负责的内容:
1 controller层接收请求和数据
2请求和数据转发个业务层
3响应数据转化成json给前端
优点:
相比servlet使用简单 开发便捷
灵活性强
二、入门案例
1.开发流程
servlet:
SpringMVC:
tomcat服务器收到浏览器请求;tomcat给MVC中的DispatcherServlet;DispatcherServlet按照url对应规则发送给bean(一个bean对应一个或多个url);Spring容器管理DispatcherServlet和bean对象。
所以需要编写:
1.bean对象
2.bean和url的对应关系
3.Spring容器管理DispatcherServlet和bean对象
4.配置tomcat服务器,识别Spring容器,将请求交给DispatcherServlet分发
2.案例制作
2.1依赖导入:
注意:servlet的范围事provided(只在编译和测试有效),因为默认事compile(在编译、运行、测试都有效)。如果运行有效的话,tomcat和servlet-api会有冲突报错
<?xml version="1.0" encoding="UTF-8"?>
2 <project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
4 <modelVersion>4.0.0</modelVersion>
5 <groupId>com.itheima</groupId>
6 <artifactId>springmvc_01_quickstart</artifactId>
7 <version>1.0-SNAPSHOT</version>
8 <packaging>war</packaging>
9 <properties>
10 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
11 <maven.compiler.source>1.8</maven.compiler.source>
12 <maven.compiler.target>1.8</maven.compiler.target>
13 </properties>
14 <!--1. 导入SpringMVC与servlet的坐标-->
15 <dependencies>
16 <dependency>
17 <groupId>javax.servlet</groupId>
18 <artifactId>javax.servlet-api</artifactId>
19 <version>3.1.0</version>
20 <scope>provided</scope>
21 </dependency>
22 <dependency>
23 <groupId>org.springframework</groupId>
24 <artifactId>spring-webmvc</artifactId>
25 <version>5.2.10.RELEASE</version>
26 </dependency>
27 </dependencies>
28
29 <build>
30 <plugins>
31 <plugin>
32 <groupId>org.apache.tomcat.maven</groupId>
33 <artifactId>tomcat7-maven-plugin</artifactId>
34 <version>2.1</version>
35 <configuration>
36 <port>80</port>
37 <path>/</path>
38 </configuration>
39 </plugin>
40 </plugins>
41 </build>
42 </project>
2.2创建controller类
//2.制作控制器类,等同于Servlet
//2.1必须是一个spring管理的bean
//2.2定义具体处理请求的方法
//2.3设置当前方法的访问路径
//2.4设置响应结果为json数据
@Controller
public class UserController {
@RequestMapping("/save")
@ResponseBody
public String save(){
System.out.println("user save ...");
return "{'module':'springmvc'}";
2.3创建MVC配置类
//3.定义配置类加载Controller对应的bean
@Configuration
@ComponentScan("com.itheima.controller")
public class SpringMvcConfig {
}
2.4创建Tomcat的Servlet容器配置类
//4.定义servlet容器的配置类
public class ServletContainersInitConfig extends AbstractDispatcherServletInitializer {
//加载springMVC配置
protected WebApplicationContext createServletApplicationContext() {
//初始化WebApplicationContext对象
AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
//加载指定配置类
ctx.register(SpringMvcConfig.class);
return ctx;
}
//设置Tomcat接收的请求哪些归SpringMVC处理
protected String[] getServletMappings() {
return new String[]{"/"};
}
//设置spring相关配置
protected WebApplicationContext createRootApplicationContext() {
return null;
}
}
继承的AbstractDispatcherServletInitializer类是SpringMVC提供的快速初始化Web3.0容器的抽象类。里面有三个方法:
1.createRootApplicationContext()方法,如果创建Servlet容器时需要加载非SpringMVC对应的bean,使用当前方法进行,使用方式同createServletApplicationContext()
2.createServletApplicationContext()方法,创建Servlet容器时,加载SpringMVC对应的bean并放入WebApplicationContext对象范围中,而WebApplicationContext的作用范围为ServletContext范围,即整个web容器范围
3.getServletMappings()方法,设定SpringMVC对应的请求映射路径,设置为/表示拦截所有请求,任意请求都将转入到SpringMVC进行处理
createServletApplicationContext用来加载SpringMVC环境
createRootApplicationContext用来加载Spring环境
2.5配置tomcat
3.服务流程
服务器初始化过程
1.ServletContainersInitConfig加载初始化web容器
2.调用createServletApplicationContext()方法初始化SpringMVC容器,加载SpringMvcConfig配置类
3.执行@ComponentScan加载对应的bean,扫描controller层,每个@RequestMapping的名称对应一个具体的方法
4.执行getServletMappings方法,定义所有的请求都通过SpringMVC
单次请求过程
4.SpringConfig和SpringMvcConfig的融合
1.Tomcat的配置类要重写
简化版:
public class ServletContainersInitConfig extends
AbstractAnnotationConfigDispatcherServletInitializer {
protected Class<?>[] getRootConfigClasses() {
return new Class[]{SpringConfig.class};
}
protected Class<?>[] getServletConfigClasses() {
return new Class[]{SpringMvcConfig.class};
}
protected String[] getServletMappings() {
return new String[]{"/"};
}
2.MVC和Spring的不要重复扫描controller类
三、请求与响应
3.1设置请求映射路径
当类上和方法上都添加了@RequestMapping注解,前端发送请求的时候,要和两个注解的value
值相加匹配才能访问到。
@RequestMapping注解value属性前面加不加/都可以
@Controller
@RequestMapping("/user")
public class UserController {
@RequestMapping("/save")
@ResponseBody
public String save(){
System.out.println("user save ...");
return "{'module':'user save'}";
}
@RequestMapping("/delete")
@ResponseBody
public String save(){
System.out.println("user delete ...");
return "{'module':'user delete'}";
}
}
@Controller
@RequestMapping("/book")
public class BookController {
@RequestMapping("/save")
@ResponseBody
public String save(){
System.out.println("book save ...");
return "{'module':'book save'}";
}
}
3.2不同类型参数传递
关于传递过程中的中文乱码,原教学文档4.2.2有详细教程
1.普通、pojo、数组、形参不同、集合
一般的发送和接收,但是传入的参数名称与请求的参数名称(或者pojo的属性)必须相同。
数组、集合发送参数就是在postman传入参数的key相同;
嵌套pojo发送参数是:
形参不同参数、集合的接收参数,应用@RequestParam
@RequestMapping("/commonParamDifferentName")
@ResponseBody
public String commonParamDifferentName(@RequestPaam("name") String userName , int age){
System.out.println("普通参数传递 userName ==> "+userName);
System.out.println("普通参数传递 age ==> "+age);
return "{'module':'common param different name'}";
}
//集合参数:同名请求参数可以使用@RequestParam注解映射到对应名称的集合对象中作为数据
@RequestMapping("/listParam")
@ResponseBody
public String listParam(@RequestParam List<String> likes){
System.out.println("集合参数传递 likes ==> "+ likes);
return "{'module':'list param'}";
}
2.json数据
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.0</version>
</dependency>
//在SpringMVC的配置类中开启SpringMVC的注解支持,这里面就包含了将JSON转换成对象的功能
@Configuration
@ComponentScan("com.itheima.controller")
//开启json数据类型自动转换
@EnableWebMvc
public class SpringMvcConfig {
}
//使用@RequestBody注解将外部传递的json数组数据映射到形参的集合对象中作为数据
@RequestMapping("/listParamForJson")
@ResponseBody
public String listParamForJson(@RequestBody List<String> likes){
System.out.println("list common(json)参数传递 list ==> "+likes);
return "{'module':'list common for json param'}";
}
3.日期数据
//SpringMVC默认支持的字符串转日期的格式为yyyy/MM/dd
//用@DateTimeFormat解决其他格式
@RequestMapping("/dataParam")
@ResponseBody
public String dataParam(Date date,
@DateTimeFormat(pattern="yyyy-MM-dd") Date date1,
@DateTimeFormat(pattern="yyyy/MM/dd HH:mm:ss") Date date2)
System.out.println("参数传递 date ==> "+date);
System.out.println("参数传递 date1(yyyy-MM-dd) ==> "+date1);
System.out.println("参数传递 date2(yyyy/MM/dd HH:mm:ss) ==> "+date2);
return "{'module':'data param'}";
}
3.3响应
不使用@ResponseBody会需要返回类似于jsp的页面。
一般要用@ResponseBody
@Controller
public class UserController {
@RequestMapping("/toJsonList")
@ResponseBody
public List<User> toJsonList(){
System.out.println("返回json集合数据");
User user1 = new User();
user1.setName("传智播客");
user1.setAge(15);
User user2 = new User();
user2.setName("黑马程序员");
user2.setAge(12);
List<User> userList = new ArrayList<User>();
userList.add(user1);
userList.add(user2);
return userList;
}
}
四、Rest风格
优点:
隐藏资源的访问行为,无法通过地址得知对资源是何种操作
书写简化
http://localhost/users 查询全部用户信息 GET(查询)
http://localhost/users/1 查询指定用户信息 GET(查询)
http://localhost/users 添加用户信息 POST(新增/保存)
http://localhost/users 修改用户信息 PUT(修改/更新)
http://localhost/users/1 删除用户信息 DELETE(删除)
4.1修改为Restful风格
//新增的Rest风格
@Controller
public class UserController {
//设置当前请求方法为POST,表示REST风格中的添加操作
@RequestMapping(value = "/users",method = RequestMethod.POST)
@ResponseBody
public String save() {
System.out.println("user save...");
return "{'module':'user save'}";
}
}
//删
@Controller
public class UserController {
//设置当前请求方法为DELETE,表示REST风格中的删除操作
@RequestMapping(value = "/users/{id}/{name}",method =RequestMethod.DELETE)
@ResponseBody
public String delete(@PathVariable Integer id,@PathVariable String name)
{
System.out.println("user delete..." + id+","+name);
return "{'module':'user delete'}";
}
}