【问题标题】:Multiple JAX RS paths triggering the wrong method触发错误方法的多个 JAX RS 路径
【发布时间】:2017-10-01 23:01:30
【问题描述】:

我有以下服务(我无法控制路径和注释)

@Path("/")
public class MyService { 

 @GET
 @Path("/{id}")
 @Produces(MediaType.APPLICATION_JSON)
 public void getById(@PathParam("id") final Long id) {...}

 @GET
 @Produces(MediaType.APPLICATION_JSON)
 public void getAll(@QueryParam("param1") Long param1
                   ,@QueryParam("param2") Long param2) {...}
}

场景 A:

如果服务是使用 /rest/myservice 的应用程序上下文部署的,并且 web.xml 映射是

<servlet-mapping>
    <servlet-name>MyServlet</servlet-name>
    <url-pattern>/*</url-pattern>
</servlet-mapping>

一切正常。 调用 GET http://localhost:8080/rest/myservice/123 调用 getById 调用 GET http://localhost:8080/rest/myservice?param1=123 调用 getAll

场景 B:

如果服务是使用 /rest 的应用程序上下文部署的,并且 web.xml 映射是

<servlet-mapping>
     <servlet-name>MyServlet</servlet-name>
     <url-pattern>/myservice/*</url-pattern>
 </servlet-mapping>

对 GET http://localhost:8080/rest/myservice/123 的调用仍会调用 getById 但对 GET http://localhost:8080/rest/myservice?param1=123 的调用也会调用 getById 并且 Jersey 在 NumberFormatException 上崩溃(它认为 /myservice实际上是方法的第一个参数,id是Long)。

同样重要的是要提到 GET http://localhost:8080/rest/myservice/(注意尾部的斜杠)确实会调用 getAll,但是我将无法发送参数。

我唯一可以控制的是 web.xml 和应用程序上下文(但它不能是 /rest/myservice。它必须是通用的并且与服务名称无关)

有没有办法让场景 B 工作?

更新:添加客户端代码

来自 Restlet 客户端的简单 Rest 调用:

GET http://localhost:8080/rest/myservice/123 - 200 OK

GET http://localhost:8080/rest/myservice?param1=123 导致异常

org.glassfish.jersey.server.internal.inject.ExtractorException: java.lang.NumberFormatException: For input string: "myservice"
    at org.glassfish.jersey.server.internal.inject.ParamConverters$AbstractStringReader.fromString(ParamConverters.java:90)
    at org.glassfish.jersey.server.internal.inject.AbstractParamValueExtractor.convert(AbstractParamValueExtractor.java:138)
    at org.glassfish.jersey.server.internal.inject.AbstractParamValueExtractor.fromString(AbstractParamValueExtractor.java:129)
    at org.glassfish.jersey.server.internal.inject.SingleValueExtractor.extract(SingleValueExtractor.java:83)
    at org.glassfish.jersey.server.internal.inject.PathParamValueFactoryProvider$PathParamValueFactory.provide(PathParamValueFactoryProvider.java:92)
    at org.glassfish.jersey.server.spi.internal.ParameterValueHelper.getParameterValues(ParameterValueHelper.java:81)
    at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$AbstractMethodParamInvoker.getParamValues(JavaResourceMethodDispatcherProvider.java:121)
    at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$VoidOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:136)

【问题讨论】:

  • 那么,如果场景 B 不适合你,为什么不能使用场景 A?
  • 我们有很多使用场景 A 中描述的配置的 Web 服务。我正在尝试创建某种包装器以便一次加载它们。 (为什么?为了在资源有限的本地机器上的容器中运行它们时获得性能)。这意味着我只有 1 个 web.xml,即包装器的 web.xml,并且我无法使用场景 A 中描述的配置。
  • 您可以发布客户端代码吗? /myservice 不太可能被解释为参数(顺便说一句,param1 设置为 blah 而不是数字)。
  • 您对 param1 的看法是正确的,也对其进行了编辑。无论 param1 是作为 Long 还是 String 发送,仍然会发生异常。
  • 那么我将无法发送参数:为什么? http://localhost:8080/rest/myservice/?param1=123&amp;param2=456 怎么样?

标签: java rest web-services jersey jax-rs


【解决方案1】:

为了完整起见,http://localhost:8080/rest/myservice/?param1=123&param2=456 确实有效。 (谢谢@JBNizet

'?' 前的斜线将 requestRelativeContext 从 /myservice 更改为 /

更新:事实证明,此问题不会在较新的 Jersey 版本中重现。 2.25.1 版不受此影响。

【讨论】:

    猜你喜欢
    • 2011-06-14
    • 1970-01-01
    • 1970-01-01
    • 2017-09-02
    • 2022-01-21
    • 1970-01-01
    • 2011-07-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多