【SpringBoot】15 核心功能 - Web开发原理 - 请求处理 - 常用请求参数注解

文章目录


一、常用参数纾解

1、注解

@PathVariable@RequestHeader@ModelAttribute@RequestParam@MatrixVariable@CookieValue@RequestBody

2、Servlet API

WebRequestServletRequestMultipartRequestHttpSessionjavax.servlet.http.PushBuilderPrincipalInputStreamReaderHttpMethodLocaleTimeZoneZoneId

3、复杂参数

MapErrors/BindingResultModelRedirectAttributesServletResponseSessionStatusUriComponentsBuilderServletUriComponentsBuilder

4、自定义对象参数

可以自动类型转换与格式化,可以级联封装。

二、@PathVariable注解

1、代码测试

新建一个Controller

c 复制代码
package com.web.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;

@RestController
public class ParameterTestController {

    // /car/1/owner/zhangsan
    @GetMapping("/car/{id}/owner/{username}")
    public Map<String, Object> getCar(@PathVariable("id") Integer id,
                                      @PathVariable("username") String username,
                                      @PathVariable Map<String, String> pv){

        Map<String, Object> map = new HashMap<>();
        map.put("id", id);
        map.put("username", username);
        map.put("pv", pv);
        return  map;
    }
}

首页文件index添加访问路径

c 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>Hello,欢迎您!</h1>

测试REST风格
<form action="/user" method="get">
    <input value="REST-GET 提交" type="submit"/>
</form>
<form action="/user" method="post">
    <input value="REST-POST 提交" type="submit"/>
</form>

测试put和delete请求
<form action="/user" method="post">
    <input type="hidden" name="_method" value="put">
    <input type="submit" value="Submit PUT">
</form>

<form action="/user" method="post">
    <input type="hidden" name="_method" value="delete">
    <input type="submit" value="Submit DELETE">
</form>

测试基本请求注解
<ul>
    <a href="car/3/owner/lisi">car/{id}/owner/{username}</a>
    <li>@PathVariable (路径变量)</li>

</ul>

</body>
</html>

点击链接,访问李四

2、过程原理

@PathVariable 注解讲解

@PathVariable 是 Spring MVC 中的一个注解,用于从 URL 路径中提取变量值,并将其绑定到控制器方法的参数上。它通常与 RESTful 风格的 URL 设计一起使用,使 URL 更加简洁和语义化。


1. 代码解析

控制器方法
java 复制代码
@GetMapping("/car/{id}/owner/{username}")
public Map<String, Object> getCar(
    @PathVariable("id") Integer id,
    @PathVariable("username") String username,
    @PathVariable Map<String, String> pv
) {
    Map<String, Object> map = new HashMap<>();
    map.put("id", id);
    map.put("username", username);
    map.put("pv", pv);
    return map;
}
HTML 链接
html 复制代码
<a href="car/3/owner/lisi">car/{id}/owner/{username}</a>

2. @PathVariable 的作用

  • 从 URL 路径中提取变量

    • URL 模板 /car/{id}/owner/{username} 定义了两个路径变量:
      • {id}:表示汽车的 ID。
      • {username}:表示车主的用户名。
    • 当用户访问 /car/3/owner/lisi 时:
      • id 会被解析为 3Integer 类型)。
      • username 会被解析为 "lisi"String 类型)。
  • 绑定到方法参数

    • @PathVariable("id") Integer id:将 URL 中的 {id} 绑定到 id 参数。
    • @PathVariable("username") String username:将 URL 中的 {username} 绑定到 username 参数。
    • @PathVariable Map<String, String> pv:将所有路径变量收集到一个 Map 中,键为变量名,值为解析后的字符串。

