2016-08-22 54 views
2

我想創建一個可以與@With註釋樣式一起使用的動作。這個動作需要進行RPC調用,所以如果我正確理解了文檔,我應該把它放在異步方式中。Java中的Play Framework 2.5中的動作組合和異步

這就是我試圖做的到現在爲止:

public class GetUserIdAction extends play.mvc.Action.Simple { 

    @Override 
    public CompletionStage<Result> call(Http.Context context) { 
    String token = ""; 

    if (StringUtils.isEmpty(token)) { 
     return delegate.call(context); 
    } 

    CompletionStage<Http.Context> promiseOfUpdatedContext = CompletableFuture.supplyAsync(() -> setUserIdForToken(context, token)); 

    return promiseOfUpdatedContext.thenApply(ctx -> delegate.call(ctx)); 
    } 

    private Http.Context setUserIdForToken(Http.Context context, String token) { 
    context.args.put("user_id", authenticationManager.getUserIdForToken(token)); 
    // The AuthenticationManager is issuing an RPC call and thus may take some time to complete. 
    return context; 
    } 
} 

拋開事實token始終是空的,authenticationManager沒有設置,這僅僅是一個快速無意義的例子,我的IDE抱怨的thenApply部分。據我所知,它期待CompletionStage<Result>,並得到更像CompletionStage<CompletionStage<Result>>

什麼是處理它的方法?因爲這裏我想要的是在上下文中放置一些信息,然後繼續連接。

或者我試圖做一些愚蠢的和組成的行動已經是異步?

回答

1

你有一個CompletionStage<Something>,並希望以CompletionStage<Result>結束。最簡單的方法是使用thenCompose

下面是一個例子,有一個小的變化:我有一個CompletableFuture獲得令牌,只有那時我將它添加到HttpContext的

@Override 
public CompletionStage<Result> call(final Http.Context context) { 
    final String token = ""; 

    if (StringUtils.isEmpty(token)) { 
     return delegate.call(context); 
    } 

    return CompletableFuture.supplyAsync(() -> { 
     // do something to fetch that token 
     return "your_new_token"; 
    }).thenCompose(tokenReceived -> { 
     context.args.put("user_id", tokenReceived); 
     return delegate.call(context); 
    }); 
} 
+0

非常感謝你現在的工作! –

相關問題