一篇让你知道SpringMVC中的所有基础使用技术

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: 一篇让你知道SpringMVC中的所有基础使用技术

一、常用注解

( 1 ) @RequestMapping

@RequestMapping注解可以用于控制器类和处理方法上,用于指定请求URL路径、HTTP请求方法和其他条件,从而将请求映射到对应的处理方法上。

参数 说明
value @RequestMapping 的 value 属性必须设值; @RequestMapping 的 value 属性是通过当前请求的请求地址来匹配请求; 从源码中可以看到value属性是一个字符串类型的数组,因此说明可以将多个请求映射到一个方法上,只需要给 value 来指定一个包含多个路径的数组。
method @RequestMapping的method属性是通过当前请求的请求方式来匹配请求; 浏览器向服务器发送请求,请求方式有很多GET、HEAD、POST、PUT、PATCH、DELETE、OPTIONS、TRACE。可以使用 method 属性来约束请求方式。
headers @RequestMapping的headers属性是通过当前请求的请求头信息来匹配请求; @RequestMapping的headers属性是一个字符串类型的数组,可以通过下面四种表达是来设置匹配关系 例如: “header”:要求请求映射的请求必须为包含 header的请求头信息 “!header”:要求请求映射的请求必须为不包含 header的请求头信息 “header=value”:要求请求映射的请求必须为包含 header的请求头信息,并且header的值必须为value “header!=value”:要求请求映射的请求必须为包含 header的请求头信息,并且header的值必须不是value
params @RequestMapping的params属性是通过当前请求的请求参数来匹配请求; @RequestMapping的params属性是一个字符串类型的数组,可以通过下面四种表达是来设置匹配关系 例如: “param”:要求请求映射的请求必须为包含 param的请求参数 “!param”:要求请求映射的请求是不能包含param的请求参数 “param=value”:要求请求映射的请求必须包含 param 的请求参数,且 param 参数的值必须为 value “param!=value”: 要求请求映射的请求是必须包含 param 的请求参数,其值不能为 value。

示例:

@RequestMapping注解还可以用于指定请求参数、请求头、请求体等条件。

例如:

@Controller
@RequestMapping("/users")
public class UserController {
    @RequestMapping(value = "/{id}", method = RequestMethod.GET, params = "active=true")
    public String getActiveUser(@PathVariable("id") int id) {
        // ...
    }
}

上面的例子中,只有当请求参数中包含"active=true"时,才会将请求映射到getActiveUser方法上。

( 2 ) @RequestParam

@RequestParam注解用于将请求参数绑定到控制器方法的参数上。它可以用于指定请求参数的名称、是否必需、默认值等。

参数 说明
value 请求中传入参数的名称,如果不设置后台接口的value值,则会默认为该变量名。
required 该参数是否为必传项。默认是true,表示请求中一定要传入对应的参数,否则会报404错误,如果设置为false时,当请求中没有此参数,将会默认为null,而对于基本数据类型的变量,则必须有值,这时会抛出空指针异常。如果允许空值,则接口中变量需要使用包装类来声明。
defaultValue 参数的默认值,如果请求中没有同名的参数时,该变量默认为此值。注意默认值可以使用SpEL表达式,如"#{systemProperties[‘java.vm.version’]}"

示例:

@RequestParam注解还可以用于将请求参数绑定到非基本类型的对象上。

例如:

@Controller
@RequestMapping("/users")
public class UserController {
    @RequestMapping(value = "/create", method = RequestMethod.POST)
    public String createUser(@RequestParam("user") User user) {
        // ...
    }
}

上面的例子中,createUser方法的user参数是一个自定义的User对象。SpringMVC会根据请求参数的名称和User对象的属性名称进行自动绑定。

( 3 ) @ModelAttribute

@ModelAttribute注解用于将请求参数或其他数据绑定到控制器方法的参数上或方法的返回值上。它可以用于方法参数级别和方法级别,并且还可以用于处理表单提交时的数据绑定和验证。

  • 绑定请求参数到命令对象:放在功能处理方法的入参上时,用于将多个请求参数绑定到一个命令对象,从而简化绑定流程,而且自动暴露为模型数据用于视图页面展示时使用;
  • 暴露表单引用对象为模型数据:放在处理器的一般方法(非功能处理方法)上时,是为表单准备要展示的表单引用对象,如注册时需要选择的所在城市等,而且在执行功能处理方法(@RequestMapping注解的方法)之前,自动添加到模型对象中,用于视图页面展示时使用;
  • 暴露@RequestMapping方法返回值为模型数据:放在功能处理方法的返回值上时,是暴露功能处理方法的返回值为模型数据,用于视图页面展示时使用。

示例:

@ModelAttribute注解还可以用于处理表单提交时的数据绑定和验证。

例如:

@Controller
@RequestMapping("/users")
public class UserController {
    @RequestMapping(value = "/create", method = RequestMethod.POST)
    public String createUser(@ModelAttribute("user") @Valid User user, BindingResult result) {
        // ...
    }
}

上面的例子中,createUser方法的user参数使用了@ModelAttribute和@Valid注解。@Valid注解用于启用数据验证,BindingResult用于接收验证结果。

( 4 ) @SessionAttributes

@SessionAttributes注解用于将模型中的属性存储到会话中,以便在多个请求之间共享数据。它可以用于控制器类级别和方法级别,并且可以使用@ModelAttribute注解来访问存储在会话中的属性。

@SessionAttributes注解只能使用在类上,用于在多个请求之间传递参数,类似于Session的Attribute,但不完全一样,一般来说@SessionAttributes设置的参数只用于暂时的传递(存入sessionAttributeStore),而不是长期的保存,长期保存的数据还是要放到Session中。

示例:

在处理方法中,可以使用@ModelAttribute注解来访问存储在会话中的属性。

例如:

@Controller
@RequestMapping("/users")
public class UserController {
    @RequestMapping(value = "/edit", method = RequestMethod.GET)
    public String editUser(@ModelAttribute("user") User user) {
        // ...
    }
}

上面的例子中,editUser方法的user参数使用了@ModelAttribute注解,并指定了"user"属性。这意味着在每个请求中,如果会话中有名为"user"的属性,则该属性将绑定到user参数上。

( 5 ) @RequestBody

@RequestBody注解用于将请求体中的数据绑定到方法参数上,主要用于处理POST请求的请求体数据。它可以与其他注解一起使用,例如@Valid注解来进行数据验证。

@RequestBody主要用来接收前端传递给后端的json字符串中的数据的(即请求体中的数据的);

GET方式无请求体,所以使用@RequestBody接收数据时,前端不能使用GET方式提交数据,而是用POST方式进行提交。在后端的同一个接收方法里,@RequestBody与@RequestParam()可以同时使用,@RequestBody最多只能有一个,而@RequestParam()可以有多个。

示例:

@RequestBody注解还可以与其他注解一起使用,例如@Valid注解来进行数据验证。

例如:

@Controller
@RequestMapping("/users")
public class UserController {
    @RequestMapping(value = "/create", method = RequestMethod.POST)
    public String createUser(@RequestBody @Valid User user, BindingResult result) {
        // ...
    }
}

上面的例子中,createUser方法的user参数使用了@RequestBody和@Valid注解。@Valid注解用于启用数据验证,BindingResult用于接收验证结果。

( 6 ) @RequestHeader

@RequestHeader注解用于将请求头中的数据绑定到方法参数上,主要用于获取请求头的信息。它可以用于控制器方法的参数级别,并且可以用于获取各种请求头的信息。

参数 说明
name name 和 value 互为别名,当只有一个参数时,可以省略 value,直接("xxx") 就可以了
value name 和 value 互为别名,当只有一个参数时,可以省略 value,直接("xxx") 就可以了
required 默认情况下,如果请求头中缺少了指定的 name,那么将会报错。 如果没有添加required = false,当请求头中没有这个zking请求头时就会报错。
defaultValue 如果请求头中缺少了指定的 name ,那么会报错,可以使用 defaultValue 这个属性指定默认值,就可以避免报错 ;如果请求头缺少指定 name ,该属性设置的值将会作为默认值,如果该属性不设置值,它有自己的默认值 DEFAULT_NONE

示例:

@RequestHeader注解还可以用于获取其他请求头的信息,例如获取Content-Type、Authorization等。例如:

@Controller
@RequestMapping("/users")
public class UserController {
    @RequestMapping(value = "/info", method = RequestMethod.POST)
    public String updateUserInfo(@RequestHeader("Content-Type") String contentType, 
                                 @RequestHeader("Authorization") String authorization) {
        // ...
    }
}

上面的例子中,updateUserInfo方法使用了@RequestHeader注解,并分别指定了"Content-Type"和"Authorization"。当收到一个POST请求时,请求头中的"Content-Type"和"Authorization"数据将被自动转换为String类型,并分别绑定到contentType和authorization参数上。

( 7 ) @PathVariable

@PathVariable注解用于将URL路径中的变量绑定到方法参数上,主要用于获取URL路径中的动态参数。它可以用于控制器方法的参数级别,并且可以用于获取单个或多个URL路径中的变量。

即 Representational State Transfer。(资源)表现层状态转化。是目前最流行的一种互联网软件架构。它结构清晰、符合标准、易于理解、扩展方便,所以正得到越来越多网站的采用。

  • 资源(Resources):网络上的一个实体,或者说是网络上的一个具体信息。它可以是一段文本、一张图片、一首歌曲、一种服务,总之就是一个具体的存在。可以用一个URI(统一资源定位符)指向它,每种资源对应一个特定的 URI 。要获取这个资源,访问它的URI就可以,因此 URI 即为每一个资源的独一无二的识别符。
  • 表现层(Representation):把资源具体呈现出来的形式,叫做它的表现层(Representation)。比如,文本可以用 txt 格式表现,也可以用 HTML 格式、XML 格式、JSON 格式表现,甚至可以采用二进制格式。
  • 状态转化(State Transfer):每发出一个请求,就代表了客户端和服务器的一次交互过程。HTTP协议,是一个无状态协议,即所有的状态都保存在服务器端。因此,如果客户端想要操作服务器,必须通过某种手段,让服务器端发生状态转化State Transfer)。而这种转化是建立在表现层之上的,所以就是 表现层状态转化。具体说,就是 HTTP 协议里面,四个表示操作方式的动词:GETPOSTPUTDELETE。它们分别对应四种基本操作:GET 用来获取资源,POST 用来新建资源,PUT 用来更新资源,DELETE 用来删除资源。

示例:

@PathVariable注解还可以用于获取多个URL路径中的变量。

例如:

@Controller
@RequestMapping("/users")
public class UserController {
    @RequestMapping(value = "/{id}/info/{name}", method = RequestMethod.GET)
    public String getUserInfo(@PathVariable("id") int userId, 
                              @PathVariable("name") String userName) {
        // ...
    }
}

上面的例子中,getUserInfo方法使用了两个@PathVariable注解,并分别指定了"id"和"name"。当收到一个GET请求时,URL路径中的"id"和"name"变量将被自动转换为int和String类型,并分别绑定到userId和userName参数上。

( 8 ) @CookieValue

@CookieValue注解用于将请求中的Cookie值绑定到方法参数上,主要用于获取Cookie的值。它可以用于控制器方法的参数级别,并且可以用于获取单个或多个Cookie值。

参数 说明
value 绑定的参数名称,String类型。
required 是否必须包含value,boolean类型,默认为 true,表示请求参数中必须包含对应的参数;若不存在,将抛出异常。
defaultValue 默认值,String类型。当没有传参时将使用此值赋值。

示例:

@CookieValue注解用于将请求中的Cookie值绑定到方法参数上,主要用于获取Cookie的值。它可以用于控制器方法的参数级别,并且可以用于获取单个或多个Cookie值。

@CookieValue注解还可以用于获取多个Cookie值。

@Controller
@RequestMapping("/users")
public class UserController {
    @RequestMapping(value = "/info", method = RequestMethod.GET)
    public String getUserInfo(@CookieValue("sessionId") String sessionId, 
                              @CookieValue("userId") int userId) {
        // ...
    }
}

上面的例子中,getUserInfo方法使用了两个@CookieValue注解,并分别指定了"sessionId"和"userId"。当收到一个GET请求时,请求中名为"sessionId"和"userId"的Cookie值将被自动转换为String和int类型,并分别绑定到sessionId和userId参数上。

二、参数转递

以下的实例操作代码,是基于本人博客的扩展续写代码 :  SpringMVC的工作流程及入门

配置项目中的 pom.xml 配置文件 ,以下配置(修改)完后的所有配置

