在springboot+tomcat应用中获取request对象可以使用RequestContextHolder.getRequestAttributes()的方式来获取,此种方式的核心在于request所在容器被放在threadlocal中,但是webflux结合netty项目却不能这么使用,因为webflux是异步响应式的,下面介绍下异步服务webflux+netty如何便捷获取request。
编写基于webflux的RequestContextHolder实现- 编写ReactiveHttpContextHolder类用来模拟RequestContextHolder
public class ReactiveHttpContextHolder {
//获取当前请求对象
public static Mono getRequest() {
return Mono.subscriberContext()
.map(context -> context.get(Info.CONTEXT_KEY).getRequest());
}
//获取当前response
public static Mono getResponse(){
return Mono.subscriberContext()
.map(context -> context.get(Info.CONTEXT_KEY).getResponse());
}
public static final class Info{
public static final Class CONTEXT_KEY = ServerWebExchange.class;
}
}
- 编写过滤器类用于设置request到容器中
@Component
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE)
public class AppFilter implements WebFilter {
@Override
public Mono filter(ServerWebExchange exchange, WebFilterChain chain) {
//设置当前请求
return chain.filter(exchange)
.subscriberContext(context -> context.put(ReactiveHttpContextHolder.Info.CONTEXT_KEY, exchange));
}
}
编写切面实现token拦截,校验权限
- 切面逻辑代码
@Component
@Aspect
public class AuthAspect extends baseController {
@Pointcut("execution(public * xx.xx.xxController.*(..))")
private void classRule(){}
//带有AuthIgnore注解的不校验
@Pointcut("@annotation(xx.AuthIgnore)")
private void ignoreRule(){}
@Around("classRule() && !ignoreRule()")
public Mono
- 说明
过滤器会在切面之前执行,因此aop中能获取到在filter中设置的request - 测试结果



