SpringBoot從Service層獲取request.getHeader()的幾種方式
在Spring Boot中,有幾種方式可以從Service層獲取request.getHeader():
1.通過(guò)方法參數(shù)傳遞(推薦)
Service接口:
@Service
public class UserService {
public String getUserInfo(String headerValue) {
// 使用headerValue
return "處理Header: " + headerValue;
}
}Controller層:
@RestController
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/user")
public String getUser(@RequestHeader("Authorization") String token) {
return userService.getUserInfo(token);
}
}2.使用RequestContextHolder(常用)
@Service
public class UserService {
public String getUserInfo() {
// 獲取HttpServletRequest對(duì)象
HttpServletRequest request = ((ServletRequestAttributes)
RequestContextHolder.getRequestAttributes()).getRequest();
// 獲取特定Header
String token = request.getHeader("Authorization");
String userAgent = request.getHeader("User-Agent");
// 獲取所有Header名稱
Enumeration<String> headerNames = request.getHeaderNames();
return "Token: " + token;
}
}3.通過(guò)ThreadLocal持有Request
創(chuàng)建RequestHolder工具類:
@Component
public class RequestHolder {
private static final ThreadLocal<HttpServletRequest> requestHolder = new ThreadLocal<>();
public static void setRequest(HttpServletRequest request) {
requestHolder.set(request);
}
public static HttpServletRequest getRequest() {
return requestHolder.get();
}
public static String getHeader(String headerName) {
HttpServletRequest request = getRequest();
return request != null ? request.getHeader(headerName) : null;
}
public static void remove() {
requestHolder.remove();
}
}創(chuàng)建攔截器:
@Component
public class RequestInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler) {
RequestHolder.setRequest(request);
return true;
}
@Override
public void afterCompletion(HttpServletRequest request,
HttpServletResponse response,
Object handler,
Exception ex) {
RequestHolder.remove(); // 防止內(nèi)存泄漏
}
}注冊(cè)攔截器:
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Autowired
private RequestInterceptor requestInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(requestInterceptor);
}
}Service中使用:
@Service
public class UserService {
public String getUserInfo() {
String token = RequestHolder.getHeader("Authorization");
return "Token: " + token;
}
}4.注入HttpServletRequest
@Service
public class UserService {
@Autowired
private HttpServletRequest request; // 需要@RequestScope
public String getUserInfo() {
String token = request.getHeader("Authorization");
return "Token: " + token;
}
}注意:這種方式需要在Spring Boot 2.x及以上版本,并且Service必須是RequestScope。
@Service
@RequestScope
public class UserService {
// ...
}5.封裝Header信息到DTO
HeaderDTO:
@Data
public class RequestContext {
private String token;
private String userAgent;
private String clientIp;
// 其他需要的Header信息
}Controller:
@RestController
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/user")
public String getUser(HttpServletRequest request) {
RequestContext context = new RequestContext();
context.setToken(request.getHeader("Authorization"));
context.setUserAgent(request.getHeader("User-Agent"));
return userService.getUserInfo(context);
}
}6.使用AOP獲取
@Aspect
@Component
public class RequestAspect {
@Pointcut("execution(* com.example.service..*.*(..))")
public void servicePointcut() {}
@Before("servicePointcut()")
public void before(JoinPoint joinPoint) {
HttpServletRequest request = ((ServletRequestAttributes)
RequestContextHolder.getRequestAttributes()).getRequest();
// 可以將Header信息放入MDC或ThreadLocal
MDC.put("token", request.getHeader("Authorization"));
}
}最佳實(shí)踐建議:
- 推薦方案1:通過(guò)方法參數(shù)傳遞,保持Service層純凈
- 異步場(chǎng)景:如果需要跨線程,需要手動(dòng)傳遞Header信息
- 日志追蹤:可以使用MDC存儲(chǔ)TraceID等跟蹤信息
- 安全性:注意ThreadLocal的清理,避免內(nèi)存泄漏
// 異步線程中傳遞Header的示例
@Async
public CompletableFuture<String> asyncProcess() {
// 在主線程獲取Header
String token = ((ServletRequestAttributes)
RequestContextHolder.getRequestAttributes())
.getRequest()
.getHeader("Authorization");
return CompletableFuture.supplyAsync(() -> {
// 異步線程中無(wú)法直接獲取RequestContextHolder
// 需要手動(dòng)傳遞
return processWithToken(token);
});
}選擇哪種方式取決于具體業(yè)務(wù)場(chǎng)景,一般來(lái)說(shuō),優(yōu)先考慮方案1或方案2。
以上就是SpringBoot從Service層獲取request.getHeader()的幾種方式的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot Service獲取request.getHeader()的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Springboot @WebFilter無(wú)法注入其他Bean的示例問(wèn)題
這篇文章主要介紹了Springboot @WebFilter無(wú)法注入其他Bean的示例問(wèn)題,本文通過(guò)示例代碼給大家分享解決方法,需要的朋友可以參考下2021-09-09
配置springboot項(xiàng)目使用外部tomcat過(guò)程解析
這篇文章主要介紹了配置springboot項(xiàng)目使用外部tomcat過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-09-09
SpringBoot中spring.factories文件的作用及讀取過(guò)程
SpringBoot通過(guò)spring.factories文件實(shí)現(xiàn)自動(dòng)配置和擴(kuò)展機(jī)制,該文件位于類路徑下的META-INF目錄中,鍵是接口或抽象類的全限定名,值是實(shí)現(xiàn)類的全限定名列表,SpringFactoriesLoader類負(fù)責(zé)讀取和解析spring.factories文件,獲取指定工廠類型的實(shí)現(xiàn)類列表2025-11-11
解決SpringCloud Config結(jié)合github無(wú)法讀取配置的問(wèn)題
這篇文章主要介紹了解決SpringCloud Config結(jié)合github無(wú)法讀取配置的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2021-02-02