<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>org.example</groupId>
  <artifactId>index</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>war</packaging>
  <name>index Maven Webapp</name>
  <!-- FIXME change it to the project's website -->
  <url>http://www.example.com</url>
  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
    <maven.compiler.plugin.version>3.7.0</maven.compiler.plugin.version>
    <!--添加jar包依赖-->
    <!--1.spring 5.0.2.RELEASE相关-->
    <spring.version>5.0.2.RELEASE</spring.version>
    <!--2.mybatis相关-->
    <mybatis.version>3.4.5</mybatis.version>
    <!--mysql-->
    <mysql.version>5.1.44</mysql.version>
    <!--pagehelper分页jar依赖-->
    <pagehelper.version>5.1.2</pagehelper.version>
    <!--mybatis与spring集成jar依赖-->
    <mybatis.spring.version>1.3.1</mybatis.spring.version>
    <!--3.dbcp2连接池相关 druid-->
    <commons.dbcp2.version>2.1.1</commons.dbcp2.version>
    <commons.pool2.version>2.4.3</commons.pool2.version>
    <!--4.log日志相关-->
    <log4j2.version>2.9.1</log4j2.version>
    <log4j2.disruptor.version>3.2.0</log4j2.disruptor.version>
    <slf4j.version>1.7.13</slf4j.version>
    <!--5.其他-->
    <junit.version>4.12</junit.version>
    <servlet.version>4.0.0</servlet.version>
    <lombok.version>1.18.2</lombok.version>
    <!-- jstl+standard -->
    <jstl.version>1.2</jstl.version>
    <standard.version>1.1.2</standard.version>
    <!-- spring -->
    <spring.version>5.0.2.RELEASE</spring.version>
    <jackson.version>2.9.3</jackson.version>
  </properties>
  <dependencies>
    <!--1.spring相关-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-orm</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-tx</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aspects</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-test</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <!--2.mybatis相关-->
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>${mybatis.version}</version>
    </dependency>
    <!--mysql-->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>${mysql.version}</version>
    </dependency>
    <!--pagehelper分页插件jar包依赖-->
    <dependency>
      <groupId>com.github.pagehelper</groupId>
      <artifactId>pagehelper</artifactId>
      <version>${pagehelper.version}</version>
    </dependency>
    <!--mybatis与spring集成jar包依赖-->
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis-spring</artifactId>
      <version>${mybatis.spring.version}</version>
    </dependency>
    <!--3.dbcp2连接池相关-->
    <dependency>
      <groupId>org.apache.commons</groupId>
      <artifactId>commons-dbcp2</artifactId>
      <version>${commons.dbcp2.version}</version>
    </dependency>
    <dependency>
      <groupId>org.apache.commons</groupId>
      <artifactId>commons-pool2</artifactId>
      <version>${commons.pool2.version}</version>
    </dependency>
    <!-- log4j2日志相关依赖 -->
    <!-- log配置:Log4j2 + Slf4j -->
    <!-- slf4j核心包-->
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-api</artifactId>
      <version>${slf4j.version}</version>
    </dependency>
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>jcl-over-slf4j</artifactId>
      <version>${slf4j.version}</version>
      <scope>runtime</scope>
    </dependency>
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-databind</artifactId>
      <version>${jackson.version}</version>
    </dependency>
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-core</artifactId>
      <version>${jackson.version}</version>
    </dependency>
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-annotations</artifactId>
      <version>${jackson.version}</version>
    </dependency>
    <!--核心log4j2jar包-->
    <dependency>
      <groupId>org.apache.logging.log4j</groupId>
      <artifactId>log4j-api</artifactId>
      <version>${log4j2.version}</version>
    </dependency>
    <dependency>
      <groupId>org.apache.logging.log4j</groupId>
      <artifactId>log4j-core</artifactId>
      <version>${log4j2.version}</version>
    </dependency>
    <!--用于与slf4j保持桥接-->
    <dependency>
      <groupId>org.apache.logging.log4j</groupId>
      <artifactId>log4j-slf4j-impl</artifactId>
      <version>${log4j2.version}</version>
    </dependency>
    <!--web工程需要包含log4j-web,非web工程不需要-->
    <dependency>
      <groupId>org.apache.logging.log4j</groupId>
      <artifactId>log4j-web</artifactId>
      <version>${log4j2.version}</version>
      <scope>runtime</scope>
    </dependency>
    <!--需要使用log4j2的AsyncLogger需要包含disruptor-->
    <dependency>
      <groupId>com.lmax</groupId>
      <artifactId>disruptor</artifactId>
      <version>${log4j2.disruptor.version}</version>
    </dependency>
    <!--5.其他-->
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>${junit.version}</version>
      <!--            <scope>test</scope>-->
    </dependency>
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>${servlet.version}</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <version>${lombok.version}</version>
      <scope>provided</scope>
    </dependency>
    <!-- spring mvc相关依赖 -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>jstl</groupId>
      <artifactId>jstl</artifactId>
      <version>${jstl.version}</version>
    </dependency>
    <dependency>
      <groupId>taglibs</groupId>
      <artifactId>standard</artifactId>
      <version>${standard.version}</version>
    </dependency>
  </dependencies>
  <build>
    <finalName>index</finalName>
    <resources>
      <!--解决mybatis-generator-maven-plugin运行时没有将XxxMapper.xml文件放入target文件夹的问题-->
      <resource>
        <directory>src/main/java</directory>
        <includes>
          <include>**/*.xml</include>
        </includes>
      </resource>
      <!--解决mybatis-generator-maven-plugin运行时没有将jdbc.properites文件放入target文件夹的问题-->
      <resource>
        <directory>src/main/resources</directory>
        <includes>
          <include>jdbc.properties</include>
          <include>*.xml</include>
        </includes>
      </resource>
    </resources>
      <plugins>
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>${maven.compiler.plugin.version}</version>
          <configuration>
            <source>${maven.compiler.source}</source>
            <target>${maven.compiler.target}</target>
            <encoding>${project.build.sourceEncoding}</encoding>
          </configuration>
        </plugin>
        <plugin>
          <groupId>org.mybatis.generator</groupId>
          <artifactId>mybatis-generator-maven-plugin</artifactId>
          <version>1.3.2</version>
          <dependencies>
            <!--使用Mybatis-generator插件不能使用太高版本的mysql驱动 -->
            <dependency>
              <groupId>mysql</groupId>
              <artifactId>mysql-connector-java</artifactId>
              <version>${mysql.version}</version>
            </dependency>
          </dependencies>
          <configuration>
            <overwrite>true</overwrite>
          </configuration>
        </plugin>
        <plugin>
          <artifactId>maven-clean-plugin</artifactId>
          <version>3.1.0</version>
        </plugin>
        <!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging -->
        <plugin>
          <artifactId>maven-resources-plugin</artifactId>
          <version>3.0.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>3.8.0</version>
        </plugin>
        <plugin>
          <artifactId>maven-surefire-plugin</artifactId>
          <version>2.22.1</version>
        </plugin>
        <plugin>
          <artifactId>maven-war-plugin</artifactId>
          <version>3.2.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-install-plugin</artifactId>
          <version>2.5.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-deploy-plugin</artifactId>
          <version>2.8.2</version>
        </plugin>
      </plugins>
  </build>
</project>

创建一个名为 Demo.jsp 的 页面,方便进行演示

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
 <h1>SpringMVC 练习时长两年半</h1>
</body>
</html>

下载相关软件更方便的为我们进行开发(或者直接在相关地址继续下载也可) :  Eolink Apikit

创建一个名为 : ParemController的类继续测试(所有代码如下) :

package com.CloudJun.web;
import com.CloudJun.model.Book;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.util.Map;
/**
 * @author CloudJun
 * @create  2023-09-05 15:03
 */
