背景
在springboot+tomcat應用中獲取request對象可以使用RequestContextHolder.getRequestAttributes()的方式來獲取,此種方式的核心在于request所在容器被放在threadlocal中,但是webflux結合netty項目卻不能這么使用,因為webflux是異步響應式的,下面介紹下異步服務webflux+netty如何便捷獲取request。
編寫基于webflux的RequestContextHolder實現
編寫ReactiveHttpContextHolder類用來模擬RequestContextHolder
public class ReactiveHttpContextHolder {public static Mono<ServerHttpRequest> getRequest() {return Mono.subscriberContext().map(context
-> context
.get(Info.CONTEXT_KEY
).getRequest());}public static Mono<ServerHttpResponse> getResponse(){return Mono.subscriberContext().map(context
-> context
.get(Info.CONTEXT_KEY
).getResponse());}public static final class Info{public static final Class<ServerWebExchange> CONTEXT_KEY
= ServerWebExchange.class;}
}
編寫過濾器類用于設置request到容器中
@Component
@ConditionalOnWebApplication(type
= ConditionalOnWebApplication.Type.REACTIVE
)
public class AppFilter implements WebFilter {@Overridepublic Mono<Void> 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(){}@Pointcut("@annotation(xx.AuthIgnore)")private void ignoreRule(){}@Around("classRule() && !ignoreRule()")public Mono<Object> aroundInvoke(ProceedingJoinPoint joinPoint
){Mono<ServerHttpRequest> requestMono
= ReactiveHttpContextHolder.getRequest();return requestMono
.flatMap(request
-> {String token
= getHeader("token", request
);if (token
== null || TokenCacheContainer.getTokenCache().get(token
) == null){BusException ex
= new BusException("01300001");return buildErrMsg(ex
);} else {try {return (Mono<Object>) joinPoint
.proceed();} catch (Throwable throwable
) {LogFactory.getLog(AuthAspect.class).error("", throwable
);BusException ex
= new BusException("01300000");return buildErrMsg(ex
);}}});}private Mono<String> buildErrMsg(BusException ex
){ApiJsonResult errResult
= ApiJsonResult.createErrResult(ex
.getErrorCode(), ex
.getReason(), ex
.getResolve());return Mono.just( errResult
.toString() );}
}
說明
過濾器會在切面之前執行,因此aop中能獲取到在filter中設置的request測試結果
總結
以上是生活随笔為你收集整理的webflux切面拦截权限,webflux整合aop,webflux获取request的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。