Jax-RS:与方法注释@GET @POST结合使用时,不接受可选的路径参数

时间:2019-04-25 07:45:02

标签: java rest jersey jax-rs

我通过jerseyjacksonmaven一起使用:

    <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>

我有一个使用以下方法+ POST方法的服务类:

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


@POST
@Path("{Prefix}{p:/?}{id: ((\\d+)?)}/abc/{myValueVariable}")
@Produces(MediaType.APPLICATION_JSON)
public Response setMyToken(@Context ServletContext context, @Context Request request, @HeaderParam("If-None-Match") String ifMatch, @HeaderParam("Prefer") String prefer) {..}

GET网址应该接受两个可选参数。例如。以下网址应匹配:

  • P / 1 / abc / 我的号码
  • P / abc / 我的号码
  • P / 1 / abc

但是,前两个网址似乎不匹配-第二个可选参数似乎无法识别(我收到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) {..}

以下网址匹配:

  • P / 1 / abc / MyNumber / endPath
  • P / abc / 我的号码 / endPath
  • P / 1 / abc / endPath

我不想使用最后一个参数。我该如何解决这个问题?我在做什么错了?

编辑: 我进一步注意到,如果我不使用第一个占位符,它将起作用:

@GET
@Path("hardCodePrefix{p:/?}{id: ((\\d+)?)}/abc{p2:/?}{number: (([A-Za-z0-9]*)?)}")

一旦我尝试用变量或正则表达式替换hardCodePrefix,就会遇到上述问题(URL不匹配)

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

@GET
@Path("hardCodePrefix{p:/?}{id: ((\\d+)?)}/abc{p2:/?}{number: .*}")

例如P / 1 / abc /匹配,我得到/用于p2。但是类似P / 1 / abc / 2的东西将不再起作用。...(无匹配方法错误)


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

现在,我做了一个 有趣的观察 。如果我向我的服务类添加了附加POST服务,则GET服务不起作用(URL P / abc / MyNumber 返回未找到方法错误) ,如果我将其删除(由于我一直都在使用POST方法,因此发生了上述问题):

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

}
/*with that code below the GET method does not work, if I remove it, it works*/
@POST
@Path("{Prefix}{p:/?}{id: ((\\d+)?)}/abc/{yeah}")
public Response doAnything3() {
    return Response.ok("sdf").build();

}

POST的存在似乎干扰了GET方法的工作:这是球衣的臭虫吗?

我使用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();

}

URL调用的mypath/1/abc/dd GET返回方法未找到错误。 如果我更改,将带有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的最后一个参数不应是可选的(请参阅问题的上部))。我不知道为什么会发生这种奇怪的事情->答案应该阐明为什么会发生这种情况,并在答案中提供一个很好的解决方案。

0 个答案:

没有答案