Spring MVC

目录

SpringMVC

什么是MVC模型

[Spring MVC](#Spring MVC)

案例

[Spring MVC执行流程](#Spring MVC执行流程)

[Spring MVC封装参数](#Spring MVC封装参数)

简单数据类型

简单对象

关联对象

简单数据类型集合

Map集合

参数类型转换器

[Spring MVC注解](#Spring MVC注解)

[@Controlle r和 @RequestMapping](#@Controlle r和 @RequestMapping)

@RequestParam

@RequestHeader、@CookieValue

@SessionAttributes

@PathVariable


SpringMVC

什么是MVC模型

MVC全称Model View Controller,是一种设计创建Web应用程序的模式。这三个单词分别代表Web应用程序的三个部分:

Model(模型):指数据模型。用于存储数据以及处理用户请求的业务逻辑。在Web应用中,JavaBean对象,业务模型等都属于Model。

View(视图):用于展示模型中的数据的,一般为jsp或html文件。

Controller(控制器):是应用程序中处理用户交互的部分。接受视图提出的请求,将数据交给模型处理,并将处理后的结果交给视图显示。

Spring MVC

Spring MVC是一个基于MVC模式的轻量级Web框架,是Spring框架的一个模块,和Spring可以直接整合使用,我们使用的版本是Spring6,所以JDK需要17以上。SpringMVC代替了Servlet技术,它通过一套注解,让一个简单的Java类成为处理请求的控制器,而无须实现任何接口。

案例

  1. 使用maven创建web项目,补齐包结构。

  2. 引入相关依赖

    <?xml version="1.0" encoding="UTF-8"?>

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>3.4.4</version>
    <relativePath/>
    </parent>
    <groupId>org.bit</groupId>
    <artifactId>Spring_MyBatis_Demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>Spring_MyBatis_Demo</name>
    <description>Spring_MyBatis_Demo</description>
    <url/>
    <licenses>
    <license/>
    </licenses>
    <developers>
    <developer/>
    </developers>
    <scm>
    <connection/>
    <developerConnection/>
    <tag/>
    <url/>
    </scm>
    <properties>
    <java.version>17</java.version>
    </properties>
    <dependencies>
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    复制代码
         <dependency>
             <groupId>org.projectlombok</groupId>
             <artifactId>lombok</artifactId>
             <optional>true</optional>
         </dependency>
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-test</artifactId>
             <scope>test</scope>
         </dependency>
     </dependencies>
    
     <build>
         <plugins>
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-compiler-plugin</artifactId>
                 <configuration>
                     <annotationProcessorPaths>
                         <path>
                             <groupId>org.projectlombok</groupId>
                             <artifactId>lombok</artifactId>
                         </path>
                     </annotationProcessorPaths>
                 </configuration>
             </plugin>
             <plugin>
                 <groupId>org.springframework.boot</groupId>
                 <artifactId>spring-boot-maven-plugin</artifactId>
                 <configuration>
                     <excludes>
                         <exclude>
                             <groupId>org.projectlombok</groupId>
                             <artifactId>lombok</artifactId>
                         </exclude>
                     </excludes>
                 </configuration>
             </plugin>
         </plugins>
     </build>
    </project>

Spring MVC执行流程

Spring MVC的组件

  • DispatcherServlet:前端控制器,接受所有请求,调用其他组件。
  • HandlerMapping:处理器映射器,根据配置找到方法的执行链。
  • HandlerAdapter:处理器适配器,根据方法类型找到对应的处理器。
  • ViewResolver:视图解析器,找到指定视图。

组件的工作流程

  1. 客户端将请求发送给前端控制器。
  2. 前端控制器将请求发送给处理器映射器,处理器映射器根据路径找到方法的执行链,返回给前端控制器。
  3. 前端控制器将方法的执行链发送给处理器适配器,处理器适配器根据方法类型找到对应的处理器。
  4. 处理器执行方法,将结果返回给前端控制器。
  5. 前端控制器将结果发送给视图解析器,视图解析器找到视图文件位置。
  6. 视图渲染数据并将结果显示到客户端。

Spring MVC封装参数

简单数据类型

在Servlet中我们通过request.getParameter(name)获取请求参数。该方式存在两个问题:

  • 请求参数较多时会出现代码冗余。
  • 与容器紧耦合。

而SpringMVC支持参数注入的方式用于获取请求数据,即将请求参数直接封装到方法的参数当中。用法如下:

  1. 编写控制器方法

    // 封装为简单数据类型类型参数
    @RequestMapping("/a1")
    public void Main(String username,int age){
    System.out.println(username);
    System.out.println(age);
    }

  2. 访问该方法时,请求参数名和方法参数名相同,即可完成自动封装。

http://localhost:8080/a1?username=hhj\&age=20

简单对象

SpringMVC支持将参数直接封装为对象,写法如下:

  1. 编写实体类

  2. 编写控制器方法

    public class Student {
    private int id;
    private String name;
    private String sex;
    }

    // 封装为简单对象类型参数
    @RequestMapping("/a1")
    public void Stu(Student student){
    System.out.println(student);
    }

  3. 访问该方法时,请求参数名和对象参数的属性名相同,即可完成自动封装。

http://localhost:8080/a1?id=1\&name=hhj\&sex=male

关联对象

SpringMVC还可以将请求参数封装为关联对象,即对象的属性也是一个对象。写法如下:

  1. 编写实体类

    public class Student {
    private int id;
    private String name;
    private String sex;
    private Address address; // 地址对象
    // 省略getter/setter/tostring
    }

    public class Address {
    private String info; //地址信息
    private String postcode; //邮编
    // 省略getter/setter/tostring
    }

2.编写控制器方法

复制代码
// 获取关联对象类型参数
@RequestMapping("/a2")
public void objParam2(Student student){  
  System.out.println(student);
}

3.访问该方法时,请求参数名和方法参数的属性名相同,即可完成自动封装。

http://localhost:8080/a2?id=1\&name=hhj\&sex=male\&address.info=xian\&address.postcode=123456

简单数据类型集合

1.编写控制器方法

封装为简单数据类型集合,参数前必须添加@RequestParam注解

复制代码
@RequestMapping("/c1/param4")
public void listParam(@RequestParam List<String> users){ 
  System.out.println(users);
}

2.该方式也可以封装为简单数据类型数组:

复制代码
@RequestMapping("/c1/param5")
public void listParam2(@RequestParam String[] users){ 
  System.out.println(users[0]); 
  System.out.println(users[1]);
}
  1. 请求的参数写法

http://localhost:8080/c1/param4?users=hhj\&users=zpy

Map集合

同样,SpringMVC要想把参数封装到Map集合中,需要封装到有Map属性的对象中。

  1. 编写实体类

  2. 编写控制器方法

    public class AddressMap {
    private Map<String,Address> address;
    // 省略getter/setter/tostring
    }

    // 对象中包含map属性
    @RequestMapping("/c1/param7")
    public void mapParam3(AddressMap addressMap){
    System.out.println(addressMap.getAddress());
    }

3.请求的参数写法

参数的写法为:map属性名[键].值中的属性,例如:address[one].info

请求的路径如下:

http://localhost:8080/c1/param7?address\[one\].info=xian\&address\[one\].postcode=100000\&address\[two\].info=beijing\&address\[two\].postcode=100011

编码后为:

http://localhost:8080/c1/param7?address[one].info=bj\&address[one].postcode=100010\&address[two].info=sh\&address[two].postcode=100011

参数类型转换器

前端传来的参数全部为字符串类型,SpringMVC使用自带的转换器将字符串参数转为需要的类型。如:

复制代码
// 获取简单类型参数
@RequestMapping("/c1/param1")
public void simpleParam(String username,int age){ 
  System.out.println(username);  
  System.out.println(age);
}

但在某些情况下,无法将字符串转为需要的类型,如:

复制代码
@RequestMapping("/c1/param8")
public void dateParam(Date birthday){ 
  System.out.println(birthday);
}

由于日期数据有很多种格式,SpringMVC默认只能转换2050/1/1这样的日期格式。但假如前端传来的参数格式为2025-01-01时,SpringMVC就无法解析参数。此时需要自定义参数类型转换器。

Spring MVC注解

@Controlle r和 @RequestMapping

@Controller

作用:标记控制器,将控制器交给Spring容器管理。

位置:类上方

位置:方法或类上方。用于类上,表示类中的所有控制器方法都是以该地址作为父路径。

属性:

  • value/path:请求路径

  • method:指定请求方式

  • params:规定必须发送的请求参数

  • headers:规定请求必须包含的请求头

    @Controller
    @RequestMapping("/c3")
    public class MyController3 {
    /**
    * 访问路径是 /c3/a1
    * 支持post和get请求
    * 请求必须带有username参数
    * 请求必须带有User-agen请求头
    *
    */
    @RequestMapping(path = "/a1",
    method = {RequestMethod.POST, RequestMethod.GET},
    params = {"username"},
    headers = {"User-agent"})
    public String annotation1(String username) {
    System.out.println(username);
    return "baizhan";
    }
    }

@RequestParam

作用:在控制器方法中封装请求参数

位置:方法参数前

属性:

复制代码
/*
  定义请求的参数名为name,默认值为sxt,不是必须的参数
 */
@RequestMapping("/a2")
public String annotation2(@RequestParam(name = "name",defaultValue = "sxt",required = false) String username) {
  System.out.println(username);
  return "baizhan";
}

请求URL的写法:http://localhost:8080/c3/a2?name=hhj

@RequestHeader、@CookieValue

@RequestHeader

作用:将请求头数据封装到控制器方法参数中

位置:方法参数前

@CookieValue

作用:将Cookie数据封装到控制器方法参数中

位置:方法参数前

复制代码
/*
    获取User-Agent请求头
    获取JSESSIONID的Cookie值
   */
@RequestMapping("/annotation3")
public String annotation3(@RequestHeader("User-Agent") String userAgent, @CookieValue("JSESSIONID") String jSessionId){
  System.out.println(userAgent);
  System.out.println(jSessionId);
  return "baizhan";
}
@SessionAttributes

作用:将Model模型中的数据存到session域中

位置:类上方

复制代码
@Controller
@RequestMapping("/c4")
// 将模型中的name数据保存到session中
@SessionAttributes("name")
public class MyController4 {
  @RequestMapping("/t1")
  public String t1(Model model){
    // model中保存name数据
    model.addAttribute("name","中北
    1111");
    return "baizhan";
   }

  @RequestMapping("/t2")
  public String t2(HttpSession session){
    // 从session中获取name数据
    Object name = session.getAttribute("name");
    System.out.println(name);
    return "baizhan";
   }
}
@PathVariable

作用:在RESTful风格的URL中获取占位符的值

位置:方法参数前

属性:

value:获取哪个占位符的值作为参数值,如果占位符和参数名相同,可以省略该属性。

复制代码
@Controller
@RequestMapping("/student")
// 模拟学生的增删改查控制器
public class MyController6 {
  // 路径中的/{id}表示占位符,最后会封装到方法的参数中使用
  // 删除学生
  @RequestMapping(value = "/{id}",method = RequestMethod.DELETE)
  public String deleteStudent(@PathVariable("id") int id){
    System.out.println("删除id为"+id+"的学生");
    return "baizhan";
   }


  // 如果占位符和参数名相同,可以省略@PathVariable中的value属性
  // 根据id查询学生
  @RequestMapping(value = "/{id}",method = RequestMethod.GET)
  public String findStudentById(@PathVariable int id){
    System.out.println("查找id为"+id+"的学生");
    return "baizhan";
   }
  // 新增学生
  @RequestMapping(value = "/{id}",method = RequestMethod.POST)
  public String addStudent(@PathVariable int id, Student student){
    System.out.println("新增id为"+id+"的学生");
    System.out.println(student);
    return "baizhan";
   }
  // 修改学生
  @RequestMapping(value = "/{id}",method = RequestMethod.PUT)
  public String updateStudent(@PathVariable int id, Student student){
    System.out.println("修改id为"+id+"的学生");
    System.out.println(student);
    return "baizhan";
   }
}
相关推荐
你是狒狒吗16 分钟前
HttpServletRequest是什么
java
你们补药再卷啦28 分钟前
springboot 项目 jmeter简单测试流程
java·spring boot·后端
菜鸡且互啄6940 分钟前
sql 向Java的映射
java·开发语言
顾林海1 小时前
深度解析HashMap工作原理
android·java·面试
雷渊1 小时前
介绍一下RocketMQ的几种集群模式
java·后端·面试
菜菜的后端私房菜1 小时前
深入解析Java SPI🌟从使用到原理的全面之旅🚀
java·后端·设计
AronTing1 小时前
01-Spring Cloud Alibaba 微服务架构总览与核心组件详解
java·微服务·架构
2401_835261382 小时前
多线程(Java)
java·开发语言·jvm
zlt20002 小时前
Spring AI与DeepSeek实战四:系统API调用
java·人工智能·spring ai·deepseek