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";
   }
}
相关推荐
浮游本尊31 分钟前
Java学习第22天 - 云原生与容器化
java
渣哥2 小时前
原来 Java 里线程安全集合有这么多种
java
间彧2 小时前
Spring Boot集成Spring Security完整指南
java
间彧3 小时前
Spring Secutiy基本原理及工作流程
java
Java水解4 小时前
JAVA经典面试题附答案(持续更新版)
java·后端·面试
洛小豆6 小时前
在Java中,Integer.parseInt和Integer.valueOf有什么区别
java·后端·面试
前端小张同学6 小时前
服务器上如何搭建jenkins 服务CI/CD😎😎
java·后端
ytadpole6 小时前
Spring Cloud Gateway:一次不规范 URL 引发的路由转发404问题排查
java·后端
华仔啊7 小时前
基于 RuoYi-Vue 轻松实现单用户登录功能,亲测有效
java·vue.js·后端