@Slf4j
@Controller
@RequestMapping("/Cloud")
public class ParemController {
    @RequestMapping("/Jun")
    public String index(String bname,Integer bid){
        log.info("简单类型的参数:bname:{},bid:{}",bname,bid);
        return "demo";
    }
    @RequestMapping("/Jun01")
    public String index01(Book book, HttpServletRequest request){
        log.info("复杂类型的参数:book:{}",
                request.getParameter("bname"),
                request.getParameter("bid"));
        log.info("复杂类型的参数:book:{}",
                book.toString());
        return "demo";
    }
    @RequestMapping("/Jun02")
    public String index02(
            @RequestParam String bname,
            @RequestParam(required = false)Integer bid){
        log.info("@RequestParam的参数:bname:{},bid:{}",bname,bid);
        return "demo";
    }
    @RequestMapping("/Jun03/{bid}")
    public String index03(
            @PathVariable("bid") Integer bid){
        log.info("@PathVariable参数:bid:{}",bid);
        return "demo";
    }
    @RequestMapping("/Jun04")
    public String index04(Map map){
        log.info("@RequestBody:map:{}",map);
        return "demo";
    }
    @RequestMapping("/Jun05")
    public String index05(@RequestBody Map map){
        log.info("@RequestBody 参数:map:{}",map);
        return "demo";
    }
    @RequestMapping("/Jun06")
    public String index06(
            Book book,
            @RequestBody Map map,
            @RequestHeader("string") String string){
        log.info("@Book 参数:Book:{}",book);
        log.info("@RequestBody 参数:map:{}",map);
        log.info("@RequestHeader 参数:string:{}",string);
        return "demo";
    }
    @GetMapping
    public String type01(){
        System.out.println("@GetMapping:对应查询请求");
        return "demo";
    }
    @PostMapping
    public String type02(){
        System.out.println("@PostMapping:对应新增请求");
        return "demo";
    }
    @PutMapping
    public String type03(){
        System.out.println("@PutMapping:对应修改请求");
        return "demo";
    }
    @DeleteMapping
    public String type04(){
        System.out.println("@DeleteMapping:对应删除请求");
        return "demo";
    }
}

