This repository has been archived by the owner. It is now read-only.

Resource method invoked before filter due to misplaced annotation #3731

Closed
hwellmann opened this Issue Dec 6, 2017 · 2 comments

Comments

Projects
None yet
2 participants
@hwellmann

hwellmann commented Dec 6, 2017

Scenario

There is a resource method with a misplaced @PathParam method annotation (instead of or in addition to a parameter annotation).

The application has at least one post-matching container request filter.

Expected behaviour

An error is logged during validation, the application does not start.

Or the annotation is ignored, and the container request filter is invoked before the resource method.

Actual behaviour

The resource method is invoked before the request filter. (Apparently, due to the @PathParam method annotation, the method is regarded as a setter and invoked during the injection phase).

Example

public class InvalidInjectionTest extends JerseyTest {

    @Override
    protected Application configure() {
        return new ResourceConfig(
                BasicTestsResource.class,
                PostMatchingFilter.class
        );
    }

    @Test
    public void testPostMatching() {
        test("postMatching");
    }

    private void test(String name) {
        Response r = target("basic").path(name).request().get();
        assertEquals("Unexpected HTTP response status code.", 200, r.getStatus());
        assertTrue("Response does not have entity.", r.hasEntity());
        assertEquals("Unexpected response entity value.", name, r.readEntity(String.class));
    }

    @Path("/basic")
    public static class BasicTestsResource {

        @Path("postMatching")
        @GET
	// misplaced annotation causes resource method to be invoked before filter
        @PathParam("id")
        public String getPostMatching() {
            System.out.println("method");
            return "postMatching";
        }
    }

    public static class PostMatchingFilter implements ContainerRequestFilter {

        @Override
        public void filter(ContainerRequestContext requestContext) throws IOException {
            System.out.println("filter");
        }
    }
}

Running this test prints

method
filter
method

The expected output is

filter
method
@jansupol

This comment has been minimized.

Member

jansupol commented Feb 23, 2018

Here is what it does: The method annotated with @PathParam is treated as a setter method. When the resource class is instantiated, the setter method is called. In this case the resource method is not a setter, it does not set anything, but it is still invoked. The consequent filter and method invocations are regularly from the request.

We should not allow to a resource with a resource method annotated with the @XXXParam to be valid, because of side effects of the resource method being called twice as you showed.

@jansupol jansupol closed this Feb 23, 2018

@jansupol

This comment has been minimized.

Member

jansupol commented Feb 23, 2018

Fixed in 2.27

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.