SpringMVC学习笔记

发布于:2024-05-05 ⋅ 阅读:(27) ⋅ 点赞:(0)

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

@Controller
public class UserController{}

@RequestMapping
方法注解,位于SpringMVC控制器方法定义上方,设置当前控制器方法请求访问路径
@ResponseBody
方法注解,位于SpringMVC控制器方法定义上方,设置当前控制器方法响应内容为当前返回值,无需解析

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

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


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包等
    • 方式三:不区分两者环境
      方式一:
@ComponentScan({"com.itheima.service","com.itheima.dao"})
public class SpringConfig {
}

方式二:

@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,仅设置配置类类名即可完成开发

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类型形参即可接收参数

类型

public class User {
	private String name;
	private int age;
	//setter...getter...略
}

发送请求和参数
在这里插入图片描述
后台接收参数

//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属性参数
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...略
}

发送请求
在这里插入图片描述
后台接收参数:

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

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

数组类型参数

  • 数组参数:请求参数名与形参对象属性名相同且请求参数为多个,定义数组类型即可接收参数
    在这里插入图片描述

后台接收参数

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

发送请求和参数

集合类型参数

使用@RequestParam注解来解决集合类型参数接收问题,请求参数名与形参对象属性名相同且请求参数为多个。
在这里插入图片描述
后台接收参数:

//集合参数:同名请求参数可以使用@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依赖

<dependency>
	<groupId>com.fasterxml.jackson.core</groupId>
	<artifactId>jackson-databind</artifactId>
	<version>2.9.0</version>
</dependency>

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

@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对象数据

传说的数据内容

{
	"name":"itcast",
	"age":15,
	"address":{
		"province":"beijing",
		"city":"beijing"
	}
}

后台接收数据

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

JSON对象数组

在这里插入图片描述

@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来注释日期格式

@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
在这里插入图片描述

响应

在这里插入图片描述


网站公告

今日签到

点亮在社区的每一天
去签到