3. 运行流程

  1. 用户访问 URL

    • 例如,用户访问 http://localhost:8080/car/3/owner/lisi
  2. Spring MVC 解析 URL

    • 根据 @GetMapping("/car/{id}/owner/{username}") 匹配 URL。
    • 提取 id=3username=lisi
  3. 绑定到方法参数

    • id3Integer 类型)。
    • username"lisi"String 类型)。
    • pv{"id": "3", "username": "lisi"}Map<String, String>)。
  4. 返回结果

    • 控制器方法返回一个 Map,Spring 将其转换为 JSON 响应:

      json 复制代码
      {
          "id": 3,
          "username": "lisi",
          "pv": {
              "id": "3",
              "username": "lisi"
          }
      }

4. 关键点

(1) 变量名匹配
  • @PathVariable 的值(如 "id""username")必须与 URL 模板中的变量名一致。
  • 如果省略 @PathVariable 的值(如 @PathVariable Integer id),Spring 会尝试根据方法参数名自动匹配。
(2) 类型转换
  • Spring 会自动尝试将路径变量的字符串值转换为目标类型(如 IntegerLong 等)。
  • 如果转换失败(例如 id 是非数字字符串),会抛出 TypeMismatchException
(3) @PathVariable Map
  • @PathVariable Map<String, String> pv 会收集所有路径变量,键为变量名,值为字符串。
  • 适用于动态路径变量或不确定变量名的情况。

5. 对比其他注解

注解 作用 示例
@PathVariable 从 URL 路径中提取变量 /car/{id}id
@RequestParam 从请求参数中提取值 ?id=3id
@RequestHeader 从请求头中提取值 Host: localhost:8080Host
@CookieValue 从 Cookie 中提取值 JSESSIONID=xxxJSESSIONID

6. 小结

  • @PathVariable 的作用:从 URL 路径中提取变量值,并绑定到方法参数。
  • 适用场景:RESTful 风格的 URL 设计,例如 /car/{id}/owner/{username}
  • 注意事项:
    • 确保 @PathVariable 的变量名与 URL 模板一致。
    • Spring 会自动进行类型转换,但需确保路径变量的值合法。
    • 可以使用 Map 收集所有路径变量,适用于动态场景。

通过 @PathVariable,Spring MVC 可以轻松实现 RESTful 风格的 URL 解析,使接口更加清晰和易用。

三、@RequestHeader注解

1、代码

请求头注解

controller

c 复制代码
package com.web.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;

@RestController
public class ParameterTestController {

    // /car/1/owner/zhangsan
    @GetMapping("/car/{id}/owner/{username}")
    public Map<String, Object> getCar(@PathVariable("id") Integer id,
                                      @PathVariable("username") String username,
                                      @PathVariable Map<String, String> pv,
                                      @RequestHeader("User-Agent") String userAgent,
                                      @RequestHeader Map<String, String> headers){

        Map<String, Object> map = new HashMap<>();
        map.put("id", id);
        map.put("username", username);
        map.put("pv", pv);
        map.put("userAgent", userAgent);
        map.put("headers", headers);
        return  map;
    }
}

首页index

c 复制代码
测试基本请求注解
<ul>
    <a href="car/3/owner/lisi">car/{id}/owner/{username}</a>
    <li>@PathVariable (路径变量)</li>
    <li>@RequestHeader (获取请求头)</li>
</ul>

2、原理讲解

@RequestHeader 注解讲解

@RequestHeader 是 Spring MVC 中的一个注解,用于从 HTTP 请求头中提取值,并将其绑定到控制器方法的参数上。它适用于需要获取客户端发送的请求头信息的场景,例如获取浏览器类型、认证信息等。


1. 代码解析

