LostMekkaSoft
LostMekkaSoft

Reputation: 363

How to use JAX-RS filters with generated controller interfaces? (JavaEE, Wildfly18)

I have a code generator, that generates interfaces for JAX-RS endpoints and my backend app implements these interfaces, to provide the business logic.

The problem now is, that I cannot use name-bound container filters to enhance the business logic or to add security: Any @NameBinding marker annotation on the implementing class or its methods is ignored and the corresponding filter is not called.

Here is a minimal example: (code is in Kotlin, but the issue is the same when implemented in pure Java)

// generated
data class FooDto(val filtered: Boolean)

// generated
@Path("/")
interface OpenApiGeneratedInterface {
    @GET
    @Path("/foo/bar")
    @Produces("application/json")
    fun foo(): FooDto
}

// my implementation
class ImplementingApiController : OpenApiGeneratedInterface {
    @TestMarker
    override fun foo() = FooDto(filtered = false)
}

// may come from external dependency
@NameBinding
@Retention(AnnotationRetention.RUNTIME)
@Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION)
annotation class TestMarker

// may come from external dependency
@Provider
@TestMarker
class TestFilter: ContainerResponseFilter {
    override fun filter(
        requestContext: ContainerRequestContext,
        responseContext: ContainerResponseContext,
    ) {
        responseContext.entity = FooDto(filtered = true)
    }
}

When a request to /foo/bar is made, I get {"filtered":false}, so the filter is not running. When I move the @TestMarker annotation from ImplementingApiController::foo to OpenApiGeneratedInterface::foo, I instead get {"filtered":true}, so the filter did run this time. Note, that modifying the interface is not possible in reality, since the real interfaces are generated. I only did this in the example to show that the filter is working in general.

The problem seems to be, that the system only looks for marker annotations on the interfaces and never on the implementing classes.

Here is the complete picture; I am in control of:

I have no or nearly no control over:

This leaves me with little wiggle room to get this working.

Is this even possible in this constellation, and if yes, how would this work?

What I have tried so far:

Further ideas:

Upvotes: 3

Views: 417

Answers (0)

Related Questions