在动作合成期间访问Play框架的路线参数 [英] Access Play Framework route parameters during action composition

查看:68
本文介绍了在动作合成期间访问Play框架的路线参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have an action I want to apply to multiple routes in my Play application. These routes perform actions on a product, and a product can have various versions. I want my API to work such that the user can specify a version explicitly (via a query parameter), and if they do not specify one we will look up the latest version from the DB for them and operate on that one. So this action needs to be able to look up the latest version of a product, but we need to know which product is being asked for. In the route's controller, this is obvious. Play calls the route controller with route parameters as arguments:

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

但是在我们的操作中,我们只有此Play内部Context对象可以使用.我的动作看起来像这样:

But in our action, we only have this Play internal Context object to work with. My action looks something like this:

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( ... );
        }
    }
}

尽管我在该操作中还有一些其他有效性检查.有时我会立即从那里返回错误.因此,我们可以通过向所有路由添加查询字符串参数版本"并在每个路由控制器中添加六行代码来替换此动作组合解决方案:

Although I have some additional validity checking in that action. Sometimes I return an error from there immediately. So we could replace this action composition solution by adding the query string parameter "version" to all the routes and adding a half dozen lines of code in each of my route controllers:

@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对象中包含很多东西.标题在那里,查询参数在那里,甚至被命中的确切路径也在那里!即使不是这样,到那时框架仍已解析路由并确定了路由参数的值.这必须是正确的,因为如果不是,那么它将如何知道要调用哪个动作?但是,这些解析的参数似乎对我们完全不可用.我们可以自己从路径上再次解析它们.但是,为什么我们必须这样做呢?我们将解析路径两次.为什么框架不公开这些值?

But this use case is exactly what action composition should be for, I think. It just seems that the route parameters are missing. The Context object exposed in the Action call() method has a lot of stuff in it, actually. Headers are there, query parameters are there, and even the exact path being hit is there! Even if that were not so, by the point the framework has parsed the route and determined the values of the route parameters. This must be true because if it was not, then how would it know which action to call? However, it appears that these parsed parameters are completely unavailable to us. We could parse them again ourselves from the path. But why should we have to do that? We would be parsing the path twice. Why doesn't the framework expose these values?

我发现有一篇有趣的文章,为解决类似的问题,提出了一种将url参数放入查询字符串参数映射中的黑客. https://alots .wordpress.com/2014/05/01/access-url-parameters-as-get-parameters-in-play/ 但是在我看来,尽管我可能不太理解Scala,但我还是会误解它,尽管我可能会误解它.如果是这样,我不妨修改逻辑以重新解析Action中的路径.

There's an interesting article I found that, to solve a similar problem, suggests a hack that will put a url parameter into the query string parameters map. https://alots.wordpress.com/2014/05/01/accessing-url-parameters-as-get-parameters-in-play/ However it appears to me that this method is also basically double parsing the path anyway, although I might be misinterpreting it as I'm not very familiar with Scala. If so, I might as well just hack in logic to reparse the path in my Action.

推荐答案

至少,您不能开箱即用. Play无法提供在动作组合中获取请求参数的方法.

You can't, at least, not out of the box. Play doesn't provide ways to get the request params in action composition.

基本上:您必须分析自己.

Basically : You have to parse yourself.

这篇关于在动作合成期间访问Play框架的路线参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