SpringMVC学习笔记

SpringMVC概述

Web程序三层架构

数据层:Mybatis

表现层:SpringMVC

SpringMVC入门案例

SpringMVC制作过程:

  1. 创建web工程(Maven结构)
  2. 设置tomcat服务器,加载web工程(tomcat)
  3. 导入坐标(SpringMVC+Servlet)
  4. 定义处理请求的功能类(UserController)
  5. 设置请求映射(配置映射关系)
  6. 将SpringMVC设定加载到Tomcat容器

具体代码见https://github.com/cug-lucifer/springmvc_01_quickstart
@Controller

类注解,位于SpringMVC控制类定义上方,设定SpringMVC核心控制器bean

java 复制代码
@Controller
public class UserController{}

@RequestMapping

方法注解,位于SpringMVC控制器方法定义上方,设置当前控制器方法请求访问路径
@ResponseBody

方法注解,位于SpringMVC控制器方法定义上方,设置当前控制器方法响应内容为当前返回值,无需解析

java 复制代码
@RequestMapping("/save")
@ResponseBody
public String save(){
	System.out.println("saving ... ");
	return "{'module':'SpringMVC}";
}

AbstractDispatcherServletInitializer

SpringMVC提供的快速初始化Web3.0容器的抽象类

java 复制代码
public class ServletContainerInitConfig extends AbstractDispatcherServletInitializer {

    // 加载springMVC容器配置
    @Override
    protected WebApplicationContext createServletApplicationContext() {
        AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
        ctx.register(SpringMvcConfig.class);
        return ctx;
    }

    //设置哪些请求归属springMVC处理
    @Override
    protected String[] getServletMappings() {
        return new String[]{"/"};
    }

    //加载spring容器配置
    @Override
    protected WebApplicationContext createRootApplicationContext() {
        return null;
    }
}

启动服务器初始化过程

  1. 服务器启动,执行ServletContainersInitConfig类,初始化web容器
  2. 执行createServletApplicationContext方法,创建WebApplicationContext对象
  3. 加载SpringMvcConfig
  4. 执行@ComponentScan加载对应的bean
  5. 加载UserController,每个@RequestMapping的名称对应一个具体的方法
  6. 执行getServletMappings方法,定义所有的请求都通过SpringMVC

单次请求过程

  1. 发送请求localhost/save
  2. web容器发现所有请求都经过SpringMVC,将请求交给SpringMVC处理
  3. 解析请求路径 /save
  4. /save匹配执行对应的方法save()
  5. 执行save()
  6. 检测到有@ResponseBody直接将save()方法的返回值作为响应报文体返回给请求方

Controller加载控制与业务bean加载控制

  • SpringMVC相关bean(表现层)
  • Spring控制的bean
    • 业务bean(Service)
    • 功能bean(DataSource等)

功能不同,如何避免Spring错误加载到SpringMVC中的bean

加载Spring控制的bean的时候,排除掉SpringMVC控制的bean

  • SpringMVC相关bean加载控制
    • SpringMVC加载的bean对应的包均在com.itheima.controller包内
  • Spring相关bean加载控制
    • 方式一:Spring加载的bean设定扫描范围为com.itheima,排除掉controller包内的bean
    • 方式二:Spring加载的bean设定扫描范围为精准扫描,例如service包、dao包等
    • 方式三:不区分两者环境
      方式一:
java 复制代码
@ComponentScan({"com.itheima.service","com.itheima.dao"})
public class SpringConfig {
}

方式二:

java 复制代码
@Configuration
//设置spring配置类加载bean时的过滤规则,当前要求排除掉表现层对应的bean
//excludeFilters属性:设置扫描加载bean时,排除的过滤规则
//type属性:设置排除规则,当前使用按照bean定义时的注解类型进行排除
//classes属性:设置排除的具体注解类,当前设置排除@Controller定义的bean
@ComponentScan(value="com.itheima",
    excludeFilters = @ComponentScan.Filter(
        type = FilterType.ANNOTATION,
        classes = Controller.class
    )
)
public class SpringConfig {
}

@ComponentScan 类注解

属性:

  • excludeFilters:排除扫描路径中加载的bean,需要指定类别(type)与具体项(classes)
  • includeFilters:加载指定的bean,需要指定类别(type)与具体项(classes)

web配置简化开发

继承AbstractAnnotationConfigDispatcherServletInitializer,仅设置配置类类名即可完成开发

java 复制代码
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[]{"/"};
    }
}

Post请求与Get请求

解决Post请求中中文乱码问题

在控制器中添加CharacterEncodingFilter()

复制代码
@Override
protected Filter[] getServletFilters(){
	CharacterEncodingFilter filter = new CharacterEncodingFilter();
	filter.setEncoding("utf-8");
	return new Filter[]{filter};
}

请求参数

普通参数

通过url地址传参,地址参数名与形参变量名相同,定义形参即可接收参数

参数名与变量名不同,使用@RequestParam("name")

POJO类型参数

  • POJO参数:请求参数名与形参对象属性名相同,定义POJO类型形参即可接收参数

类型

java 复制代码
public class User {
	private String name;
	private int age;
	//setter...getter...略
}

发送请求和参数

后台接收参数

java 复制代码
//POJO参数:请求参数与形参对象中的属性对应即可完成参数传递
@RequestMapping("/pojoParam")
@ResponseBody
public String pojoParam(User user){
	System.out.println("pojo参数传递 user ==> "+user);
	return "{'module':'pojo param'}";
}

注意:

  • POJO参数接收,前端GET和POST发送请求数据的方式不变。
  • 请求参数key的名称要和POJO中属性的名称一致,否则无法封装。

