【问题标题】:How can I pass string path param containing slash character?如何传递包含斜杠字符的字符串路径参数?
【发布时间】:2016-11-20 23:03:50
【问题描述】:

我有这个 REST 资源:

@GET
@Path("{business},{year},{sample}")
@Produces(MediaType.APPLICATION_JSON)
public Response getSample(
        @PathParam("business") String business,
        @PathParam("year") String year,
        @PathParam("sample") String sampleId {
    Sample sample = dao.findSample(business, year, sampleId);
    return Response.ok(sample).build();
}

sample 参数可以包含斜杠字符:例如6576/M982

我用http://ip:port/samples/2000,2006,6576/M982 调用它,但显然不起作用。

我也试过http://ip:port/samples/2000,2006,6576%2FM982,将斜杠编码为%2F,但也不起作用,它没有到达端点。

编辑

我正在使用 Retrofit 调用端点,我这样做:

@GET("/samples/{business},{year},{sampleId}")
Observable<Sample> getSampleById(
        @Path("business") String business,
        @Path("year") String year,
        @Path(value = "sampleId", encoded = true) String sampleId);

使用encoded = true,但仍然无法正常工作。

【问题讨论】:

  • 你必须URLEncode它。
  • 你试过@GET("/samples/{business}%2C{year}%2C{sampleId}")吗?

标签: java spring jersey


【解决方案1】:

,/ 等保留字符必须经过 URL 编码。

  • , 编码为 %2C
  • / 编码为 %2F

试试http://ip:port/samples/2000%2C2006%2C6576%2FM982


RFC 3986 定义了以下一组可用作分隔符的reserved characters。因此,它们需要 URL 编码:

: / ? # / [ ] / @ ! $ & ' ( ) * + , ; =

Unreserved characters 不需要 URL 编码:

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
a b c d e f g h i j k l m n o p q r s t u v w x y z
0 1 2 3 4 5 6 7 8 9 - _ . ~

如果 URL 编码 , 对您来说不是一个好的选择,您可以考虑使用查询参数。您的代码将如下所示:

@GET
@Produces(MediaType.APPLICATION_JSON)
public Response getSample(@QueryParam("business") String business, 
                          @QueryParam("year") String year,
                          @QueryParam("sample") String sampleId {
    ...
}

您的网址将类似于http://ip:port/samples?business=2000&amp;year=2006&amp;sample=6576%2FM982

请注意,/ 仍需要进行 URL 编码。

【讨论】:

  • "保留字符,如 , 和 / 必须是 URL 编码的。"尽管查询内容确实如此,但路径内容不一定如此。来自同一个 rfc:“因此,保留集中的字符不受规范化的保护,因此可以安全地被特定于方案和特定于生产者的算法用于分隔 URI 中的数据子组件。”因此,如果将斜杠用作路径分隔符,则可以不对斜杠进行编码。此外,编码的斜线会让你在一些网络服务器(tomcat)上遇到麻烦
  • @Amalgovinus 是的。但是,在 OP 情况下,看起来 / 不是路径分隔符。所以编码没问题。
  • 请注意,包含 %2F 的 URL 被许多 http 和应用程序服务器阻止,因为旧 http 服务器中的错误意味着会解码 %2F 并将其视为路径分隔符,而不应用路径安全检查跨度>
【解决方案2】:

尝试使用{sample:.+} 而不是{sample}

@Path 注释是正则表达式,正则表达式不匹配 / 字符。

要覆盖正则表达式,我们可以在PathParam 的末尾添加.+

通过这种方式,我们可以在路径中允许/,避免使用%2F

【讨论】:

  • 解释不足
【解决方案3】:

实际上,.+ 提供了帮助。只是它需要是@Path 的一部分,而不是@PathParam

例子:

@Path("{sample:.+}")

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-02-20
    • 2016-04-06
    • 2012-06-28
    • 2014-02-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多