几个月以来,我一直在研究Apache CXF,Karaf和Felix,我发现所有这些捆绑技术都非常有趣。 在处理一些用例时,我陷入一种情况,即我只需要一个Interceptor即可在发送到Karaf应用程序下部署的任何捆绑包的每个HTTP请求上执行。
基本上,我想对每个请求进行授权,更改一些标头,并对已发送给系统的任何请求进行一些安全检查,最重要的是,我想在一个类中进行处理。 我发现了在每个捆绑中添加拦截器的许多方法,但我想在某个集中的位置/捆绑中执行此操作,以便可以从该捆绑中处理所有请求。 执行某些授权后,它可以简单地拒绝任何请求,也可以将其传递给相关的包(cxf在内部执行)。
在这样做的时候,我知道CXF总是为每个在捆绑软件蓝图中初始化的RestServer创建一个单独的BUS。 但是要实现我的目标,我们必须在同一总线上注册所有捆绑包,并将拦截器应用于该总线。 这样,我们可以控制总线上所有的请求。
通用拦截器
public class CommonInterceptor extends AbstractPhaseInterceptor {public CommonInterceptor() {super(Phase.PRE_PROTOCOL);}public void handleMessage(Message message) throws Fault {/*** Here write whatever logic you want to implement on each HTTP call sent to your project.* * This interceptor will be called on every request that is being recieved by container and then will be sent* to the relevant bundle/class for handling.*/String url = ( String ) message.get( URL_KEY_ );String method = ( String ) message.get( Message.HTTP_REQUEST_METHOD );LOGGER.debug( "################### Authentication Interceptor Validating Request : " + url + "####################" );Map< String, List< String >> headers = Headers.getSetProtocolHeaders( message );if ( headers.containsKey( X_AUTH_TOKEN ) ) {return;}else{message.getInterceptorChain().abort();}}
}
上面是常见的拦截器代码,您可以在其中使用正在发送到服务器的请求来执行任何操作。 在构造函数中,我正在分配将拦截器连接到的阶段。 CXF有多个阶段。 您可以获取有关“阶段”链接的信息: CXF中的“阶段”。
扩展AbstractFeature:
public class InterceptorManager extends AbstractFeature {private static final String COMMON_BUS_NAME = "javapitshop_bus";private static final Logger LOGGER = LoggerFactory.getLogger(InterceptorManager.class);private static final Interceptor< Message > COMMON_INTERCEPTOR = new CommonInterceptor();protected void initializeProvider(InterceptorProvider provider, Bus bus) {if ( COMMON_BUS_NAME.equals( bus.getId() ) ) {LOGGER.debug( " ############## Registering Common Interceptor on BUS ##############" );bus.getInInterceptors().add( COMMON_INTERCEPTOR );} else {LOGGER.error( " ############## Bus Id: '" + bus.getId() + "' doesn't matched with system bus id ##############" );} }
}
在上面的代码中,我正在扩展AbstractFeature类,并连接initilizeProvider方法。 然后我给我们的普通巴士起了个名字。 基本上,只要安装了任何OSGi捆绑软件,它都会在总线上进行注册。 在这种情况下,我们要检查捆绑包是否具有所需的总线ID。 该总线ID在整个系统范围内都是唯一的,具有该总线ID的所有捆绑包都将注册到同一总线,并且与这些捆绑包相关的每个请求都将首先发送到CommonInterceptor。
捆绑包中的公交车注册:
<cxf:bus id="javapitshop_bus"><cxf:features><cxf:logging /></cxf:features></cxf:bus>
要在同一总线上注册捆绑包,您必须给该总线赋予一个ID并将其注册在捆绑包的blueprint.xml文件中。 在所有相关的捆绑软件中执行此操作,所有这些捆绑软件都将分配有相同的总线,并且CommonInterceptor将自动实现到所有捆绑软件。
- 您可以从我的Github下载完整的源代码。
翻译自: https://www.javacodegeeks.com/2014/11/a-common-cxf-request-interceptor-for-all-osgi-bundles.html