能否在方法调用及参数列表外使用Request Header或@RequestHeader注解?
嘿,我来帮你理清这两个关于Request Header的问题!
能否在方法调用之外的其他地方使用Request Header?
当然可以!在Spring生态里,你完全可以脱离方法调用的范围获取Request Header。核心思路是借助RequestContextHolder拿到当前请求的上下文,进而获取HttpServletRequest对象,从里面提取Header信息——不管是工具类、服务层组件,还是其他非Controller的类,只要处于当前请求的线程中,都能这么做。
举个实用的工具类例子:
import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; public class HeaderHelper { public static String getAuthHeader() { ServletRequestAttributes requestAttrs = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); if (requestAttrs != null) { return requestAttrs.getRequest().getHeader("Authorization"); } return null; } }
不过要注意:这种方式只在当前请求线程有效,如果是异步任务或者脱离了请求上下文的场景,RequestContextHolder可能拿不到请求对象,这时候就得提前把需要的Header值传递过去哦。
是否可以在方法参数列表之外的其他位置设置@RequestHeader注解?
必须可以!Spring支持在Controller类的字段或者Setter方法上标注@RequestHeader,Spring会自动在处理请求时把对应Header的值注入进去,不用每次都在方法参数里写一遍。
比如字段注入的写法:
import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; @RestController public class DeviceController { @RequestHeader("Authorization") private String authToken; @GetMapping("/devices/{id}") public DeviceResource getDeviceDetails(@PathVariable String id) { // 直接用authToken就好啦 // ...你的业务逻辑 return new DeviceResource(); } }
再比如Setter方法注入的写法:
@RestController public class DeviceController { private String authToken; @RequestHeader("Authorization") public void setAuthToken(String authToken) { this.authToken = authToken; } @GetMapping("/devices/{id}") public DeviceResource getDeviceDetails(@PathVariable String id) { // 同样可以直接使用authToken // ...业务逻辑 return new DeviceResource(); } }
这里要提一句:Spring的Controller默认是单例,但这种类级别的Header注入是线程安全的——因为Spring会在每个请求处理时,为当前请求线程注入对应的Header值,不会出现线程间的干扰。
附上你提供的部分代码参考:
@ApiOperation("Gather all details of a specific device, identified by its ID") @ApiResponses(value = { @ApiResponse(code = 200, message = "OK", response = DeviceResource.class), @ApiResponse(code = 404, message = "Device not found", response = VndErrors.class), @ApiResponse(code = 500, message = "Printer shell execution error", response = VndErrors.class) }) @GetMapping("/devices/{id}") public DeviceResource getDeviceDetails(/* 你的参数 */) { // ...业务逻辑 }
内容的提问来源于stack exchange,提问作者Dullimeister
相关产品推荐
相关产品推荐