嵌套POJO类型参数

应用于POJO对象中嵌套了其它的POJO类的情况

  • 嵌套POJO参数:请求参数名与形参对象属性名相同,按照对象层次结构关系即可接收嵌套POJO属性参数
java 复制代码
public class Address {
	private String province;
	private String city;
	//setter...getter...略
}
public class User {
	private String name;
	private int age;
	private Address address;
	//setter...getter...略
}

发送请求

后台接收参数:

java 复制代码
@RequestMapping("/pojoParam")
@ResponseBody
public String pojoParam(User user){
	System.out.println("pojo参数传递 user ==> "+user);
	return "{'module':'pojo param'}";
}

注意:
请求参数key的名称要和POJO中属性的名称一致,否则无法封装

数组类型参数

  • 数组参数:请求参数名与形参对象属性名相同且请求参数为多个,定义数组类型即可接收参数

后台接收参数

java 复制代码
//数组参数:同名请求参数可以直接映射到对应名称的形参数组对象中
@RequestMapping("/arrayParam")
@ResponseBody
public String arrayParam(String[] likes){
	System.out.println("数组参数传递 likes ==> "+ Arrays.toString(likes));
	return "{'module':'array param'}";
}

发送请求和参数

集合类型参数

使用@RequestParam注解来解决集合类型参数接收问题,请求参数名与形参对象属性名相同且请求参数为多个。

后台接收参数:

java 复制代码
//集合参数:同名请求参数可以使用@RequestParam注解映射到对应名称的集合对象中作为数据
@RequestMapping("/listParam")
@ResponseBody
public String listParam(@RequestParam List<String> likes){
	System.out.println("集合参数传递 likes ==> "+ likes);
	return "{'module':'list param'}";
}
  • 集合保存普通参数:请求参数名与形参集合对象名相同且请求参数为多个,@RequestParam绑定参数关系
  • 对于简单数据类型使用数组会比集合更简单些。

@RequestParam

JSON数据传输参数 😒

现在比较流行的开发方式为异步调用。前后台以异步方式进行交换,传输的数据使用的是JSON。对于JSON数据类型,常见的有三种:

  • json普通数组("value1", "value2", "value3", ...
  • json对象(key1:value1, key2:value2, ...
  • json对象数组({key1:value1, ...}, {key2:value2, ...}

SpringMVC默认使用的是jackson来处理json的转换,所以需要在pom.xml添加jackson依赖

xml 复制代码
<dependency>
	<groupId>com.fasterxml.jackson.core</groupId>
	<artifactId>jackson-databind</artifactId>
	<version>2.9.0</version>
</dependency>

并且需要在SpringMVC的配置类中开启SpringMVC的注解支持

java 复制代码
@Configuration
@ComponentScan("com.itheima.controller")
//开启json数据类型自动转换
@EnableWebMvc
public class SpringMvcConfig {
}
1

JSON普通数组

在参数前添加@RequestBody注解

复制代码
//使用@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'}";
}

JSON对象数据

传说的数据内容

json 复制代码
{
	"name":"itcast",
	"age":15,
	"address":{
		"province":"beijing",
		"city":"beijing"
	}
}

后台接收数据

java 复制代码
@RequestMapping("/pojoParamForJson")
@ResponseBody
public String pojoParamForJson(@RequestBody User user){
	System.out.println("pojo(json)参数传递 user ==> "+user);
	return "{'module':'pojo for json param'}";
}

JSON对象数组

java 复制代码
@RequestMapping("/listPojoParamForJson")
@ResponseBody
public String listPojoParamForJson(@RequestBody List<User> list){
	System.out.println("list pojo(json)参数传递 list ==> "+list);
	return "{'module':'list pojo for json param'}";
}

@EnableWebMvc

@RequestBody

@RequestBody@RequestParam区别

  • 区别
    • @RequestParam用于接收url地址传参,表单传参
    • @RequestBody用于接收json数据
  • 应用
    • 后期开发中,发送json格式数据为主,@RequestBody应用较广
    • 如果发送非json格式数据,选用@RequestParam接收请求参数

日期参数传递

在Contorl类中,将参数设置为日期类型,并且使用@DateTimeFormat来注释日期格式

java 复制代码
@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'}";
}

@DateTimeFormat

响应

相关推荐
栈溢出了1 小时前
Redis 分片集群与哈希槽笔记
java·redis·笔记·spring
我命由我123451 小时前
复利极简理解
经验分享·笔记·学习·职场和发展·求职招聘·职场发展·学习方法
AOwhisky2 小时前
Python 学习笔记(第三期)——流程控制核心知识点自测与详解
开发语言·笔记·python·学习·云原生·运维开发·流程控制
tyqtyq222 小时前
药品说明书解读 —— AI 安全用药助手,鸿蒙原生应用深度解析
人工智能·学习·华为·生活·harmonyos
小心亦新3 小时前
STM32学习13 定时器1中断
stm32·嵌入式硬件·学习
我命由我123453 小时前
72 法则极简理解
经验分享·笔记·学习·职场和发展·求职招聘·职场发展·学习方法
qq_263_tohua4 小时前
第112期 CNN学习,不错的文章
学习
我想我不够好。4 小时前
满级的惩戒在范围
学习
LiaoWL1234 小时前
【SpringCloud合集-04】Sentinel 流量控制与熔断降级 学习笔记
学习·spring cloud·sentinel
xian_wwq5 小时前
【学习笔记】OpenAI 兼容 API 服务化:从协议到 LLM Gateway(19/35)
笔记·学习