乐途乐途
主页
  • 计算机基础

    • TCP/IP协议
    • Linux命令
    • HTTP协议
  • 数据库

    • SQL
    • MySQL 5.7
  • 编程语言

    • C语言
    • Python2
    • Python3
  • 数据格式

    • JSON
    • XML
  • 认证与安全

    • JWT
  • 工具

    • Markdown
  • Git

    • GitFlow
  • Quartz

    • Quartz
  • Java

    • MyBatis
    • Spring
    • Spring MVC
    • Maven 入门
    • Maven 进阶
    • Java 设计模式
  • 缓存

    • Redis
联系
阿里云
主页
  • 计算机基础

    • TCP/IP协议
    • Linux命令
    • HTTP协议
  • 数据库

    • SQL
    • MySQL 5.7
  • 编程语言

    • C语言
    • Python2
    • Python3
  • 数据格式

    • JSON
    • XML
  • 认证与安全

    • JWT
  • 工具

    • Markdown
  • Git

    • GitFlow
  • Quartz

    • Quartz
  • Java

    • MyBatis
    • Spring
    • Spring MVC
    • Maven 入门
    • Maven 进阶
    • Java 设计模式
  • 缓存

    • Redis
联系
阿里云
  • 学习路径
  • 第1章 SpringMVC概述与DispatcherServlet

    • 本章导读:Spring MVC概述与DispatcherServlet
    • Spring MVC 是什么
    • MVC 设计模式
    • 前端控制器模式
    • DispatcherServlet
    • 核心组件协作
  • 第2章 控制器与请求映射

    • 本章导读:控制器与请求映射
    • Controller
    • RestController
    • RequestMapping
    • GetMapping
    • PostMapping
    • PutMapping
    • DeleteMapping
    • PathVariable
    • RESTful
    • 请求映射原理
  • 第3章 请求参数获取与转换

    • 本章导读:请求参数获取与转换
    • RequestParam
    • RequestBody
    • RequestHeader
    • CookieValue
    • Model
    • ModelAttribute
    • 数据绑定原理
    • 数据校验
  • 第4章 响应数据与视图解析

    • 本章导读:响应数据与视图解析
    • ResponseBody
    • ResponseEntity
    • ModelAndView
    • ViewResolver
    • HttpMessageConverter
    • forward与redirect
  • 第5章 拦截器过滤器与跨域

    • 本章导读:拦截器、过滤器与跨域
    • HandlerInterceptor
    • WebMvcConfigurer
    • CrossOrigin
    • 登录验证实战
  • 第6章 文件上传与异常处理

    • 本章导读:文件上传与异常处理
    • MultipartFile
    • 文件下载
    • ExceptionHandler
    • ControllerAdvice
    • RestControllerAdvice
    • ResponseStatus
  • 第7章 高级特性与最佳实践

    • 本章导读:高级特性与最佳实践
    • SessionAttributes
    • SessionAttribute
    • RedirectAttributes
    • MockMvc测试
    • 国际化
    • 最佳实践
  • 第8章 扩展与异步机制

    • 本章导读:扩展与异步机制
    • 异步请求处理
    • 自定义参数解析器
    • 内容协商

RequestHeader

本章紧接 @RequestParam,聚焦 HTTP 请求头(Request Header)的获取。如果说 @RequestParam 处理的是请求的"业务数据",那么 @RequestHeader 处理的就是请求的"元数据"——如客户端类型、认证令牌、内容格式等。这些信息不直接参与业务计算,却决定了请求如何被解析、如何被鉴权。


定义与作用

@RequestHeader 用于将 HTTP 请求头中的字段值绑定到 Controller 方法的参数上。

HTTP 请求头携带了关于请求本身的大量元信息:

  • User-Agent:客户端是什么浏览器、什么操作系统
  • Content-Type:请求体的数据格式(JSON、表单、XML)
  • Authorization:认证令牌(Bearer Token、Basic Auth)
  • Accept:客户端期望的响应格式
  • X-Request-ID:链路追踪 ID

在 RESTful API 开发中,请求头常用于传递横切关注点的数据——这些数据与具体业务无关,但每个请求都可能需要(如鉴权、日志追踪、版本控制)。

生活类比:信封上的邮戳

想象飞翔科技收发室收到一封信件:

  • 信纸内容(请求体):这是真正的业务数据,如"申请报销 500 元"
  • 信封上的邮戳(请求头):包含发件地址、邮戳日期、特快标识等元信息

@RequestParam 读的是信纸上的具体内容(如报销金额),@RequestHeader 读的是信封上的邮戳(如发件人地址、邮件优先级)。两者各司其职,缺一不可。


核心原理

请求头绑定流程

与 @RequestParam 的核心区别:

维度@RequestParam@RequestHeader
数据来源request.getParameter()request.getHeader()
数据位置URL 查询参数 / 表单体HTTP 请求头
大小写敏感参数名大小写不敏感请求头名大小写不敏感(HTTP 规范)
多值支持同名参数多值同名头字段多值(逗号分隔或重复出现)

适用位置与常用属性

@RequestHeader 只能标注在 Controller 方法的参数 上。

属性类型默认值说明
name / valueString""请求头字段名,大小写不敏感
requiredbooleantrue是否必填
defaultValueString无缺失时的默认值

常见请求头对照表

请求头典型值使用场景
User-AgentMozilla/5.0 (Windows NT 10.0...)识别客户端类型、做兼容性适配
Content-Typeapplication/json告知服务器请求体格式
Acceptapplication/json告知服务器期望的响应格式
AuthorizationBearer eyJhbGciOiJIUzI1Ni...JWT / OAuth2 令牌传递
X-Request-ID550e8400-e29b-41d4-a716-446655440000分布式链路追踪
Hostapi.feixiang.com虚拟主机、路由分发
Refererhttps://feixiang.com/employees来源页面统计、防盗链
CookiesessionId=abc123; theme=dark会话状态(但获取 Cookie 推荐 @CookieValue)

