有没有办法在@Path 注释中指定查询参数?

问题描述

我有一个 Quarkus 服务,我正在尝试(在某种程度上)模仿 S3 API。

我注意到 S3 中的分段上传是这样的:

POST bucket.host.com /KEY?uploads // signifies that a multipart upload on KEY is starting
                                  // and returns an uploadId for it
PUT bucket.host.com /KEY?uploadId=UPLOADID&partNumber=2 // uploads part 2 of the file,// content is in request body
PUT bucket.host.com /KEY?uploadId=UPLOADID&partNumber=1 // upload part 1
POST bucket.host.com /KEY?uploadId=UPLOADID // signifies that the multipart upload is completed

“原子”文件上传(即,没有分段,文件只是一次性上传)“重用”PUT 路径,因此要以这种方式上传文件,您只需在 URL 上执行 PUT 并跳过两者查询参数。

我不会使用“存储桶嵌入在主机名中”的方法,而是将其作为请求 URL 的一部分。

所以我目前拥有的是一个看起来像这样的资源类(在我的例子中简化了,bucket 被称为“project”,KEY 被称为“path”):

@Path("/fts")
class FileTransferService(
    @ConfigProperty(name = "fts.project.root")
    private val projectRoot: String
) {

    @POST
    @Path("{project}/{path:.*}")
    @Produces(MediaType.APPLICATION_JSON)
    fun multipartfileUpload(
        @PathParam project: String,@PathParam path: String,@QueryParam("uploads") uploads: String?,@QueryParam("uploadId") uploadId: String?
    ): String {
        // Here I'll have to check whether uploads or uploadId is set
        // and determine the path to take with some if/else statements.
    }

    @PUT
    @Path("{project}/{path:.*}")
    @Produces(MediaType.APPLICATION_JSON)
    fun upload(
        @PathParam project: String,@QueryParam("uploadId") uploadId: String?,@QueryParam("partNumber") partNumber: String?,body: InputStream
    ): String {
        // Here I'll need to check uploadId and/or partNumber to determine
        // whether this is an "atomic file upload" or a single part of a 
        // multi part upload and determine the path to take with if/else again.
    }
}

正如你在上面代码的注释中看到的,我必须做一些 if/else 检查并根据查询参数是否设置走不同的路线。

这让我很烦。我宁愿有不同的@POST 方法,一种是设置 uploads 参数的情况,另一种是设置 uploadId 参数的情况。

我尝试了多种方法,其中一个指定了 QueryParameter,而另一个没有,但这似乎不起作用。我在 quarkus 日志中收到一条信息消息,指出为该路径找到了多个匹配项,并且随机选择了一个匹配项(可能只是第一个匹配项)。

所以我猜测,如果这完全可行,它会以某种方式将查询参数放入 @Path 注释中,但我一直无法找到如何做到这一点。一个可能的原因是这是不可能的,但我想在这里询问并获得确认。

解决方法

如果您想使用查询参数,您当前的版本是正确的。

您将无法使用 JAX-RS 做您想做的事。路径决定了调用的方法,查询参数只是可选的附加信息。

如果你绝对想根据参数存在有不同的方法,你需要使用路径参数。