最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Spring中的@RequestHeader注解使用及說(shuō)明

 更新時(shí)間:2025年12月18日 08:59:58   作者:李少兄  
`@RequestHeader`注解是SpringFramework中用于從HTTP請(qǐng)求中提取元數(shù)據(jù)信息的一個(gè)強(qiáng)大工具,它比手動(dòng)通過(guò)HttpServletRequest獲取請(qǐng)求頭值更加優(yōu)雅、聲明式且類型安全

前言

在構(gòu)建現(xiàn)代 Web 應(yīng)用或 RESTful API 時(shí),我們經(jīng)常需要從 HTTP 請(qǐng)求中提取元數(shù)據(jù)信息。其中,請(qǐng)求頭(Request Headers) 是傳遞客戶端身份、認(rèn)證令牌、內(nèi)容類型、語(yǔ)言偏好等關(guān)鍵信息的重要載體。

許多開(kāi)發(fā)者在早期開(kāi)發(fā)中習(xí)慣通過(guò) HttpServletRequest.getHeader(String name) 手動(dòng)獲取請(qǐng)求頭值。然而,Spring Framework 提供了一個(gè)更優(yōu)雅、聲明式且類型安全的解決方案——@RequestHeader 注解。

一、什么是 @RequestHeader?

@RequestHeader 是 Spring Framework org.springframework.web.bind.annotation 包下的一個(gè)方法參數(shù)注解,用于將 HTTP 請(qǐng)求頭中的特定字段值自動(dòng)綁定到控制器方法的參數(shù)上。

它屬于 Spring MVC 的數(shù)據(jù)綁定(Data Binding)機(jī)制的一部分,與 @RequestParam、@PathVariable、@RequestBody 等注解共同構(gòu)成 Spring 對(duì) HTTP 請(qǐng)求的結(jié)構(gòu)化解析能力。

1.1 基本定義

@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequestHeader {
    // 指定要綁定的請(qǐng)求頭名稱
    @AliasFor("name")
    String value() default "";

    @AliasFor("value")
    String name() default "";

    // 是否必須存在,默認(rèn)為 true
    boolean required() default true;

    // 當(dāng)請(qǐng)求頭不存在時(shí)的默認(rèn)值(僅在 required = false 時(shí)生效)
    String defaultValue() default ValueConstants.DEFAULT_NONE;
}

注意:value()name() 是別名關(guān)系(通過(guò) @AliasFor 實(shí)現(xiàn)),二者等價(jià),通常使用 value。

二、核心功能與使用方式

2.1 基礎(chǔ)用法:綁定單個(gè)請(qǐng)求頭

假設(shè)客戶端發(fā)送如下請(qǐng)求:

GET /api/user/profile HTTP/1.1
Host: api.example.com
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Accept-Language: zh-CN
X-Client-Version: 2.1.0

在 Controller 中可直接提?。?/p>

@RestController
@RequestMapping("/api/user")
public class UserController {

    @GetMapping("/profile")
    public UserProfile getProfile(
        @RequestHeader("Authorization") String authHeader,
        @RequestHeader("Accept-Language") String lang,
        @RequestHeader("X-Client-Version") String clientVersion
    ) {
        // authHeader = "Bearer eyJhbGci..."
        // lang = "zh-CN"
        // clientVersion = "2.1.0"
        return userService.getProfile(authHeader, lang);
    }
}

優(yōu)點(diǎn)

  • 無(wú)需注入 HttpServletRequest
  • 代碼簡(jiǎn)潔、語(yǔ)義清晰
  • 自動(dòng)完成字符串轉(zhuǎn)換(支持基本類型、枚舉等)

2.2 可選參數(shù)與默認(rèn)值

當(dāng)某些請(qǐng)求頭可能不存在時(shí),可通過(guò) required = false 避免 400 錯(cuò)誤:

@GetMapping("/info")
public AppInfo getAppInfo(
    @RequestHeader(value = "X-Trace-ID", required = false) String traceId,
    @RequestHeader(value = "User-Agent", defaultValue = "unknown") String userAgent
) {
    if (traceId == null) {
        traceId = generateTraceId(); // 自動(dòng)生成
    }
    return new AppInfo(traceId, userAgent);
}

注意:

  • defaultValue 僅在 required = false 且請(qǐng)求頭缺失時(shí)生效。
  • 若同時(shí)設(shè)置 required = truedefaultValue,defaultValue 不會(huì)被使用(因?yàn)?Spring 認(rèn)為該頭必須存在)。

2.3 綁定所有請(qǐng)求頭(Map 形式)

若需訪問(wèn)多個(gè)或動(dòng)態(tài)請(qǐng)求頭,可綁定為 Map<String, String>HttpHeaders 對(duì)象:

@GetMapping("/debug")
public Map<String, String> debugHeaders(@RequestHeader Map<String, String> headers) {
    // headers 包含所有請(qǐng)求頭(key 不區(qū)分大小寫(xiě),統(tǒng)一轉(zhuǎn)為小寫(xiě)?注意:實(shí)際保留原始大小寫(xiě))
    return headers;
}

// 或使用 HttpHeaders(推薦,支持多值頭)
@GetMapping("/debug2")
public ResponseEntity<?> debugWithHttpHeaders(@RequestHeader HttpHeaders headers) {
    List<String> authList = headers.get("Authorization"); // 支持同名多值
    String contentType = headers.getFirst("Content-Type");
    return ResponseEntity.ok().build();
}

說(shuō)明:

  • Map<String, String>:每個(gè) header key 對(duì)應(yīng)第一個(gè)值(若存在多個(gè)同名頭)。
  • HttpHeaders:Spring 封裝的多值映射結(jié)構(gòu),支持 get(key) 返回 List<String>,更安全。

2.4 類型轉(zhuǎn)換支持

@RequestHeader 支持自動(dòng)類型轉(zhuǎn)換,不僅限于 String

@GetMapping("/config")
public void getConfig(
    @RequestHeader("X-Retry-Count") int retryCount,          // 轉(zhuǎn)為 int
    @RequestHeader("X-Enable-Feature") boolean enableFeature, // 轉(zhuǎn)為 boolean ("true"/"false")
    @RequestHeader("X-Priority") PriorityLevel priority       // 自定義枚舉
) {
    // ...
}

// 枚舉示例
public enum PriorityLevel {
    LOW, MEDIUM, HIGH;

    // Spring 會(huì)調(diào)用 valueOf(String) 進(jìn)行轉(zhuǎn)換
}

