@Post method with capturing parenthesis in @Path not matched in Jersey

拈花ヽ惹草 提交于 2019-12-24 01:39:25

问题


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 on ReadOnlyAtomFeed.getFeed is not inherited by ActivityLog.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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!