能否使用Java Stream API重写带Rest-Assured请求重试的WHILE循环
使用Stream API重写重试请求逻辑的实现方案
完全可以使用Java Stream API实现你需要的重试逻辑,而且基于Stream的惰性求值特性,不会在首次请求成功的场景下发起多余请求,完全符合你的要求。
实现代码
protected Response getResponseWithRetries(Map<String, Object> requestBody, String token, String url) { // 存储最后一次请求的响应,应对3次请求全部失败的场景 final AtomicReference<Response> lastResponse = new AtomicReference<>(); return Stream.generate(() -> { Response resp = getResponse(requestBody, token, url); lastResponse.set(resp); return resp; }) .limit(3) // 限制最多发起3次请求 .peek(resp -> { // 仅非200响应时休眠,避免首次请求成功的不必要等待 if (resp.getStatusCode() != HttpStatus.SC_OK) { sleep(5000); } }) .filter(resp -> resp.getStatusCode() == HttpStatus.SC_OK) .findFirst() // 找到第一个符合要求的响应后立刻终止流处理,不会发起后续请求 .orElseGet(lastResponse::get); // 3次全失败时返回最后一次的响应 }
如果需要严格对齐原有代码无论请求是否成功都休眠5秒的逻辑,直接移除peek方法内的状态码判断即可。
原理解释
Stream.generate()接收Supplier<Response>作为参数,只有当Stream需要获取下一个元素时才会执行内部的请求逻辑,属于懒加载,不会提前生成所有请求结果limit(3)限制最多生成3个元素,即最多发起3次请求filter()过滤出状态码为200的响应findFirst()作为终止操作,找到第一个符合条件的响应后会立刻终止流处理,不会触发后续的请求发送AtomicReference用于存储最后一次请求的响应,应对3次请求全部失败的场景,最终返回最后一次的响应结果,和原有代码逻辑保持一致
补充说明
这种场景下Stream写法的可读性和简洁度和while循环相比没有明显优势,如果你的团队没有强制要求用函数式写法,原有while循环的实现也完全可以保留。
内容的提问来源于stack exchange,提问作者Stanislav Semyonov
相关产品推荐
相关产品推荐

