SpringMvc介绍。
目录
1、SpringMvc概述
1、基本介绍
2、工作流程
3、bean加载控制
二、请求
1、请求映射路径
2、请求方式
3、请求参数
4、请求参数(传递json数据)
5、日期类型参数传递
三、响应
四、REST风格
1、REST简介
2、RESTful入门案例
3、RESTful快速开发
五、拦截器
1、拦截器概念
2、拦截器开发
3、拦截器参数
4、拦截器链配置
1、SpringMvc概述
1、基本介绍
▶ 基本概念
SpringMVC是一种基于Java实现MVC模型的轻量级Web框架
▷ 优点
● 使用简单、开发便捷(相比于Servlet)
● 灵活性强
▷ 当前WEB程序的工作流程:
● 三层架构
○ web程序通过浏览器访问前端页面,发送异步请求到后端服务器
○ 后台服务器采用三层架构进行功能开发
○表现层负责接收请求和数据然后将数据转交给业务层
○ 业务层负责调用数据层完成数据库表的增删改查,并将结果返给表现层
○ 表现层将数据转换成json格式返回给前端
○前端页面将数据进行解析最终展示给用户。
▷ 表现层与数据层的技术选型:
● 数据层采用Mybatis框架
● 变现层采用SpringMVC框架,SpringMVC主要负责的内容有:
○controller如何接收请求和数据
○ 如何将请求和数据转发给业务层
○ 如何将响应数据转换成json发回到前端
▶ 程序流程
1.浏览器发送请求到Tomcat服务器
2.Tomcat服务器接收到请求后,会将请求交给SpringMVC中的DispatcherServlet[前端控制器]来处理请求
3.DispatcherServlet不真正处理请求,只是按照对应的规则将请求分发到对应的Bean对象
4.Bean对象是有我们自己编写来处理不同的请求,每个Bean中可以处理一个或多个不同的请求url
5.DispatcherServlet和Bean对象都需要交给Spring容器来进行管理
▶ 知识点
@Controller
@RequestMapping
@ResponseBody
▶ 入门案例
● AbstractDispatcherServletInitializer类是SpringMVC提供的快速初始化Web3.0容器的抽象类
● AbstractDispatcherServletInitializer提供三个接口方法供用户实现
○ createServletApplicationContext()方法,创建Servlet容器时,加载SpringMVC对应bean并放入WebApplicationContext对象范围中,而WebApplicationContext的作用范围为ServletContext范围,即整个web容器范围
protected WebApplicationContext createServletApplicationContext() {
AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
ctx.register(SpringMvcConfig.class);
return ctx;
}
○ createRootApplicationContext()方法,如果创建Servlet容器时需要加载非SpringMVC对的bean,使用当前方法进行,使用方式同createServletApplicationContext()
protected WebApplicationContext createRootApplicationContext() {
return null;
}
○ getServletMappings()方法,设定SpringMVC对应的请求映射路径,设置为/表示拦截所请求,任意请求都将转入到SpringMVC进行处理
protected String[] getServletMappings() {
return new String[]{"/"};
}
2、工作流程
▶ 启动服务器初始化过程
1. 服务器启动,执行ServletContainersInitConfig类,初始化web容器
2. 执行createServletApplicationContext方法,创建了WebApplicationContext对象
● 该方法加载SpringMVC的配置类SpringMvcConfig来初始化SpringMVC的容器
3. 加载SpringMvcConfig配置类
4. 执行@ComponentScan加载对应的bean
● 扫描指定包下所有类上的注解,如Controller类上的@Controller注解
5. 加载UserController,每个@RequestMapping的名称对应一个具体的方法
● 此时就建立了 `/save` 和 save方法的对应关系
6. 执行getServletMappings方法,定义所有的请求都通过SpringMVC
● `/`代表所拦截请求的路径规则,只有被拦截后才能交给SpringMVC来处理请求
▶ 单次请求过程
1. 发送请求localhost/save
2. web容器发现所有请求都经过SpringMVC,将请求交给SpringMVC处理
● 因为符合上面第六步设置的请求路径,所以该请求会交给SpringMVC来处理
3. 解析请求路径/save
4. 由/save匹配执行对应的方法save()
● 上面的第五步已经将请求路径和方法建立了对应关系,通过/save就能找到对应的save方法
5. 执行save()
6. 检测到有@ResponseBody直接将save()方法的返回值作为响应求体返回给请求方
3、bean加载控制
▶ Controller加载控制与业务bean加载控制
● SpringMVC相关bean(表现层bean)
● Spring控制的bean
○ 业务bean(Service)
○ 功能bean(DataSource等)
●SpringMVC相关bean加载控制
○ SpringMVC加载的bean对应的包均在com.itheima.controller包内
● Spring相关bean加载控制
○ 方式一:Spring加载的bean设定扫描范围为com.itheima,排除掉controller包内的bean
○ 方式二:Spring加载的bean设定扫描范围为精准范围,例如service包、dao包等
○ 方式三:不区分Spring与SpringMVC的环境,加载到同一个环境中
▶ 知识点
▶ bean的加载格式
public class ServletContainersInitConfig extends AbstractDispatcherServletInitializer {
protected WebApplicationContext createServletApplicationContext() {
AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
ctx.register(SpringMvcConfig.class);
return ctx;
}
protected WebApplicationContext createRootApplicationContext() {
AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
ctx.register(SpringConfig.class);
return ctx;
}
protected String[] getServletMappings() {
return new String[]{"/"};
}
}
▶ 简化开发
public class ServletContainersInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer{
protected Class[] getServletConfigClasses() {
return new Class[]{SpringMvcConfig.class};
}
protected String[] getServletMappings() {
return new String[]{"/"};
}
protected Class[] getRootConfigClasses() {
return new Class[]{SpringConfig.class};
}
}
二、请求
1、请求映射路径
2、请求方式
▶ Get请求
● 普通参数:url地址传参,地址参数名与形参变量名相同,定义形参即可接收参数
@RequestMapping("/commonParam")
@ResponseBody
public String commonParam(String name ,int age){
System.out.println("普通参数传递 name ==> "+name);
System.out.println("普通参数传递 age ==> "+age);
return "{'module':'common param'}";
}
▶ post请求
● 普通参数:form表单post请求传参,表单参数名与形参变量名相同,定义形参即可接收参数
@RequestMapping("/commonParam")
@ResponseBody
public String commonParam(String name ,int age){
System.out.println("普通参数传递 name ==> "+name);
System.out.println("普通参数传递 age ==> "+age);
return "{'module':'common param'}";
}
▶ Post请求中文乱码处理
● 为web容器添加过滤器并指定字符集,Spring-web包中提供了专用的字符过滤器
public class ServletContainersInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer{
// 配字符编码过滤器
protected Filter[] getServletFilters() {
CharacterEncodingFilter filter = new CharacterEncodingFilter();
filter.setEncoding("utf-8");
return new Filter[]{filter};
}
}
3、请求参数
▶ 普通参数:url地址传参,地址参数名与形参变量名相同,定义形参即可接收参数
@RequestMapping("/commonParam")
@ResponseBody
public String commonParam(String name ,int age){
System.out.println("普通参数传递 name ==> "+name);
System.out.println("普通参数传递 age ==> "+age);
return "{'module':'common param'}";
}
▶ 普通参数:请求参数名与形参变量名不同,使用@RequestParam绑定参数关系
@RequestMapping("/commonParamDifferentName")
@ResponseBody
public String commonParamDifferentName(@RequestParam("name")String userName , int age){
System.out.println("普通参数传递 userName ==> "+userName);
System.out.println("普通参数传递 age ==> "+age);
return "{'module':'common param different name'}";
}
▶ @RequestParam
▶ POJO参数:请求参数名与形参对象属性名相同,定义POJO类型形参即可接收参数
@RequestMapping("/pojoParam")
@ResponseBody
public String pojoParam(User user){
System.out.println("pojo参数传递 user ==> "+user);
return "{'module':'pojo param'}";
}
▶ 嵌套POJO参数:POJO对象中包含POJO对象
▶ 嵌套POJO参数:请求参数名与形参对象属性名相同,按照对象层次结构关系即可接收嵌套POJO属性参数
@RequestMapping("/pojoContainPojoParam")
@ResponseBody
public String pojoContainPojoParam(User user){
System.out.println("pojo嵌套pojo参数传递 user ==> "+user);
return "{'module':'pojo contain pojo param'}";
}
▶ 数组参数:请求参数名与形参对象属性名相同且请求参数为多个,定义数组类型形参即可接收参数
@RequestMapping("/arrayParam")
@ResponseBody
public String arrayParam(String[] likes){
System.out.println("数组参数传递 likes ==> "+ Arrays.toString(likes));
return "{'module':'array param'}";
}
▶ 集合保存普通参数:请求参数名与形参集合对象名相同且请求参数为多个,@RequestParam绑定参数关系
@RequestMapping("/listParam")
@ResponseBody
public String listParam(@RequestParam List likes){
System.out.println("集合参数传递 likes ==> "+ likes);
return "{'module':'list param'}";
}
4、请求参数(传递json数据)
▶ 接收请求中的json数据
▷ ①:添加json数据转换相关坐标
com.fasterxml.jackson.core
jackson-databind
2.9.0
▷ ②:设置发送json数据(请求body中添加json数据)
▷ ③:开启自动转换json数据的支持
@Configuration
@ComponentScan("com.itheima.controller")
@EnableWebMvc
public class SpringMvcConfig {
}
注意事项:@EnableWebMvc注解功能强大,该注解整合了多个功能,此处仅使用其中一部分功能,即json数据进行自动类型转换。
▷ ④:设置接收json数据
@RequestMapping("/listParamForJson")
@ResponseBody
public String listParamForJson(@RequestBody List likes){
System.out.println("list common(json)参数传递 list ==> "+likes);
return "{'module':'list common for json param'}";
}
▶ @EnableWebMvc
▶ @RequestBody
▶ POJO参数:json数据与形参对象属性名相同,定义POJO类型形参即可接收参数
@RequestMapping("/pojoParamForJson")
@ResponseBody
public String pojoParamForJson(@RequestBody User user){
System.out.println("pojo(json)参数传递 user ==> "+user);
return "{'module':'pojo for json param'}";
}
▶ POJO集合参数:json数组数据与集合泛型属性名相同,定义List类型形参即可接收参数
@RequestMapping("/listPojoParamForJson")
@ResponseBody
public String listPojoParamForJson(@RequestBody List list){
System.out.println("list pojo(json)参数传递 list ==> "+list);
return "{'module':'list pojo for json param'}";
}
▶ @RequestBody与@RequestParam区别
● 区别
○ @RequestParam用于接收url地址传参,表单传参【application/x-www-form-urlencoded】
○ @RequestBody用于接收json数据【application/json】
● 应用
○ 后期开发中,发送json格式数据为主,@RequestBody应用较广
○ 如果发送非json格式数据,选用@RequestParam接收请求参数
5、日期类型参数传递
▶ 参数传递
● 日期类型数据基于系统不同格式也不尽相同
○ 2088-08-18
○ 2088/08/18
○ 08/18/2088
● 接收形参时,根据不同的日期格式设置不同的接收方式
@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("参数传递 date(yyyy-MM-dd) ==> "+date1);
System.out.println("参数传递 date(yyyy/MM/dd HH:mm:ss) ==> "+date2);
return "{'module':'data param'}";
}
http://localhost/dataParam?date=2088/08/08&date1=2088-08-18&date2=2088/08/28 8:08:08
▶ @DateTimeFormat
▶ 类型转换器
● Converter接口
public interface Converter {
@Nullable
T convert(S var1);
}
○ 请求参数年龄数据(String→Integer)
○ json数据转对象(json → POJO)
○ 日期格式转换(String → Date)
● @EnableWebMvc功能之一:根据类型匹配对应的类型转换器
三、响应
▶ 响应页面(了解)
@RequestMapping("/toPage")
public String toPage(){
return "page.jsp";
}
▶ 响应文本数据(了解)
@RequestMapping("/toText")
@ResponseBody
public String toText(){
return "response text";
}
▶ 响应json数据(对象转json)
@RequestMapping("/toJsonPOJO")
@ResponseBody
public User toJsonPOJO(){
User user = new User();
user.setName("赵云");
user.setAge(41);
return user;
}
▶ 响应json数据(对象集合转json数组)
@RequestMapping("/toJsonList")
@ResponseBody
public List toJsonList(){
User user1 = new User();
user1.setName("赵云");
user1.setAge(41);
User user2 = new User();
user2.setName("master 赵云");
user2.setAge(40);
List userList = new ArrayList();
userList.add(user1);
userList.add(user2);
return userList;
}
▶ @ResponseBody
▶ HttpMessageConverter接口
public interface HttpMessageConverter {
boolean canRead(Class clazz, @Nullable MediaType mediaType);
boolean canWrite(Class clazz, @Nullable MediaType mediaType);
List getSupportedMediaTypes();
T read(Class



