完整示例

场景

飞翔科技员工管理系统需要记录每个请求的客户端信息,用于安全审计和兼容性分析。架构师白歌要求后端小崔在接口中采集 User-Agent 和自定义的 X-Client-Version 头。

代码实现

package com.feixiang.web;

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

@RestController
@RequestMapping("/employees")
public class EmployeeController {

    /**
     * 获取 User-Agent,识别客户端类型
     */
    @GetMapping("/client-info")
    public String getClientInfo(
            @RequestHeader("User-Agent") String userAgent,
            @RequestHeader(value = "X-Client-Version", required = false) String clientVersion) {
        return String.format("客户端: %s, 版本: %s", userAgent, clientVersion);
    }

    /**
     * 获取所有请求头(Map 形式)
     */
    @GetMapping("/headers")
    public String getAllHeaders(@RequestHeader Map<String, String> headers) {
        return "请求头数量: " + headers.size() + ", Content-Type=" + headers.get("content-type");
    }

    /**
     * 获取多值请求头(List 形式)
     */
    @GetMapping("/multi-header")
    public String getMultiValueHeader(@RequestHeader("Accept") List<String> acceptValues) {
        return "Accept 头: " + acceptValues;
    }
}

HTTP 请求示例

示例 1:获取 User-Agent

curl -H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)" \
     -H "X-Client-Version: 2.1.0" \
     "http://localhost:8080/employees/client-info"

响应:

客户端: Mozilla/5.0 (Windows NT 10.0; Win64; x64), 版本: 2.1.0

示例 2:自定义头缺失(required=false)

curl -H "User-Agent: curl/7.68.0" \
     "http://localhost:8080/employees/client-info"

响应:

客户端: curl/7.68.0, 版本: null

X-Client-Version 未传,由于 required=false,参数值为 null,不报错。

示例 3:获取所有请求头

curl -H "Content-Type: application/json" \
     -H "X-Request-ID: 550e8400-e29b-41d4-a716" \
     "http://localhost:8080/employees/headers"

响应:

请求头数量: 7, Content-Type=application/json

示例 4:多值 Accept 头

curl -H "Accept: application/json" \
     -H "Accept: text/html" \
     "http://localhost:8080/employees/multi-header"

响应:

Accept 头: [application/json, text/html]

易错场景与面试考点

误区一:请求头名大小写写错

现象:@RequestHeader("content-type") 和 @RequestHeader("Content-Type") 都能正常工作。

原理:HTTP/1.1 规范规定请求头字段名大小写不敏感。Spring MVC 底层调用 HttpServletRequest.getHeader(),该方法在标准实现中不区分大小写。

建议:虽然大小写不敏感,但团队应统一规范。推荐首字母大写的驼峰写法(Content-Type、User-Agent),与 RFC 规范一致。

误区二:用 @RequestHeader 获取 Cookie

现象:@RequestHeader("Cookie") String cookie 能拿到 sessionId=abc; theme=dark 这样的原始字符串。

问题:Cookie 字符串需要手动解析(按 ; 分割、URL 解码),繁琐且易错。

正确做法:使用专门的 @CookieValue 注解(下一节讲解),直接按 Cookie 名提取单个值:

@GetMapping("/session")
public String getSession(@CookieValue("sessionId") String sessionId) {
    return "会话ID: " + sessionId;
}

误区三:请求头值包含中文未编码

现象:@RequestHeader("X-Employee-Name") String name 拿到乱码。

纠正:HTTP 请求头值默认按 ISO-8859-1 编码。如果需要在请求头中传递中文,客户端必须先进行 URL 编码(URLEncoder.encode("张三", "UTF-8")),服务端再 URL 解码。

最佳实践:业务数据(如员工姓名)不要放在请求头中传递,应放在请求体(@RequestBody)或查询参数(@RequestParam)中。

面试高频:@RequestHeader 和 @RequestParam 的区别

标准回答:

  1. 数据来源不同:@RequestParam 从 URL 查询参数或表单数据获取(getParameter()),@RequestHeader 从 HTTP 请求头获取(getHeader())
  2. 用途不同:@RequestParam 用于业务数据(如搜索关键词、分页参数),@RequestHeader 用于元数据(如认证令牌、客户端版本)
  3. 大小写规则不同:请求参数名大小写不敏感(但通常按声明匹配),请求头名按 HTTP 规范大小写不敏感
  4. 多值处理:两者都支持多值,但请求头的多值通常以逗号分隔(如 Accept: application/json, text/xml),而参数多值通常重复出现(如 id=1&id=2)

小结

@RequestHeader 是 Spring MVC 获取 HTTP 请求头元数据的核心注解。它将请求头字段映射为 Java 方法参数,支持必填控制、默认值和多值接收。

核心要点:

  • 请求头名大小写不敏感,但团队应统一规范
  • 业务数据不要放在请求头中传递,避免编码问题
  • 获取 Cookie 应使用 @CookieValue,不要手动解析 Cookie 头
  • 常用场景:鉴权令牌、客户端版本、链路追踪 ID

本章与全局的关系:本章讲解了"如何获取请求的元数据"。下一节 @CookieValue 将专门讲解 HTTP Cookie 的获取方式,它是请求头机制的一个特例,但拥有更便捷的专用注解。

上一页
RequestBody
下一页
CookieValue