2

我有一个代码生成器,它为 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班级_
  • 运行应用程序的系统(因此我可以更改配置或添加更多过滤器/拦截器)

我无法或几乎无法控制:

  • 接口(根据OpenApiGeneratedInterfaceOpenAPI 规范生成)
  • DTO 类FooDto(也生成)
  • 创建这些接口的代码生成器(这是一个遥远的项目)
  • 注释及其相应的@TestMarker过滤器(来自另一个项目)

这让我几乎没有回旋余地来完成这项工作。

在这个星座中这甚至可能吗?如果是的话,这将如何运作?

到目前为止我已经尝试过:

  • 添加@Path@Provider注释以ImplementingApiController强制系统使用此类进行注释发现(不起作用)
  • 添加一个javax.ws.rs.container.DynamicFeature并通过反射搜索接口实现来连接过滤器(可以工作,但是当接口和实现不是由同一个类加载器管理时,它会变得非常丑陋)
  • 添加我自己ContainerResponseFilter的始终处于活动状态并动态调用实际过滤器(也需要与 a 相同的反射疯狂DynamicFeature

进一步的想法:

  • 更改代码生成器以省略界面中的 JAX-RS 注释并自己注释所有内容(有效,但几乎完全违背了这一点)
  • 更改代码生成器以包含我需要的各种标记注释(然后在构建生成的代码时遇到循环依赖问题)
4

0 回答 0