我有一个代码生成器,它为jax-rs端点生成接口,我的后端应用程序实现这些接口,以提供业务逻辑。
现在的问题是,我不能使用名称绑定容器过滤器来增强业务逻辑或添加安全性:任何 @NameBinding
将忽略实现类或其方法上的标记注解,并且不调用相应的筛选器。
下面是一个简单的例子:(代码是用kotlin编写的,但在纯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)
}
}
当一个请求 /foo/bar
是做出来的,我明白 {"filtered":false}
,因此筛选器未运行。当我移动 @TestMarker
注解自 ImplementingApiController::foo
至 OpenApiGeneratedInterface::foo
,我反而得到了 {"filtered":true}
,所以这次确实运行了筛选器。注意,修改接口在现实中是不可能的,因为实际的接口是生成的。我在示例中这样做只是为了说明过滤器通常是工作的。
问题似乎是,系统只在接口上查找标记注解,而从不在实现类上查找。
这是全貌;我控制着:
这个 ImplementingApiController
班
运行应用程序的系统(因此我可以更改配置或添加更多筛选器/拦截器)
我无法或几乎无法控制:
这个 OpenApiGeneratedInterface
接口(由openapi规范生成)
dto类 FooDto
(同时生成)
创建这些接口的代码生成器(它是一个远程项目)
这个 @TestMarker
注解及其相应的过滤器(来自另一个项目)
这就给我留下了一点回旋的余地。
这在这个星座中是可能的吗?如果是的话,这是怎么回事?
到目前为止,我尝试了:
添加 @Path
或者 @Provider
注解到 ImplementingApiController
强制系统使用此类进行注解发现(不起作用)
添加 javax.ws.rs.container.DynamicFeature
并通过反射搜索接口实现来连接过滤器(可以工作,但当接口和实现不是由同一个类装入器管理时,它会变得非常难看)
添加我自己的 ContainerResponseFilter
它始终处于活动状态,并动态调用实际过滤器(也需要与 DynamicFeature
)
进一步想法:
更改代码生成器以省略接口中的jax-rs注解,并自己注解所有内容(可以工作,但几乎完全忽略了这一点)
更改代码生成器以包含我需要的所有类型的标记注解(然后在构建生成的代码时遇到循环依赖性问题)
暂无答案!
目前还没有任何答案,快来回答吧!