控制器方法
java 复制代码
@GetMapping("/example")
public Map<String, Object> example(
    @RequestHeader("User-Agent") String userAgent,  // 提取 "User-Agent" 请求头
    @RequestHeader Map<String, String> headers      // 提取所有请求头
) {
    Map<String, Object> map = new HashMap<>();
    map.put("userAgent", userAgent);  // 存储 "User-Agent" 的值
    map.put("headers", headers);      // 存储所有请求头
    return map;
}
运行流程
  1. 客户端发送 HTTP 请求

    • 例如,浏览器发送一个请求,包含以下请求头:

      复制代码
      User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) ...
      Accept: text/html,application/xhtml+xml,...
      Host: localhost:8080
  2. Spring MVC 解析请求头

    • @RequestHeader("User-Agent") String userAgent
      • 提取 User-Agent 请求头的值,并绑定到 userAgent 参数。
    • @RequestHeader Map<String, String> headers
      • 提取所有请求头,存储为一个 Map,键为请求头名称,值为请求头内容。
  3. 返回结果

    • 控制器方法返回一个 Map,Spring 将其转换为 JSON 响应:

      json 复制代码
      {
          "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) ...",
          "headers": {
              "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) ...",
              "Accept": "text/html,application/xhtml+xml,...",
              "Host": "localhost:8080"
          }
      }

2. @RequestHeader 的作用

  • 提取特定请求头

    • @RequestHeader("User-Agent") String userAgent
      • 从 HTTP 请求头中提取 User-Agent 的值,并绑定到 userAgent 参数。
      • 适用于需要获取特定请求头信息的场景,例如判断客户端浏览器类型。
  • 提取所有请求头

    • @RequestHeader Map<String, String> headers
      • 将所有请求头存储到一个 Map 中,键为请求头名称,值为请求头内容。
      • 适用于需要遍历或调试所有请求头的场景。

3. 关键点

(1) 请求头名称匹配

  • @RequestHeader("User-Agent") 的值必须与 HTTP 请求头名称完全一致(区分大小写)。
  • 如果请求头不存在,Spring 会抛出 HttpMessageNotReadableException

(2) 类型转换

  • @RequestHeader 默认将请求头值绑定为 String 类型。
  • 如果需要其他类型(如 intboolean),Spring 会尝试自动转换,但需确保请求头值合法。

(3) @RequestHeader Map

  • @RequestHeader Map<String, String> headers 会收集所有请求头,适用于动态或未知请求头的情况。
  • 适用于调试或日志记录场景。

4. 常见请求头示例

请求头名称 作用 示例值
User-Agent 标识客户端信息(浏览器、操作系统等) Mozilla/5.0 ...
Accept 客户端可接收的内容类型 text/html,application/xhtml+xml,...
Authorization 认证信息 Bearer xxx
Host 请求的目标主机 localhost:8080

5. 对比其他注解

注解 作用 示例
@RequestHeader 从请求头中提取值 User-Agent → 浏览器信息
@PathVariable 从 URL 路径中提取变量 /car/{id}id
@RequestParam 从请求参数中提取值 ?id=3id
@CookieValue 从 Cookie 中提取值 JSESSIONID=xxxJSESSIONID

6. 小结

  • @RequestHeader 的作用:从 HTTP 请求头中提取值,并绑定到方法参数。
  • 适用场景:
    • 获取客户端浏览器信息(User-Agent)。
    • 获取认证信息(Authorization)。
    • 调试或记录所有请求头。
  • 注意事项:
    • 确保请求头名称正确。
    • 如果请求头可能不存在,可以使用 required=false 属性(如 @RequestHeader(value="X-Custom", required=false))。

通过 @RequestHeader,Spring MVC 可以轻松获取 HTTP 请求头信息,使接口更加灵活和强大。

四、@RequestParam注解

1、代码

控制器

c 复制代码
package com.web.controller;

import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
public class ParameterTestController {

    // /car/1/owner/zhangsan
    @GetMapping("/car/{id}/owner/{username}")
    public Map<String, Object> getCar(@PathVariable("id") Integer id,
                                      @PathVariable("username") String username,
                                      @PathVariable Map<String, String> pv,
                                      @RequestHeader("User-Agent") String userAgent,
                                      @RequestHeader Map<String, String> headers,
                                      @RequestParam("age") Integer age,
                                      @RequestParam("inters") List<String> inters,
                                      @RequestParam Map<String, String> params){

        Map<String, Object> map = new HashMap<>();
//        map.put("id", id);
//        map.put("username", username);
//        map.put("pv", pv);
//        map.put("userAgent", userAgent);
//        map.put("headers", headers);
        map.put("age", age);
        map.put("inters", inters);
        map.put("params", params);
        return  map;
    }
}

首页

c 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>Hello,欢迎您!</h1>

测试REST风格
<form action="/user" method="get">
    <input value="REST-GET 提交" type="submit"/>
</form>
<form action="/user" method="post">
    <input value="REST-POST 提交" type="submit"/>
</form>

测试put和delete请求
<form action="/user" method="post">
    <input type="hidden" name="_method" value="put">
    <input type="submit" value="Submit PUT">
</form>

<form action="/user" method="post">
    <input type="hidden" name="_method" value="delete">
    <input type="submit" value="Submit DELETE">
</form>

测试基本请求注解
<ul>
    <a href="car/3/owner/lisi?age=18&inters=basketball&inters=game">car/{id}/owner/{username}</a>
    <li>@PathVariable (路径变量)</li>
    <li>@RequestHeader (获取请求头)</li>
    <li>@RequestParam (获取请求参数)</li>
</ul>

</body>
</html>

运行结果

2、@RequestParam原理

@RequestParam 注解讲解

@RequestParam 是 Spring MVC 中用于从 HTTP 请求参数中提取值并绑定到控制器方法参数的注解。它适用于处理 URL 查询参数(即 ?key=value 形式的数据),常用于获取客户端提交的表单数据或附加在 URL 后的参数。


1. 代码解析

控制器方法
java 复制代码
@GetMapping("/car/{id}/owner/{username}")
public Map<String, Object> getCar(
    @RequestParam("age") Integer age,                     // 提取单个请求参数 "age"
    @RequestParam("inters") List<String> inters,          // 提取多个同名请求参数 "inters"
    @RequestParam Map<String, String> params               // 提取所有请求参数
) {
    Map<String, Object> map = new HashMap<>();
    map.put("age", age);
    map.put("inters", inters);
    map.put("params", params);
    return map;
}
对应的 HTML 链接
html 复制代码
<a href="car/3/owner/lisi?age=18&inters=basketball&inters=game">car/{id}/owner/{username}</a>

在这个链接中:

  • age=18 是一个普通的请求参数。
  • inters=basketball&inters=game 是两个同名的请求参数,值分别为 basketballgame

2. @RequestParam 的作用

  • 提取单个请求参数
    @RequestParam("age") Integer age

    从请求参数中提取名为 age 的值,并转换为 Integer 类型,绑定到 age 参数。

    如果请求中不包含 age 参数,且未设置 required=false,Spring 会抛出 MissingServletRequestParameterException

  • 提取多个同名请求参数
    @RequestParam("inters") List<String> inters

    当有多个同名请求参数时(如 inters=basketball&inters=game),Spring 会将它们收集到一个 List 中。

    适用于处理多值参数,例如复选框提交的数据。

  • 提取所有请求参数
    @RequestParam Map<String, String> params

    将所有请求参数存储到一个 Map 中,键为参数名,值为参数值(如果有多个同名参数,值会是最后一个参数的值,若要获取所有值,需使用 MultiValueMap)。

    适用于需要遍历或调试所有请求参数的场景。


3. 运行流程

  1. 客户端发送 HTTP 请求

    例如,用户访问 http://localhost:8080/car/3/owner/lisi?age=18&inters=basketball&inters=game

  2. Spring MVC 解析请求参数

    • 提取 age=18,转换为 Integer 类型,绑定到 age 参数。
    • 提取 inters=basketballinters=game,收集到 List<String> 中,绑定到 inters 参数。
    • 提取所有请求参数,存储到 Map<String, String> 中,绑定到 params 参数。
  3. 返回结果

    控制器方法返回一个 Map,Spring 将其转换为 JSON 响应:

    json 复制代码
    {
        "age": 18,
        "inters": ["basketball", "game"],
        "params": {
            "age": "18",
            "inters": "game"  // 注意:普通 Map 只会保留最后一个同名参数的值
        }
    }

    如果需要获取所有同名参数的值,建议使用 MultiValueMap


4. 关键点

(1) 参数名匹配

  • @RequestParam("age") 的值必须与请求参数名称完全一致。
  • 如果请求参数名称与方法参数名相同,可以省略注解值,如 @RequestParam Integer age

(2) 参数是否必需

  • 默认情况下,请求参数是必需的。如果请求中缺少必需的参数,Spring 会抛出异常。
  • 可以通过 required=false 设置参数为可选,如 @RequestParam(value = "age", required = false) Integer age
  • 如果参数为可选且未提供,绑定值为 ``。

(3) 默认值

  • 可以使用 defaultValue 属性为请求参数设置默认值,如 @RequestParam(defaultValue = "0") Integer age
  • 如果请求中未提供该参数,将使用默认值。

(4) 类型转换

  • Spring 会自动将请求参数的字符串值转换为目标类型(如 IntegerBoolean 等)。
  • 如果转换失败,会抛出 TypeMismatchException

(5) 处理多值参数

  • 对于同名请求参数,使用 ListMultiValueMap 来接收所有值。
  • 例如,使用 @RequestParam MultiValueMap<String, String> params 可以获取所有参数名和对应的多个值。

5. 对比其他注解

注解 作用 示例
@RequestParam 从请求参数中提取值 ?age=18age
@PathVariable 从 URL 路径中提取变量 /car/{id}id
@RequestHeader 从请求头中提取值 User-Agent → 浏览器信息
@CookieValue 从 Cookie 中提取值 JSESSIONID=xxxJSESSIONID

6. 小结

  • @RequestParam 的作用:从 HTTP 请求参数中提取值,并绑定到方法参数。
  • 适用场景:
    • 处理表单提交的数据。
    • 处理 URL 查询参数。
    • 处理多值参数(如复选框)。
  • 注意事项:
    • 确保请求参数名称正确。
    • 合理设置参数的 requireddefaultValue 属性。
    • 对于多值参数,使用 ListMultiValueMap 来接收。

通过 @RequestParam,Spring MVC 可以方便地处理 HTTP 请求参数,使接口更加灵活和易用。

五、其他注解

以下是基于你提供的代码示例风格,针对 @CookieValue@RequestBody@RequestAttribute 的示例代码,结合你的 ParameterTestController 结构进行编写:


1. @CookieValue 示例

场景:从 Cookie 中获取客户端的会话 ID 或其他信息。

java 复制代码
@RestController
public class ParameterTestController {

    @GetMapping("/cookie")
    public Map<String, String> getCookie(
            @CookieValue(value = "JSESSIONID", required = false) String sessionId) {
        
        Map<String, String> result = new HashMap<>();
        result.put("JSESSIONID", sessionId != ? sessionId : "未找到Cookie");
        return result;
    }
}

说明:

  • @CookieValue("JSESSIONID") 提取名为 JSESSIONID 的 Cookie 值。
  • required = false 表示 Cookie 可以不存在,避免抛出异常。
  • 返回一个 Map,包含提取的 Cookie 值。

2. @RequestBody 示例

场景:接收客户端提交的 JSON 请求体,并反序列化为 Java 对象。

java 复制代码
@RestController
public class ParameterTestController {

    @PostMapping("/user")
    public Map<String, Object> createUser(@RequestBody User user) {
        Map<String, Object> result = new HashMap<>();
        result.put("status", "success");
        result.put("user", user); // 返回接收到的用户对象
        return result;
    }

    // 示例用户类
    public static class User {
        private String name;
        private int age;

        // 必须提供 getter/setter,否则无法反序列化
        public String getName() { return name; }
        public void setName(String name) { this.name = name; }
        public int getAge() { return age; }
        public void setAge(int age) { this.age = age; }

