Java Jax-RS:可选路径参数不能与方法注释@GET@POST结合使用

Java Jax-RS:可选路径参数不能与方法注释@GET@POST结合使用,java,rest,jersey,jax-rs,Java,Rest,Jersey,Jax Rs,我正在通过maven与jackson一起使用jersey: <jackson.version>2.9.6</jackson.version> <jersey.version>2.25.1</jersey.version> <jetty.version>9.2.11.v20150529</jetty.version> .... <dependency> <

我正在通过
maven
jackson
一起使用
jersey

    <jackson.version>2.9.6</jackson.version>
    <jersey.version>2.25.1</jersey.version>
    <jetty.version>9.2.11.v20150529</jetty.version>
     ....
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-core</artifactId>
      <version>${jackson.version}</version>
    </dependency>
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-annotations</artifactId>
      <version>${jackson.version}</version>
    </dependency> 
    <dependency>
      <groupId>com.fasterxml.jackson.jaxrs</groupId>
      <artifactId>jackson-jaxrs-base</artifactId>
      <version>${jackson.version}</version>
    </dependency>
    <dependency>
      <groupId>com.fasterxml.jackson.jaxrs</groupId>
      <artifactId>jackson-jaxrs-json-provider</artifactId>
      <version>${jackson.version}</version>
    </dependency>   
    <dependency>
            <groupId>javax.activation</groupId>
            <artifactId>activation</artifactId>
            <version>1.1.1</version>
     </dependency>
     <dependency>
            <groupId>javax.xml.bind</groupId>
            <artifactId>jaxb-api</artifactId>
            <version>2.3.0</version>
     </dependency>
     <dependency>
            <groupId>com.sun.xml.bind</groupId>
            <artifactId>jaxb-core</artifactId>
            <version>2.3.0</version>
      </dependency>
      <dependency>
            <groupId>com.sun.xml.bind</groupId>
            <artifactId>jaxb-impl</artifactId>
            <version>2.3.0</version>
      </dependency>

    <!-- Jersey Server -->
    <dependency>
        <groupId>org.glassfish.jersey.core</groupId>
        <artifactId>jersey-server</artifactId>
        <version>${jersey.version}</version>
     </dependency>    
    <dependency>
        <groupId>org.glassfish.jersey.containers</groupId>
        <artifactId>jersey-container-servlet-core</artifactId>
        <version>${jersey.version}</version>
    </dependency>
    <dependency>
        <groupId>org.glassfish.jersey.containers</groupId>
        <artifactId>jersey-container-jetty-http</artifactId>
        <version>${jersey.version}</version>
    </dependency>
    <dependency>
        <groupId>org.glassfish.jersey.media</groupId>
        <artifactId>jersey-media-json-jackson</artifactId>
        <version>${jersey.version}</version>
        <exclusions>
         <exclusion>
            <groupId>com.fasterxml.jackson.jaxrs</groupId>
            <artifactId>jackson-jaxrs-base</artifactId>
          </exclusion>
           <exclusion>
            <groupId>com.fasterxml.jackson.jaxrs</groupId>
            <artifactId>jackson-jaxrs-json-provider</artifactId>
          </exclusion>
          <exclusion>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-annotations</artifactId>
         </exclusion>
        </exclusions>
    </dependency>
GET
Url应接受两个可选参数。例如,以下URL应匹配:

  • P/1/abc/MyNumber
  • P/abc/MyNumber
  • P/1/abc
但是,前两个URL似乎不匹配-第二个可选参数似乎无法识别(我得到一个405错误-未调用方法)。我测试了很多东西,我意识到在最后添加一个额外的参数会导致我的URL匹配。所以用下面的方法

@GET
@Path("{Prefix}{p:/?}{id: ((\\d+)?)}/abc{p2:/?}{number: (([A-Za-z0-9]*)?)}/endPath")
@Produces(MediaType.APPLICATION_JSON)
public Response getMyToken(@Context ServletContext context, @Context Request request, @HeaderParam("If-None-Match") String ifMatch, @HeaderParam("Prefer") String prefer) {..}
以下URL匹配:

  • P/1/abc/MyNumber/endPath
  • P/abc/MyNumber/endPath
  • P/1/abc/endPath
