@在Jersey中,在@Path中带有捕获括号的Post方法不匹配



我在获取与Jersey匹配的JAX-RSPOST方法时遇到问题。逐字路径工作正常("/prefix/ABC/DEF"),但带括号的捕获("/pprefix/{alpha}/{beta}")无法触发。以下是使用Jersey在服务器接口中定义的有问题的方法。

public interface CollectorEndpoint
{
    ...
    @POST
    @Path("/prefix/{alpha}/{beta}") //doesn't match
    @Consumes(MediaType.APPLICATION_JSON)
    Response method1(@PathParam("alpha") String alpha,
                     @PathParam("beta") String beta,
                     String jsonContent);
    @POST
    @Path("/prefix/ABC/DEF")        //works for that one specific case
    @Consumes(MediaType.APPLICATION_JSON)
    Response method2(String jsonContent);
    ...
}

在实现类中:

@Path("/collect")
public class RestCollectorEndpoint implements CollectorEndpoint {
    ...
    @Override
    public Response method1(@PathParam("alpha") String alpha,
                            @PathParam("beta") String beta,
                            String jsonContent) {...}
    @Override
    public Response method2(String jsonContent);
    ...
}

我得到以下日志:

Matching path [/prefix/notabc/notdef]
X-Jersey-Tracing-010: MATCH       [ ---- /  0.77 ms |  ---- %] Pattern [/getpattern1(/)?] is NOT matched
X-Jersey-Tracing-011: MATCH       [ ---- /  0.77 ms |  ---- %] Pattern [/getpattern2(/)?] is NOT matched
X-Jersey-Tracing-012: MATCH       [ ---- /  0.78 ms |  ---- %] Pattern [/getpattern3(/)?] is NOT matched
X-Jersey-Tracing-013: MATCH       [ 0.09 /  0.79 ms |  7.47 %] RequestMatching summary
X-Jersey-Tracing-014: RESP-FILTER [ 0.23 /  1.18 ms | 18.96 %] Filter by [org.glassfish.jersey.filter.LoggingFilter @76ccd017 #-2147483648]
X-Jersey-Tracing-015: RESP-FILTER [ 0.26 /  1.19 ms | 21.52 %] Response summary: 1 filters
X-Jersey-Tracing-016: FINISHED    [ ---- /  1.21 ms |  ---- %] Response status: 404/CLIENT_ERROR|Not Found
Date: Sun, 17 Apr 2016 18:19:08 GMT
Content-Length: 0

是我缺少了一些简单的东西,还是我需要在某个地方实现更花哨的模式匹配?

关于JAX-RS2.0规范的注释继承的部分非常清楚。请参阅以下报价:

3.6注释继承

JAX-RS注释可以用于超类或实现接口的方法和方法参数。这样的注释由相应的子类或实现类方法继承,前提是该方法及其参数不具有任何自己的JAX-RS注释。超类上的注释优先于已实现接口上的注释。在多个实现的接口中定义的冲突注释的优先级是特定于实现的。请注意,不支持类或接口注释的继承。

如果一个子类或实现方法有任何JAX-RS注释,则超类或接口方法上的所有注释都将被忽略。例如:

public interface ReadOnlyAtomFeed {
    @GET 
    @Produces("application/atom+xml")
    Feed getFeed();
}
@Path("feed")
public class ActivityLog implements ReadOnlyAtomFeed {
    public Feed getFeed() {...}
}

在上文中,ActivityLog.getFeed从接口继承了@GET@Produces注释。相反:

@Path("feed")
public class ActivityLog implements ReadOnlyAtomFeed {
    @Produces("application/atom+xml")
    public Feed getFeed() {...}
}

在上文中,ReadOnlyAtomFeed.getFeed上的@GET注释不是由ActivityLog.getFeed继承的,并且它将需要自己的请求方法指示符,因为它重新定义了@Produces注释。

为了与其他Java EE规范保持一致,建议始终重复注释,而不是依赖注释继承。


出于某种原因,用@Inherited注释的javax.ws.rs包的唯一注释是@Consumes@Produces

根据我最初的答案:

参数化Jersey方法的Jax RS 2.0注释需要放在实现旁边——如果它们只是放在父接口中,则不会被拾取(至少在Jersey 22.2.2中)

改进:只有当覆盖/实现方法上已经有Jax RS 2.0注释时,上述情况才成立——在本例中为@PathParam。在这种情况下,规范要求忽略任何父Jax RS 2.0注释。感谢peeskillet指出这一点。

这可能是因为@Path不是@Inherited注释(可能是因为由于多重继承,继承的注释可能会有问题)。

改进:Jax RS 2.0规范似乎规定任何实现/重写的方法都将从父级继承Jax RS注释,并且没有规定这必须基于标准注释继承,所以在Jersey中可能还有其他东西在起作用。

最新更新