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

2024-02-22

我有一个操作想要应用于 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());
    }
    ...
}

但我认为,这个用例正是动作组合的用途。看来只是缺少路由参数。这Context实际上,Action call() 方法中公开的对象包含很多内容。标头在那里,查询参数在那里,甚至所命中的确切路径也在那里!即使事实并非如此,此时框架已经解析了路由并确定了路由参数的值。这一定是真的,因为如果不是,那么它如何知道要调用哪个操作?然而,这些解析的参数似乎对我们来说完全不可用。我们可以自己从路径中再次解析它们。但为什么我们必须这样做呢?我们将解析路径两次。为什么框架不公开这些值?

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


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

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

jroper 在这个问题线程中的帖子也展示了在我看来是相同的解决方案:https://github.com/playframework/playframework/issues/3378#issuecomment-54925034 https://github.com/playframework/playframework/issues/3378#issuecomment-54925034

如果这些有效,该技术将在我在原帖中链接的文章 https://alots.wordpress.com/2014/05/01/accessing-url-parameters-as-get-parameters-in-play/如果您使用 Scala,则完全没有必要解决此问题。然而,因为它只需要在 Scala 中编写一些代码(而对于 Wolfendale 和 jroper 演示的技术,您也需要在 Scala 中编写控制器),所以它可能是解决此问题的有用方法,并且仍然可以编写大部分代码Java 中的应用程序。我不确定。我还没有测试过它,我对那种黑客不感兴趣。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在动作组合期间访问 Play Framework 路由参数 的相关文章

随机推荐

  • 如何根据内容调整 DIV 宽度

    我有一个带有附加样式的 div 元素 mypost border 1px solid Peru font family arial margin auto min width 700px width 700px 我正在 DIV 块内显示 W
  • Xamarin Forms:如何更改 Android 中的工具栏高度?

    我有一个使用 Toolbar 的 XF 应用程序 它已添加到我的 ContentPage 中 如下所示 public HomePage InitializeComponent var toolbarItem new ToolbarItem
  • 在 VB.NET 中使用模块是否被认为是不好的做法?

    在设计新应用程序期间 我想知道使用具有属性的模块是否被认为是一种不好的做法 一些示例代码 Module modSettings public property Setting1 as string public property Datab
  • Flask 应用程序在 Heroku 上失败:没有名为 app 的模块

    我有一个 Flask 应用程序已部署到 Heroku 但出现错误 2018 08 27T12 39 32 197715 00 00 heroku router at error code H10 desc App crashed metho
  • strtotime(PHP日期函数)的算法如何工作?

    我想知道怎么做斯特托时间 php 日期函数 工作吗 如何解析字符串像 2012 年 9 月 15 日 到时间戳 有没有更好的算法 我的目的是改变波斯语的这个功能 您可以浏览PHP的源代码 https github com php php s
  • 客户端-服务器代码应该写在一个还是两个“项目”中? [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 我已经开始开发客户端 服务器应用程序 起初 我自然地在 Eclipse 中创建了两个项目 两个源代码控制存储库等 但我很快发现两者之间有一些共享
  • iPhone SDK 4 中针对多个平台

    我有一个 iPhone SDK 项目 该项目应该为模拟器和 ARM 处理器构建一个静态库 然后将两者组合成一个通用库 到目前为止 我使用的是 iPhone SDK 3 并通过为每个模拟器和一个 ARM 创建一个单独的目标 然后使用 shel
  • $广播到当前范围

    作为前言 我有一个 Ionic 应用程序通过 websocket 连接到 Node 服务器 而 Node 服务器通过 TCP 套接字连接到 C 应用程序 我有这项服务连接并提供套接字服务 但也监视nack响应 以便它可以发出警报 通知用户错
  • 从 RGB 格式的文件加载位图(无 Alpha)

    我只想加载 BMP 文件并获取 24 位 RGB 格式 或 32 位 RGB 格式 的位图对象 我尝试的所有方法都返回 PixelFormat Format32bppArgb 的位图 图像对象 当然 即使 BMP 没有 alpha new
  • 如何通过 SSH 运行 php 脚本? [关闭]

    Closed 这个问题是无关 help closed questions 目前不接受答案 我有一个相当长的 php 脚本 每当我的互联网连接中断一秒钟时 浏览器似乎就会停止该脚本 我不能等待 8 个小时来运行我的脚本 所以我想我可以通过 s
  • “dispatch()”是什么意思/做什么,为什么当我们有 .then() 和 .catch() 时使用它

    我是 ES6 和高级 javascript 新手 我见过使用 axios http 客户端的代码示例 如下所示 axios xxx then res gt dispatch success res err gt dispatch error
  • 哪个函数在堆栈使用效率和时间方面最好

    我编写了 3 个函数来计算元素在列表中出现的次数 我尝试了各种输入并对其进行了分析 但我仍然不知道哪个函数在堆栈使用效率和时间效率方面是最好的 请帮帮我 Using an accumulator defn count instances1
  • OpenCL - 将树复制到设备内存

    我用 C 代码实现了二叉搜索树 我的每个树节点如下所示 typedef struct treeNode int key struct treeNode right struct treeNode left treeNode t 宿主建造的树
  • NSCollectionView 取消多选

    所以我现在已经对这个主题进行了相当多的调查 但还没有发现任何与之相关的有用信息 我的问题是我创建了一个 NSCollectionView 它的作用类似于图像处理程序 因此您可以在其中放置图像 一次选择一个甚至多个图像 并根据需要删除它们 选
  • 如何在redshift中生成12位唯一编号?

    我的表中有 3 列 即email id rid final id 规则rid and final id If the email id有对应的rid use rid as the final id If the email id没有对应的r
  • for循环中多个异步函数之后的NodeJS回调

    我从 mongodb 获取一个文档 其中包含一个带有该文档注释的数组 评论中是撰写评论的用户的 id 我现在需要根据用户的 id 获取用户名 但遇到了几个问题 我有以下代码 显然 它不起作用 但我希望它能让您了解我想要完成的任务 MORE
  • 找不到类 PHP

    I used 这个推特库 https github com abraham twitteroauth并收到此错误 谁能告诉我哪里出错了 ERROR Fatal error Class Abraham TwitterOAuth Config
  • joomla中如何设置默认语言

    我使用 Joomla 1 5 24 Stable 使用 JoomFish 2 2 3 发布来翻译网站 在 joomfish 语言管理器的内容语言中 我有 3 种语言 en ru 和 ro 默认设置为 ro 激活就是全部 无论浏览器语言如何
  • 如何以编程方式打开 .net 2.0。它是否正确?

    我正在尝试以编程方式打开 安装 Net 2 0 Framework视窗功能 B c Windows 7 及更高版本不允许您手动安装 net 我的客户永远无法从控制面板启用该功能 Windows 7 包含 net 2 0 但 Windows
  • 在动作组合期间访问 Play Framework 路由参数

    我有一个操作想要应用于 Play 应用程序中的多个路线 这些路由对产品执行操作 并且产品可以有多个版本 我希望我的 API 能够正常工作 以便用户可以显式指定版本 通过查询参数 如果他们没有指定版本 我们将为他们从数据库中查找最新版本并对其