繁体   English   中英

在动作合成期间访问Play Framework路由参数

[英]Access Play Framework route parameters during action composition

我有一个动作,我想在我的Play应用程序中应用于多个路线。 这些路由对产品执行操作,产品可以具有各种版本。 我希望我的API工作,以便用户可以显式指定版本(通过查询参数),如果他们没有指定版本,我们将从数据库中查找最新版本并对其进行操作。 因此,此操作需要能够查找产品的最新版本,但我们需要知道要求的产品。 在路线的控制器中,这是显而易见的。 Play使用路由参数作为参数调用路由控制器:

@RequireProductVersion()
public CompletionStage<Result> getProduct(String productId) {
    ...
}

但是在我们的操作中,我们只有这个Play内部Context对象才能使用。 我的动作看起来像这样:

public class RequireProductVersion extends Action<RequireProductVersion> {
    @Override
    public CompletionStage<Result> call(Http.Context ctx) {
        final String version = ctx.request().getQueryString("version");
        // if an explicit "version" parameter was specified, verify it and use it
        if (version != null) {
            ...
        } else {
            // look up the latest version for this product
            final String productId = ctx.request.????getParameter("productId");
            return lookupLatestProductVersion(productId).thenCompose( ... );
        }
    }
}

虽然我在该操作中有一些额外的有效性检查。 有时我会立即从那里返回错误。 因此,我们可以通过将查询字符串参数“version”添加到所有路由并在每个路由控制器中添加六行代码来替换此动作组合解决方案:

@RequireProductVersion()
public CompletionStage<Result> getProduct(String productId, @Nullable String productVersion) {
    final int productVersion;
    try {
        productVersion = Utils.getProductVersion(productId, productVersion);
    } catch (ProductVersionException e) {
        return CompletableFuture.completedFuture(e.getAppropriateResult());
    }
    ...
}

但我认为,这个用例正是行动组合应该是什么。 似乎缺少路线参数。 实际上,Action call()方法中公开的Context对象中有很多东西。 标题在那里,查询参数在那里,甚至确切的路径都在那里! 即使不是这样,框架已经解析了路由并确定了路由参数的值。 这必须是真的,因为如果不是,那么它将如何知道要调用哪个动作? 但是,似乎这些解析的参数对我们来说完全不可用。 我们可以从路径中再次解析它们。 但是我们为什么要这样做呢? 我们将解析路径两次。 为什么框架没有公开这些值?

我发现有一篇有趣的文章,为了解决类似的问题,建议将一个url参数放入查询字符串参数映射中。 https://alots.wordpress.com/2014/05/01/accessing-url-parameters-as-get-parameters-in-play/然而,在我看来,这种方法基本上也是双重解析路径,尽管我可能会误解它,因为我对Scala不是很熟悉。 如果是这样,我可能只是破解逻辑来重新解析我的Action中的路径。

你不能,至少,不能开箱即用。 Play不提供在动作合成中获取请求参数的方法。

基本上:你必须解析自己。

好的,所以这个问题在Scala中是可以解决的。 由于Play Java如何使用注释进行动作合成(以及身体解析器,这是我遇到这个完全相同的问题的另一个地方),目前似乎没有任何方法可以在Java中解决它。 您必须自己再次解析路径。 但是,看起来在Scala中很容易实现。 我没有测试其中任何一个,我对Scala不太熟悉,但看起来像Scala中的Play,动作组合的工作方式不同。

这个要点有一个例子,说明Play Scala动作组合应如何支持: https//gist.github.com/wolfendale/75e8b5e9a7ace95aa7e6d123e6c6dacd

jroper在本期帖子中的帖子也证明了我认为同样的解决方案: https//github.com/playframework/playframework/issues/3378#issuecomment-54925034

如果你使用Scala,那么我在原文中链接文章中所展示的技术根本不是解决这个问题所必需的。 但是,因为它只需要在Scala中编写一些代码(而对于wolfendale和jroper演示的技术,你需要在Scala中编写控制器),它可能是解决这个问题的有用方法,但仍然可以编写大部分代码Java中的应用程序。 我不确定。 我没有测试它,我对那种黑客不感兴趣。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM