在spring boot中,有几种方式可以从service层获取request.getheader():
1.通过方法参数传递(推荐)
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对象
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.通过threadlocal持有request
创建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();
}
}创建拦截器:
@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(); // 防止内存泄漏
}
}注册拦截器:
@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"));
}
}最佳实践建议:
- 推荐方案1:通过方法参数传递,保持service层纯净
- 异步场景:如果需要跨线程,需要手动传递header信息
- 日志追踪:可以使用mdc存储traceid等跟踪信息
- 安全性:注意threadlocal的清理,避免内存泄漏
// 异步线程中传递header的示例
@async
public completablefuture<string> asyncprocess() {
// 在主线程获取header
string token = ((servletrequestattributes)
requestcontextholder.getrequestattributes())
.getrequest()
.getheader("authorization");
return completablefuture.supplyasync(() -> {
// 异步线程中无法直接获取requestcontextholder
// 需要手动传递
return processwithtoken(token);
});
}选择哪种方式取决于具体业务场景,一般来说,优先考虑方案1或方案2。
以上就是springboot从service层获取request.getheader()的几种方式的详细内容,更多关于springboot service获取request.getheader()的资料请关注代码网其它相关文章!
发表评论