我不想要最后一个参数。我如何解决这个问题?我做错了什么

编辑: 我进一步注意到,如果我不使用第一名持有者,它会起作用:

@GET
@Path("hardCodePrefix{p:/?}{id: ((\\d+)?)}/abc{p2:/?}{number: (([A-Za-z0-9]*)?)}")
只要我尝试用变量或正则表达式替换硬代码前缀,我就会遇到如上所述的问题(URL不匹配)

EDIT2: 真正奇怪的是,即使是*通配符也不起作用

@GET
@Path("hardCodePrefix{p:/?}{id: ((\\d+)?)}/abc{p2:/?}{number: .*}")
例如,p/1/abc/是匹配的,我得到了p2的
/
。然而,像P/1/abc/2这样的东西不再起作用了。。。。(无匹配方法错误)


EDIT3:Finding-如果存在POST方法,则无法识别GET方法的可选参数

现在,我做了一个有趣的观察。如果我在我的服务类中添加了一个附加的
POST
服务,那么
GET
服务将不起作用(
URL
P/abc/MyNumber返回“未找到任何方法”错误),如果我删除它,则该服务将起作用(出现上述问题是因为我一直在另外使用POST方法):

POST
的存在似乎干扰了
GET
方法的工作:这是jersey的错误吗?

我使用
Postman
测试代码,并显式设置
GET
方法。 我如何解决这些问题?

EDIT4:有限答案

给定以下代码:

@POST
@Path("{Prefix2}{p4:/?}{id8: ((\\d+)?)}/abc/{yeah}")
public Response doAnything3() {
    return Response.ok("sdf").build();

}

@GET
@Path("{Prefix}{p:/?}{id: ((\\d+)?)}/abc{p2:/?}{number: (([A-Za-z0-9]*)?)}")
public Response doAnything2() {
    return Response.ok("sdf").build();

}
使用
GET
调用的
URL
mypath/1/abc/dd
返回一个Method not found错误。 如果我用POST注释的方法更改为

/*adding the last to parameters as an optional parameters*/
@POST
@Path("{Prefix}{p:/?}{id: ((\\d+)?)}/abc{p8:/?}{number: (([A-Za-z0-9]*)?)}"
public Response doAnything3() {
    return Response.ok("sdf").build();

}

@GET
@Path("{Prefix}{p:/?}{id: ((\\d+)?)}/abc{p2:/?}{number: (([A-Za-z0-9]*)?)}")
public Response doAnything2() {
    return Response.ok("sdf").build();

}

解决了问题。这是一个棘手的解决办法(因为最后一个使用
POST
的参数不应该是可选的(请参见问题的上半部分))。我不知道为什么会发生这种奇怪的事情->答案应该澄清为什么会发生这种情况,并且应该在答案中给出一个很好的解决方案。

首先想到的是:您是否尝试只添加最后的“/”?是的,不起作用。。。。
@POST
@Path("{Prefix2}{p4:/?}{id8: ((\\d+)?)}/abc/{yeah}")
public Response doAnything3() {
    return Response.ok("sdf").build();

}

@GET
@Path("{Prefix}{p:/?}{id: ((\\d+)?)}/abc{p2:/?}{number: (([A-Za-z0-9]*)?)}")
public Response doAnything2() {
    return Response.ok("sdf").build();

}
/*adding the last to parameters as an optional parameters*/
@POST
@Path("{Prefix}{p:/?}{id: ((\\d+)?)}/abc{p8:/?}{number: (([A-Za-z0-9]*)?)}"
public Response doAnything3() {
    return Response.ok("sdf").build();

}

@GET
@Path("{Prefix}{p:/?}{id: ((\\d+)?)}/abc{p2:/?}{number: (([A-Za-z0-9]*)?)}")
public Response doAnything2() {
    return Response.ok("sdf").build();

}