2.1 基础类型

启动服务器后,在浏览器中请求以下地址继续测试基础类型传参 :

http://localhost:8080/index/Cloud/Jun?bname=斗破&bid=2

(该请求地址是根据自己的注解配置来进行输入方可)

结果如图 :

2.2 复杂类型

启动服务器后,在浏览器中请求以下地址继续测试基础类型传参 :

http://localhost:8080/index/Cloud/Jun01?bid=1&bname=Ikun&price=99.9

(该请求地址是根据自己的注解配置来进行输入方可)

结果如图  :

2.3 @RequestParam

启动服务器后,在浏览器中请求以下地址继续测试基础类型传参 :

http://localhost:8080/index/Cloud/Jun02?bid=1&bname=斗破

(该请求地址是根据自己的注解配置来进行输入方可)

结果如图 :

如果必须携带的参数没有携带,就会报以下错误 :

@RequestParamd 相对应对请求地址携带参数继续约束

2.4 @PathVariable

启动服务器后,在浏览器中请求以下地址继续测试基础类型传参 :

http://localhost:8080/index/Cloud/Jun03/5

(该请求地址是根据自己的注解配置来进行输入方可)

结果如图 :

@PathVariable 继续请求地址上的传递参数

2.5 @RequestBody

这里我们需要在Eolink Apikit软件工具上进行测试请求地址

启动服务器后,在Eolink Apikit软件工具中请求以下地址继续测试基础类型传参 :

http://localhost:8080/index/Cloud/Jun03/5

(该请求地址是根据自己的注解配置来进行输入方可)

结果如图 :

请求地址Jun04无法传参是因为没@RequestBody注解,这已是@RequestBody注解作用

2.6 @RequestHeader

在请求地址前如图增加携带的参数进行参数传参

最后请求的地址为:  http://localhost:8080/index/Cloud/Jun06?bid=2&bname=斗破

(该请求地址是根据自己的注解配置来进行输入方可)

请求结果如图 :

               

2.7 请求方法

@GetMapping

public String type01(){

   System.out.println("@GetMapping:对应查询请求");

   return "demo";

}


@PostMapping

public String type02(){

   System.out.println("@PostMapping:对应新增请求");

   return "demo";

}

@PutMapping

public String type03(){

   System.out.println("@PutMapping:对应修改请求");

   return "demo";

}

@DeleteMapping

public String type04(){

   System.out.println("@DeleteMapping:对应删除请求");

   return "demo";

}


对以下四个方法分别进行请求,请求该方法相对应的请求方式进行参数

(该请求地址是根据自己的注解配置来进行输入方可)

请求地址为 : http://localhost:8080/index/Cloud

依次进行请求,请求的方式不同会进行不同的请求注解

三、返回值

创建一个ResponseUtil工具类,辅助完成测试代码如下 :

package com.CloudJun.utils;
import java.io.PrintWriter;
import javax.servlet.http.HttpServletResponse;
import com.fasterxml.jackson.databind.ObjectMapper;
public class ResponseUtil {
  public static void write(HttpServletResponse response,Object o)throws Exception{
    response.setContentType("text/html;charset=utf-8");
    PrintWriter out=response.getWriter();
    out.println(o.toString());
    out.flush();
    out.close();
  }
  public static void writeJson(HttpServletResponse response,Object o)throws Exception{
    ObjectMapper om = new ObjectMapper();
//    om.writeValueAsString(o)代表了json串
    write(response, om.writeValueAsString(o));
  }
}

创建一个ReturnController类,来进行方法的请求测试(包含关于返回值的所以方法)。

package com.CloudJun.web;
import com.CloudJun.utils.ResponseUtil;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;
/**
 * @author CloudJun
 * @create  2023-09-05 19:03
 */
@Controller
@RequestMapping("/rs")
public class ReturnController {
    @RequestMapping("/test01")
    public void Test01(HttpServletResponse response) throws Exception {
        Map<String,Object> map = new HashMap<String,Object>();
        map.put("id",1);
        map.put("小黑子","坤坤");
        map.put("Ikun","增加成功。。。");
        ResponseUtil.writeJson(response,map);
    }
    @ResponseBody
    @RequestMapping("/test02")
    public Map Test02(HttpServletResponse response) throws Exception {
        Map<String,Object> map = new HashMap<String,Object>();
        map.put("id",1);
        map.put("小黑子","坤坤");
        map.put("Ikun","增加成功。。。");
        return map;
    }
    @RequestMapping("/test03")
    public String Test03() {
        return "index";
    }
    @RequestMapping("/test04")
    public String Test04(
            Model model,
            HttpServletRequest request) {
        model.addAttribute("name","斗破");
        request.setAttribute("chapter","开局送老婆");
        return "index";
    }
    @RequestMapping("/test05")
    public ModelAndView Test05() {
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.addObject("name","斗破");
        modelAndView.addObject("chapter","得挂双飞");
        modelAndView.setViewName("index");
        return modelAndView;
    }
}

创建一个index.jsp页面进行显示测试:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <h1>SpringMVC-----独孤不爱</h1>
    书籍名称:  ${name}<br>
    章节名称:  ${chapter}
</body>
</html>

3.1 void

开启服务器,在浏览器请求地址栏中输入以下请求地址

localhost:8080/index/rs/test01localhost:8080/index/rs/test01 (该请求地址是根据自己的注解配置来进行输入方可)localhost:8080/index/rs/test01

执行测试的结果为:

3.2 String

开启服务器,在浏览器请求地址栏中输入以下请求地址

localhost:8080/index/rs/test02 (该请求地址是根据自己的注解配置来进行输入方可)

执行测试的结果为:

3.3 String+Model

开启服务器,在浏览器请求地址栏中输入以下请求地址

localhost:8080/index/rs/test03 (该请求地址是根据自己的注解配置来进行输入方可)

执行测试的结果为:

Model 测试

开启服务器,在浏览器请求地址栏中输入以下请求地址

localhost:8080/index/rs/test04 (该请求地址是根据自己的注解配置来进行输入方可)

执行测试的结果为:

3.4 ModelAndView

开启服务器,在浏览器请求地址栏中输入以下请求地址

localhost:8080/index/rs/test05 (该请求地址是根据自己的注解配置来进行输入方可)

执行测试的结果为:

四、页面跳转

创建一个PathConterller测试类,进行页面跳转的各种方法测试,代码如下:

package com.CloudJun.web;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;
/**
 * @author CloudJun
 * @create  2023-09-05 19:32
 */
@Controller
@RequestMapping("/pa")
public class PathConterller {
    @ResponseBody
    @RequestMapping("/test02")
    public Map Test02(HttpServletResponse response) throws Exception {
        Map<String,Object> map = new HashMap<String,Object>();
        map.put("id",1);
        map.put("小黑子","坤坤");
        map.put("Ikun","增加成功。。。");
        return map;
    }
    //返回值中有转发(forward)和重定向(redirect)这两种跳转方式将会绕开视图解析器的前缀和后缀
    //转发到(当前类)的某一个方法
    @RequestMapping("/Demo01")
    public String Demo01(){
        System.out.println("请求地址:Demo01");
        System.out.println("转发到(当前类)的某一个方法");
        return "forward:test02";
    }
    //转发到(其他类)的某一个方法
    @RequestMapping("/Demo02")
    public String Demo02(){
        System.out.println("请求地址:Demo02");
        System.out.println("转发到(其他类)的某一个方法");
        return "forward:/rs/test04";
    }
    //重定向到(其他类)的某一个方法
    @RequestMapping("/Demo03")
    public String Demo03(){
        System.out.println("请求地址:Demo03");
        System.out.println("重定向到(其他类)的某一个方法");
        return "redirect:test02";
    }
    //重定向到(其他类)的某一个方法
    @RequestMapping("/Demo04")
    public String Demo04(){
        System.out.println("请求地址:Demo04");
        System.out.println("重定向到(其他类)的某一个方法");
        return "redirect:/rs/test04";
    }
}

4.1 转发

它相当于“request.getRequestDispatcher("url").forward(request,response)”。使用转发,既可以转发到jsp, 也可以转发到其他的控制器方法。

开启服务器,在浏览器请求地址栏中输入以下请求地址

localhost:8080/index/pa/Demo01(该请求地址是根据自己的注解配置来进行输入方可)

执行测试的结果为 :

开启服务器,在浏览器请求地址栏中输入以下请求地址

localhost:8080/index/pa/Demo02(该请求地址是根据自己的注解配置来进行输入方可)

执行测试的结果为 :

4.2 重定向

它相当于“response.sendRedirect(url)”。需要注意的是,如果重定向到jsp页面,则jsp页面不能写在WEB-INF目录中,否则无法找到。

开启服务器,在浏览器请求地址栏中输入以下请求地址

localhost:8080/index/pa/Demo03(该请求地址是根据自己的注解配置来进行输入方可)

执行测试的结果为 :

开启服务器,在浏览器请求地址栏中输入以下请求地址

