在项目中,我通过pass redis确认app_key是有效的。
我使用ReactiveRedisTemplate访问redis数据,并在过滤器中验证app_key是否有效。如果app_key有效,则跳至下一个过滤器,否则将输出输出给客户端。
实际上:如果redis连接超时,则应运行exnig。但是当redis运行正常时,该程序不是exec verfiy app_key执行程序,它将直接跳转到下一个过滤器。
请告诉我怎么做,谢谢!
@Resource
private AppKeyProvider appKeyProvider;
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
try {
String app_key =exchange.getRequest().getQueryParams().getFirst("app_key"));
//app_key verify
Flux.just(app_key).flatMap(key -> appKeyProvider.getAppKey(key)).subscribe(
appKey -> {
if (appKey == null) {
//app_key is not valid
throw new AppException(ErrorCode.ILLEGAL_APP_KEY);
}else{
//do... jump to next filter
}
},
ex -> {
throw new AppException(ErrorCode.SERVICE_BASIC_ERROR, ex);
}
);
} catch (AppException ex) {
exchange.getResponse().setStatusCode(HttpStatus.BAD_REQUEST);
exchange.getResponse().getHeaders().setContentType(MediaType.APPLICATION_JSON);
String result = RestHelper.build(ex, exchange).toString();
return exchange.getResponse().writeWith(Mono.just(exchange.getResponse().bufferFactory().wrap(result.getBytes(Charsets.UTF_8))));
}
return chain.filter(exchange);
}
AppKeyProvider.java
@Component
public class AppKeyProvider {
@Resource
private ReactiveRedisTemplate reactiveRedisTemplate;
private final static Logger logger = LoggerFactory.getLogger(AppKeyProvider.class);
private final static AppKeyProvider instance = new AppKeyProvider();
private static ConcurrentHashMap<String, Api> apiMap = new ConcurrentHashMap<String, Api>();
private final static Lock lock = new ReentrantLock(true);
/**
* Get AppKey
*
* @param app_key
* @return
*/
public Mono<AppKey> getAppKey(String app_key) {
ReactiveValueOperations<String, AppKey> operations = reactiveRedisTemplate.opsForValue();
Mono<AppKey> appKey = operations.get(RedisKeypPrefix.APP_KEY + app_key);
return appKey;
}
}
答案 0 :(得分:0)
之所以发生这种情况,是因为您已手动订阅了关键查找部分。这样做会将主过滤器处理与该操作分离开,这意味着它们可以在不同的线程中同时发生-因此它们无法跟踪彼此的结果。
此外,在反应式编程中,错误会在管道内发生,应由操作员处理;在这种情况下,try / catch块将不起作用。
这是修复此代码段的尝试:
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
String app_key = exchange.getRequest().getQueryParams().getFirst("app_key"));
return appKeyProvider.getAppKey(app_key)
.switchOnEmpty(Mono.error(new AppException(ErrorCode.ILLEGAL_APP_KEY)))
.flatMap(key -> chain.filter(exchange))
.onErrorResume(AppException.class, exc -> {
exchange.getResponse().setStatusCode(HttpStatus.BAD_REQUEST);
exchange.getResponse().getHeaders().setContentType(MediaType.APPLICATION_JSON);
String result = RestHelper.build(ex, exchange).toString();
return exchange.getResponse().writeWith(Mono.just(exchange.getResponse().bufferFactory().wrap(result.getBytes(Charsets.UTF_8))));
});
}