【问题标题】:Jax-RS overloading methods/paths order of executionJax-RS 重载方法/路径的执行顺序
【发布时间】:2015-06-07 06:57:49
【问题描述】:

我正在为我的应用编写 API,但我对 Jax-RS 如何处理某些场景感到困惑

比如我定义了两条路径:

@Path("user/{name : [a-zA-Z]+}")

@Path("user/me")

我指定的第一个路径清楚地包含第二个路径,因为正则表达式包含所有字母 a-z。但是,该程序似乎对此没有问题。是不是因为它默认是最具体的路径(即 /me 然后查找正则表达式)?

此外,如果我将两个正则表达式定义为有一些重叠的路径会发生什么。有没有会调用的默认方法?

假设我想为三种不同的方法创建三个路径:

@Path{"user/{name : [a-zA-Z]+}")
@Path("user/{id : \\d+}")
@Path("user/me")

这是最佳做法/合适吗?它如何知道调用哪个方法?

提前感谢您的澄清。

【问题讨论】:

    标签: regex api rest jax-rs


    【解决方案1】:

    这是在“将请求与资源方法匹配”中的the spec

    E进行排序,使用(1)每个成员中文字字符的数量作为主键(降序),(2)捕获组的数量作为辅助键(降序),(3) 使用非默认正则表达式(即不是 '([^ /]+?)')作为第三键的捕获组的数量(降序顺序),...

    会发生的是候选方法按指定的有序“键”排序。我用粗体突出显示它们。

    第一个排序键是文字字符的数量。所以对于这三个

    @Path{"user/{name : [a-zA-Z]+}")
    @Path("user/{id : \\d+}")
    @Path("user/me") 
    

    如果请求的 URI 是 ../user/me,将始终选择最后一个,因为它具有最多的文字字符(7 个,/ 计数)。其他的只有 5 个。

    除了../users/me 之外的任何其他../users/.. 都将取决于正则表达式。在您的情况下,一个只匹配数字,一个只匹配字母。这两个正则表达式无法重叠。所以它会相应地匹配。

    现在只是为了好玩,假设我们有

    @Path{"user/{name : .*}")
    @Path("user/{id : \\d+}")
    @Path("user/me")
    

    如果您查看前两个,我们现在有重叠的正则表达式。第一个将匹配所有数字,第二个也将匹配。那么将使用哪一个呢?我们无法做出任何假设。这是一个未指定的歧义级别,我已经看到来自不同实现的不同行为。 AFAIK,没有“最佳匹配”正则表达式的概念。要么匹配,要么不匹配。

    但是,如果我们希望始终首先检查 {id : \\d+} 怎么办。如果它与数字匹配,那么应该选择它。我们可以根据规范破解它。该规范谈到了基本上是{..}s 的“捕获组”。第二个排序键是捕获组的数量。我们可以破解它的方法是添加另一个“可选”组

    @Path{"user/{name : .*}")
    @Path("user/{id : \\d+}{dummy: (/)?}")
    

    现在后者有更多的捕获组,所以它总是在排序中领先。它所做的只是允许一个可选的/,这并不真正影响API,但确保如果请求URI 是全数字,则始终选择此路径。

    你可以看到一些测试用例的讨论in this answer

    【讨论】:

    • 很好的答案!谢谢,我试图找到规范但没有运气。
    猜你喜欢
    • 2011-06-14
    • 1970-01-01
    • 1970-01-01
    • 2017-09-02
    • 2012-06-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-03
    相关资源
    最近更新 更多