localhost:8080/index/pa/Demo04(该请求地址是根据自己的注解配置来进行输入方可)

执行测试的结果为 :  

给我们带来什么收获

学习SpringMVC中的常用注解和参数传递及返回值可以带来以下收获:

  • 1. 简化开发:SpringMVC中的注解可以帮助开发人员简化代码编写,减少样板代码的数量,提高开发效率。
  • 2. 提高可读性:使用注解可以使代码更加清晰易懂,提高代码的可读性和可维护性。
  • 3. 方便参数传递:SpringMVC中的参数传递方式多样化,可以通过注解直接将请求参数绑定到方法的参数上,避免了手动解析请求参数的繁琐过程。
  • 4. 强大的参数校验功能:SpringMVC提供了强大的参数校验功能,可以通过注解对请求参数进行校验,确保参数的合法性。
  • 5. 灵活的返回值处理:SpringMVC支持多种返回值类型,可以根据实际需求返回不同类型的数据,如JSON、XML、视图等。
  • 6. 支持RESTful风格:SpringMVC对RESTful风格的支持非常友好,可以通过注解实现资源的增删改查操作,提高API的可用性和易用性。
  • 7. 异常处理:SpringMVC提供了全局异常处理的机制,可以通过注解统一处理异常,避免代码中出现大量的try-catch块。

总之,学习SpringMVC中的常用注解和参数传递及返回值可以让开发人员更加方便地进行Web开发,提高开发效率,减少重复劳动,提高代码质量。

                                           

相关实践学习
部署Stable Diffusion玩转AI绘画(GPU云服务器)
本实验通过在ECS上从零开始部署Stable Diffusion来进行AI绘画创作,开启AIGC盲盒。
目录
相关文章
|
6月前
|
前端开发 JavaScript Java
JAVAEE框架技术之4springMVC入门
JAVAEE框架技术之4springMVC入门
132 0
JAVAEE框架技术之4springMVC入门
|
11月前
|
XML 存储 Java
SpringMVC中支持的那些视图解析技术
SpringMVC中支持的那些视图解析技术
109 0
|
前端开发 Java Go
Spring MVC 中的数据验证技术
Spring MVC 中的数据验证技术
97 0
|
2月前
|
前端开发 安全 Java
技术进阶:使用Spring MVC构建适应未来的响应式Web应用
【9月更文挑战第2天】随着移动设备的普及,响应式设计至关重要。Spring MVC作为强大的Java Web框架,助力开发者创建适应多屏的应用。本文推荐使用Thymeleaf整合视图,通过简洁的HTML代码提高前端灵活性;采用`@ResponseBody`与`Callable`实现异步处理,优化应用响应速度;运用`@ControllerAdvice`统一异常管理,保持代码整洁;借助Jackson简化JSON处理;利用Spring Security增强安全性;并强调测试的重要性。遵循这些实践,将大幅提升开发效率和应用质量。
63 7
|
6月前
|
前端开发 Java Apache
JAVAEE框架技术之6-springMVC拦截器和文件上传功能
JAVAEE框架技术之6-springMVC拦截器和文件上传功能
101 0
JAVAEE框架技术之6-springMVC拦截器和文件上传功能
序-Servlet和SpringMVC的联系和区别-配置路径先想好使用的使用的方法,然后匹配的需要的技术
序-Servlet和SpringMVC的联系和区别-配置路径先想好使用的使用的方法,然后匹配的需要的技术
|
5月前
|
JSON Java 数据库
技术笔记:SpringMVC常用注解
技术笔记:SpringMVC常用注解
|
6月前
|
前端开发 Java API
饼干探秘:深入Spring MVC中获取Cookie数据的技术解析
饼干探秘:深入Spring MVC中获取Cookie数据的技术解析
68 3
|
6月前
|
JSON 前端开发 JavaScript
JAVAEE框架技术之5-springMVC参数绑定和异步交互
JAVAEE框架技术之5-springMVC参数绑定和异步交互
73 0
JAVAEE框架技术之5-springMVC参数绑定和异步交互
|
前端开发 Java 应用服务中间件
【小家Spring】高性能关键技术之---体验Spring MVC的异步模式(Callable、WebAsyncTask、DeferredResult) 基础使用篇(上)
【小家Spring】高性能关键技术之---体验Spring MVC的异步模式(Callable、WebAsyncTask、DeferredResult) 基础使用篇(上)
【小家Spring】高性能关键技术之---体验Spring MVC的异步模式(Callable、WebAsyncTask、DeferredResult) 基础使用篇(上)