支持的類型包括:

  • 基本類型及其包裝類(int, Integer, boolean, Boolean 等)
  • String
  • java.util.Date(需配合 @DateTimeFormat
  • 枚舉(通過(guò) valueOf 或自定義 Converter
  • 自定義類型(需注冊(cè) Converter<String, T>

三、典型使用場(chǎng)景

3.1 身份認(rèn)證與 Token 提取

最常見(jiàn)的用途是從 Authorization 頭中提取 JWT 或 OAuth Token:

@PostMapping("/order")
public Order createOrder(@RequestHeader("Authorization") String authHeader) {
    if (authHeader == null || !authHeader.startsWith("Bearer ")) {
        throw new IllegalArgumentException("Invalid token");
    }
    String token = authHeader.substring(7); // 去掉 "Bearer "
    User user = jwtService.validate(token);
    return orderService.create(user);
}

提示:生產(chǎn)環(huán)境中建議使用 Spring Security + JWT Filter 全局處理,而非每個(gè)接口重復(fù)提取。

3.2 多語(yǔ)言與區(qū)域化(i18n)

通過(guò) Accept-Language 頭實(shí)現(xiàn)國(guó)際化:

@GetMapping("/message")
public String getMessage(@RequestHeader("Accept-Language") Locale locale) {
    return messageSource.getMessage("welcome.message", null, locale);
}

Spring 會(huì)自動(dòng)將 "zh-CN" 轉(zhuǎn)換為 Locale.CHINA。

3.3 客戶端版本控制與灰度發(fā)布

利用自定義頭如 X-App-Version 實(shí)現(xiàn) API 兼容:

@GetMapping("/feature")
public FeatureResponse getFeature(
    @RequestHeader("X-App-Version") String appVersion
) {
    if (VersionUtils.compare(appVersion, "2.0.0") >= 0) {
        return newFeature();
    } else {
        return legacyFeature();
    }
}

3.4 分布式追蹤(Tracing)

集成 OpenTelemetry / Sleuth 時(shí),常需傳遞 trace-id、span-id

@PostMapping("/process")
public void processEvent(@RequestHeader("X-B3-TraceId") String traceId) {
    MDC.put("traceId", traceId); // 寫(xiě)入日志上下文
    eventService.handle();
}

四、底層原理與執(zhí)行流程

4.1 參數(shù)解析器(HandlerMethodArgumentResolver)

@RequestHeader 的核心實(shí)現(xiàn)依賴于 Spring MVC 的 RequestHeaderMethodArgumentResolver

其工作流程如下:

  • Spring 在調(diào)用 Controller 方法前,遍歷所有參數(shù)。
  • 若發(fā)現(xiàn)參數(shù)標(biāo)注了 @RequestHeader,則委托給 RequestHeaderMethodArgumentResolver
  • 該解析器從 NativeWebRequest(封裝了 HttpServletRequest)中獲取對(duì)應(yīng) header 值。
  • 執(zhí)行類型轉(zhuǎn)換(通過(guò) ConversionService)。
  • 將結(jié)果注入方法參數(shù)。

4.2 類型轉(zhuǎn)換機(jī)制

Spring 使用 WebDataBinderConversionService 完成字符串到目標(biāo)類型的轉(zhuǎn)換。例如:

  • "true"Boolean.TRUE
  • "123"Integer.valueOf(123)
  • "zh-CN"new Locale("zh", "CN")

可通過(guò)自定義 ConverterFormatter 擴(kuò)展支持:

@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Override
    public void addFormatters(FormatterRegistry registry) {
        registry.addConverter(new StringToPriorityLevelConverter());
    }
}

五、常見(jiàn)誤區(qū)與注意事項(xiàng)

誤區(qū) 1:認(rèn)為 @RequestHeader 可用于任意方法

事實(shí)@RequestHeader 僅在 Spring MVC 的控制器方法(@Controller / @RestController)中有效。在 Service、Util 或普通 Bean 方法中使用將被忽略。

誤區(qū) 2:忽略大小寫(xiě)問(wèn)題

HTTP Header 名稱不區(qū)分大小寫(xiě)(RFC 7230),但 Spring 默認(rèn)按原樣匹配。

建議統(tǒng)一使用駝峰或全大寫(xiě)風(fēng)格:

// 推薦:與標(biāo)準(zhǔn)頭保持一致
@RequestHeader("Authorization")
@RequestHeader("Content-Type")

// 自定義頭建議使用 X- 前綴或統(tǒng)一命名規(guī)范
@RequestHeader("X-Api-Key")

誤區(qū) 3:在 required = true 時(shí)設(shè)置 defaultValue

// ? 無(wú)效!defaultValue 不會(huì)被使用
@RequestHeader(value = "X-Debug", required = true, defaultValue = "false")

正確做法:

// ?
@RequestHeader(value = "X-Debug", required = false, defaultValue = "false")

注意:安全性

  • 不要信任客戶端傳入的任意頭!例如 X-Forwarded-For 可能被偽造。
  • 敏感操作(如權(quán)限提升)應(yīng)結(jié)合服務(wù)端會(huì)話或簽名驗(yàn)證,而非僅依賴請(qǐng)求頭。

六、與 HttpServletRequest.getHeader() 的對(duì)比

特性@RequestHeaderrequest.getHeader()
代碼位置Controller 方法參數(shù)任意有 request 的地方
類型安全? 支持自動(dòng)轉(zhuǎn)換? 僅返回 String
可讀性? 聲明式,意圖明確? 命令式,需查找 key
校驗(yàn)?zāi)芰?/td>? 內(nèi)置 required/default? 需手動(dòng)判空
測(cè)試友好性? 易于 Mock 參數(shù)? 需 Mock HttpServletRequest
耦合度低(無(wú) Servlet API 依賴)高(強(qiáng)依賴 Servlet API)

結(jié)論:在 Controller 層優(yōu)先使用 @RequestHeader。

七、最佳實(shí)踐建議

7.1 合理分層:Controller vs 全局處理

  • 簡(jiǎn)單場(chǎng)景:直接在 Controller 使用 @RequestHeader 提取 Token。
  • 復(fù)雜鑒權(quán):使用 InterceptorFilter 全局解析 Token 并放入上下文(如 SecurityContextThreadLocal)。
// 示例:攔截器中處理
public class AuthInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, ...) {
        String token = request.getHeader("Authorization");
        User user = authService.validate(token);
        RequestContextHolder.setAttribute("currentUser", user);
        return true;
    }
}

7.2 使用常量管理 Header 名稱

避免魔法字符串:

public class HeaderConstants {
    public static final String AUTHORIZATION = "Authorization";
    public static final String TRACE_ID = "X-Trace-ID";
}

// 使用
@RequestHeader(HeaderConstants.AUTHORIZATION) String auth

7.3 結(jié)合 Lombok 與記錄日志

@Slf4j
@RestController
public class ApiController {
    @GetMapping("/data")
    public Data getData(@RequestHeader("X-Request-ID") String requestId) {
        log.info("Processing request [{}]", requestId);
        // ...
    }
}

八、擴(kuò)展:與其他注解的協(xié)同使用

@RequestHeader 可與以下注解共存于同一方法:

@PostMapping("/upload")
public UploadResult upload(
    @RequestHeader("Content-Type") String contentType,
    @RequestParam("file") MultipartFile file,
    @PathVariable("userId") Long userId,
    @RequestBody Metadata metadata
) {
    // 組合使用,各司其職
}

參考資料:Spring Framework 官方文檔 - @RequestHeader