        @Override
        public String toString() {
            return "User{name='" + name + "', age=" + age + "}";
        }
    }
}

说明:

  • @RequestBody 将请求体中的 JSON 反序列化为 User 对象。

  • 客户端需发送类似以下 JSON:

    json 复制代码
    {
        "name": "张三",
        "age": 25
    }
  • 返回的 Map 包含处理状态和接收到的用户对象。


3. @RequestAttribute 示例

场景:从请求属性中获取前置处理(如拦截器)设置的值。

java 复制代码
@RestController
public class ParameterTestController {

    @GetMapping("/attribute")
    public Map<String, String> getAttribute(
            @RequestAttribute("customAttr") String customAttr) {
        
        Map<String, String> result = new HashMap<>();
        result.put("customAttr", customAttr);
        return result;
    }
}

配套拦截器示例(用于设置请求属性):

java 复制代码
@Component
public class CustomInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        // 在请求属性中设置一个值
        request.setAttribute("customAttr", "拦截器设置的值");
        return true;
    }
}

配置拦截器(在 Spring Boot 配置类中):

java 复制代码
@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Autowired
    private CustomInterceptor customInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(customInterceptor);
    }
}

说明:

  • 拦截器在请求处理前设置了一个请求属性 customAttr
  • 控制器通过 @RequestAttribute("customAttr") 获取该属性值。
  • 适用于在请求处理链中传递数据(如用户权限信息)。

示例总结

注解 示例方法 数据来源 典型用途
@CookieValue getCookie HTTP Cookie 获取客户端会话 ID 或其他 Cookie 信息
@RequestBody createUser HTTP 请求体 接收客户端提交的 JSON/XML 数据
@RequestAttribute getAttribute 请求域属性 访问拦截器/过滤器设置的请求属性

通过这些示例,可以清晰地看到不同注解在处理 HTTP 请求时的应用场景和用法。

总结

注解 数据来源 主要用途 典型使用场景 关键特性
@PathVariable URL 路径变量 从 RESTful 风格 URL 的路径中提取变量值 /car/{id} 提取 id - 支持单个变量和批量提取(Map) - 自动类型转换 - 变量名需与 URL 模板匹配
@RequestHeader HTTP 请求头 提取特定请求头或所有请求头信息 获取 User-AgentAuthorization - 支持单个头字段和批量提取(Map) - 请求头不存在时可设置 required=false
@RequestParam URL 查询参数 提取单个查询参数、多值参数或所有查询参数 ?age=18&inters=game 提取参数 - 支持参数可选性(required=false) - 可设置默认值(defaultValue) - 多值参数使用 ListMultiValueMap
@CookieValue HTTP Cookie 从 Cookie 中提取特定值 获取会话 ID(JSESSIONID - 支持 Cookie 不存在时的可选处理(required=false) - 直接绑定到方法参数
@RequestBody HTTP 请求体 将请求体反序列化为 Java 对象 接收 JSON/XML 数据并映射到对象 - 依赖 HttpMessageConverter(如 Jackson) - 适用于 REST API 开发
@RequestAttribute 请求域属性 获取前置组件(如拦截器)设置的请求属性 访问拦截器设置的属性值 - 适用于跨组件数据传递 - 需配合拦截器或过滤器使用

总结说明:

  • 路径与查询参数@PathVariable@RequestParam 分别处理 URL 路径和查询参数,前者用于 RESTful 风格 URL,后者用于传统查询字符串。
  • 请求头与 Cookie@RequestHeader@CookieValue 分别提取请求头和 Cookie 信息,支持灵活的数据获取方式。
  • 请求体处理@RequestBody 是处理 JSON/XML 请求体的核心注解,简化了数据绑定过程。
  • 请求属性传递@RequestAttribute 用于在请求处理链中传递数据,如用户权限信息。

通过合理使用这些注解,可以显著提升 Spring MVC 控制器方法的清晰度和可维护性,同时充分利用框架的自动类型转换和格式化功能。