我有一个我需要重构的方法,因为在Play 2.5中不推荐使用F.Promise。它实际上很可读。它发送请求并通过自定义安全令牌进行身份验证,如果响应为200,则返回true。
public boolean verify(final String xSassToken){
WSRequest request = WS.url(mdVerifyXSassTokenURL)
.setHeader("X-SASS", xSassToken)
.setMethod("GET");
final F.Promise<WSResponse> responsePromise = request.execute();
try {
final WSResponse response = responsePromise.get(10000);
int status = response.getStatus();
if(status == 200 ) { //ok
return true;
}
} catch (Exception e) {
return false;
}
return false;
}
我要做的第一件事是改变这一行:
final F.Promise<WSResponse> responsePromise = request.execute();
对此:
final CompletionStage<WSResponse> responsePromise = request.execute();
但是,CompletionStage(T)没有等效的get()方法,因此我不确定获得WSResponse的最快捷,最简单的方法,我可以验证其状态。
答案 0 :(得分:1)
是的,它没有。至少不是直接的。
你在做什么&#34;错误&#34;在PlayFramework的上下文中。 get
是一个阻止调用,您应该尽可能避免阻塞。这就是WS
提供非阻止API和handle asynchronous results方法的原因。因此,首先,您应该将verify
代码重写为异步:
public CompletionStage<Boolean> verify(final String xSassToken) {
return WS.url(mdVerifyXSassTokenURL)
.setHeader("X-SASS", xSassToken)
.setMethod("GET")
.execute()
.thenApply(response -> response.getStatus() == Http.Status.OK);
}
注意我是如何使用thenApply
返回一个新的java.util.concurrent.CompletionStage
而不是一个普通的布尔值。这意味着调用verify
的代码也可以这样做。根据实例,控制器上的操作可以执行以下操作:
public class MyController extends Controller {
public CompletionStage<Result> action() {
return verify("whatever").thenApply(success -> {
if (success) return ok("successful request");
else return badRequest("xSassToken was not valid");
});
}
public CompletionStage<Boolean> verify(final String xSassToken) { ... }
}
通过这种方式,您的应用程序将能够处理更大的工作量而不会挂起。
由于您必须保持兼容性,因此我将采用这种方式来改进设计并在迁移时保持代码兼容:
/**
* @param xSassToken the token to be validated
* @return if the token is valid or not
*
* @deprecated Will be removed. Use {@link #verifyToken(String)} instead since it is non blocking.
*/
@Deprecated
public boolean verify(final String xSassToken) {
try {
return verifyToken(xSassToken).toCompletableFuture().get(10, TimeUnit.SECONDS);
} catch (Exception e) {
return false;
}
}
public CompletionStage<Boolean> verifyToken(final String xSassToken) {
return WS.url(mdVerifyXSassTokenURL)
.setHeader("X-SASS", xSassToken)
.setMethod("GET")
.execute()
.thenApply(response -> response.getStatus() == Http.Status.OK);
}
基本上,弃用旧的verify
方法并建议用户迁移到新方法。