问题
I am having trouble getting JAX-RS POST methods to match with Jersey. Verbatim paths work fine ("/prefix/ABC/DEF"), but parenthesised captures ("/prefix/{alpha}/{beta}") fail to trigger. Here are the methods in question, as defined in the server interface, using 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);
...
}
And here in the implementation class:
@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);
...
}
I get the following logs:
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
Is there something simple that I am missing, or do I need to somehow enable fancier pattern matching somewhere?
回答1:
The section regarding annotation inheritance of the JAX-RS 2.0 specification is pretty clear. See the quote below:
3.6 Annotation Inheritance
JAX-RS annotations may be used on the methods and method parameters of a super-class or an implemented interface. Such annotations are inherited by a corresponding sub-class or implementation class method provided that the method and its parameters do not have any JAX-RS annotations of their own. Annotations on a super-class take precedence over those on an implemented interface. The precedence over conflicting annotations defined in multiple implemented interfaces is implementation specific. Note that inheritance of class or interface annotations is not supported.
If a subclass or implementation method has any JAX-RS annotations then all of the annotations on the superclass or interface method are ignored. E.g.:
public interface ReadOnlyAtomFeed { @GET @Produces("application/atom+xml") Feed getFeed(); } @Path("feed") public class ActivityLog implements ReadOnlyAtomFeed { public Feed getFeed() {...} }
In the above,
ActivityLog.getFeed
inherits the@GET
and@Produces
annotations from the interface. Conversely:@Path("feed") public class ActivityLog implements ReadOnlyAtomFeed { @Produces("application/atom+xml") public Feed getFeed() {...} }
In the above, the
@GET
annotation onReadOnlyAtomFeed.getFeed
is not inherited byActivityLog.getFeed
and it would require its own request method designator since it redefines the@Produces
annotation.For consistency with other Java EE specifications, it is recommended to always repeat annotations instead of relying on annotation inheritance.
For some reason, the only annotations of the javax.ws.rs package annotated with @Inherited are @Consumes and @Produces.
回答2:
From my original answer:
Jax-RS 2.0 annotations for parameterised Jersey methods need to be placed next to the implementation - if they are just placed in a parent interface they are not picked up (at least in Jersey 22.2.2).
Refinement: the above is only true if there is already a Jax-RS 2.0 annotation on the overriding/implementing method - in this case, @PathParam
. In this case, the spec mandates that any parent Jax-RS 2.0 annotations are disregarded. Thanks to peeskillet for pointing this out.
This may be because
@Path
is not an@Inherited
annotation (possibly because inherited annotations can be problematic because of multiple inheritance).
Refinement: The Jax-RS 2.0 spec seems to mandate that any implementation/overridden methods will inherit Jax-RS annotations from the parent, and doesn't specify that this will necessarily be based on standard annotation inheritance, so perhaps something else is at work in Jersey.
来源:https://stackoverflow.com/questions/36682011/post-method-with-capturing-parenthesis-in-path-not-matched-in-jersey