九、總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • SpringBoot中的定時(shí)任務(wù)和異步調(diào)用詳解

    SpringBoot中的定時(shí)任務(wù)和異步調(diào)用詳解

    這篇文章主要介紹了SpringBoot中的定時(shí)任務(wù)和異步調(diào)用詳解,SpringBoot 定時(shí)任務(wù)是一種在SpringBoot應(yīng)用中自動(dòng)執(zhí)行任務(wù)的機(jī)制,通過(guò)使用Spring框架提供的@Scheduled注解,我們可以輕松地創(chuàng)建定時(shí)任務(wù),需要的朋友可以參考下
    2023-10-10
  • Spring框架核心概念小結(jié)

    Spring框架核心概念小結(jié)

    Spring是企業(yè)級(jí)Java的開(kāi)源開(kāi)發(fā)框架。Spring框架的核心功能可用于開(kāi)發(fā)任何java應(yīng)用程序,本文重點(diǎn)給大家介紹Spring框架核心概念總覽,感興趣的朋友跟隨小編一起看看吧
    2022-02-02
  • 完整的醫(yī)院就診掛號(hào)系統(tǒng)基于Spring MVC + Spring + MyBatis實(shí)現(xiàn)

    完整的醫(yī)院就診掛號(hào)系統(tǒng)基于Spring MVC + Spring + MyBatis實(shí)現(xiàn)

    這篇文章主要介紹了基于Spring MVC + Spring + MyBatis實(shí)現(xiàn)的醫(yī)院就診掛號(hào)系統(tǒng),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-08-08
  • java漢字轉(zhuǎn)拼音工具類分享

    java漢字轉(zhuǎn)拼音工具類分享

    這篇文章主要為大家詳細(xì)介紹了java漢字轉(zhuǎn)拼音工具類,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-01-01
  • 使用java代碼實(shí)現(xiàn)一個(gè)月內(nèi)不再提醒,通用到期的問(wèn)題

    使用java代碼實(shí)現(xiàn)一個(gè)月內(nèi)不再提醒,通用到期的問(wèn)題

    這篇文章主要介紹了使用java代碼實(shí)現(xiàn)一個(gè)月內(nèi)不再提醒,通用到期的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2021-01-01
  • SpringCloud Eureka自我保護(hù)機(jī)制原理解析

    SpringCloud Eureka自我保護(hù)機(jī)制原理解析

    這篇文章主要介紹了SpringCloud Eureka自我保護(hù)機(jī)制原理解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-02-02
  • Java 泛型總結(jié)(三):通配符的使用

    Java 泛型總結(jié)(三):通配符的使用

    在泛型的使用中,還有個(gè)重要的東西叫通配符,本文介紹通配符的使用。具有很好的參考價(jià)值。下面跟著小編一起來(lái)看下吧
    2017-03-03
  • SpringBoot與SpringMVC第一講

    SpringBoot與SpringMVC第一講

    SpringMVC全名應(yīng)該叫做SpringWebMVC,它其實(shí)是基于servlet來(lái)構(gòu)建的一個(gè)原始web框架從一開(kāi)始就包含在了spring框架中,下面通過(guò)實(shí)例代碼給大家介紹SpringBoot與SpringMVC的相關(guān)知識(shí),感興趣的朋友跟隨小編一起看看吧
    2024-05-05
  • 一篇文章讓你三分鐘學(xué)會(huì)Java枚舉

    一篇文章讓你三分鐘學(xué)會(huì)Java枚舉

    這篇文章主要給大家介紹了如何通過(guò)三分鐘學(xué)會(huì)Java枚舉的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-12-12
  • 一文讓你了解透徹Java中的IO模型

    一文讓你了解透徹Java中的IO模型

    本文只是說(shuō)明了IO模型,讓你了解IO模型是什么,怎么區(qū)分IO模型,以及分析了Java中的三種IO模型,本文是純理論知識(shí),看完之后會(huì)讓你對(duì)IO有更加深刻的理解,感興趣的同學(xué)可以參考一下
    2023-05-05

最新評(píng)論

工布江达县| 丹棱县| 吉安市| 宁乡县| 宁远县| 皋兰县| 四会市| 建德市| 石阡县| 台安县| 宾川县| 福州市| 从江县| 彰化市| 芦溪县| 平远县| 灌南县| 井冈山市| 扶沟县| 昌图县| 芦山县| 望奎县| 灵川县| 长寿区| 绥滨县| 石台县| 佳木斯市| 海林市| 吕梁市| 松潘县| 饶河县| 兴化市| 翼城县| 临夏县| 龙胜| 永州市| 图木舒克市| 盐山县| 洛浦县| 黄陵县| 泸溪县|