我在获取与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中可能还有其他东西在起作用。