我已经将CXF包部署在一个OSGi容器上,每个包中都有几个端点。端点是JAX-RS和JAX-WS风格的混合。我想用JOSSO在端点上启用一些安全性,并且需要注册一个servlet筛选器来实现。显然,由于没有声明筛选器的web.xml,我需要在OSGi服务注册表中注册它们。
我曾尝试使用pax-web http白板来注册过滤器,但从未调用过doFilter方法。我注意到分布式OSGI cxf实现提供了在过滤器上将org.apache.cxf.httpservice.filter属性设置为true,并为servletNames指定一个虚拟字符串,以避免混淆pax-web白板。对于标准的CXF (非分布式) servlet包,我可以做些类似的事情来注册OSGi过滤器吗?
发布于 2012-01-17 00:07:22
经过大量的研究,我能够使用Felix + PAX Web为CXF Servlet设置一个过滤器。诀窍是从CXF包中注册过滤器(每个包都有一个不同的http上下文)。
在我的代码中,我获取了捆绑包上下文,称为getBundles(),找到了cxf捆绑包,并获得了CXF捆绑包的捆绑包上下文。然后,我在CXF包的上下文中注册了过滤器。我现在感觉很脏,但它是有效的。
我记得我看到过一个建议,创建一个碎片包来配置PAX的Jetty服务器,这可能也可以用来注册一个过滤器--但是我现在不想在我们的项目中创建另一个工件。
发布于 2022-01-27 13:39:18
我发现自己处于这样的境地:为Apache CXF编写一个全局过滤器,但是不知道该怎么做。
一些调查显示,Apache CXF正在使用来自OSGi的HttpService,并直接注册servlet。有关更多详细信息,请参阅https://github.com/apache/cxf/blob/90df32db98d8fc76f091723561f42c6d16021db4/rt/transports/http/src/main/java/org/apache/cxf/transport/http/osgi/ServletExporter.java#L126。
您可以看到,使用了绑定到捆绑包的默认http上下文。请参阅https://github.com/ops4j/org.ops4j.pax.web/blob/d2172a91ad2579714d40b509d6c420e5c28fa2d0/pax-web-runtime/src/main/java/org/ops4j/pax/web/service/internal/HttpServiceStarted.java#L337
因此,您不能简单地公开一个过滤器并让它为CXF Servlet工作。
但是,正如froh42所说,可以获取包,导出CXF Servlet,并使用其包上下文注册过滤器。如果您不确定要查找哪个包,请在Karaf shell中使用以下命令:service:list javax.servlet.ServletContext,它将显示包的符号名称以显示上下文:
[javax.servlet.ServletContext]
------------------------------
osgi.web.contextname = default
osgi.web.contextpath = /
osgi.web.symbolicname = org.apache.cxf.cxf-rt-transports-http
osgi.web.version = 3.5.0
service.bundleid = 97
service.id = 218
service.scope = singleton
Provided by :
Apache CXF Runtime HTTP Transport (97)
Used by:
OPS4J Pax Web - Runtime (182)长话短说,这就是你如何编写这样的注册逻辑。请注意,您需要从pax-web-api模块使用WebContainer,因为它允许您注册过滤器。HttpService不具备该功能。
package org.example.cxf.filter;
import org.ops4j.pax.web.service.WebContainer;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.ServiceReference;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Deactivate;
import org.osgi.service.http.HttpContext;
import java.util.Collection;
import java.util.Dictionary;
import java.util.Hashtable;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@Component
public class CxfFilterRegistrator {
@Activate
public void onActivate(BundleContext bundleContext) throws InvalidSyntaxException {
final WebContainer cxfWebContainer = findCxfWebContainerOrFail(bundleContext);
final HttpContext otherContext = cxfWebContainer.createDefaultHttpContext();
final Dictionary<String, String> initProperties = new Hashtable<>();
initProperties.put("key", "value");
cxfWebContainer.registerFilter(MyFilter.class, new String[]{"/*"}, null, initProperties, otherContext);
}
@Deactivate
public void onDeactivate(BundleContext bundleContext) throws InvalidSyntaxException {
final WebContainer cxfWebContainer = findCxfWebContainerOrFail(bundleContext);
cxfWebContainer.unregisterFilter(MyFilter.class);
}
private WebContainer findCxfWebContainerOrFail(final BundleContext bundleContext) throws InvalidSyntaxException {
final List<Bundle> cxf = Stream.of(bundleContext.getBundles())
.filter(bundle -> bundle.getSymbolicName().equals("org.apache.cxf.cxf-rt-transports-http"))
.collect(Collectors.toList());
if (cxf.isEmpty()) {
throw new IllegalStateException("CXF not found, Bailing");
}
final BundleContext cxfBundleContext = cxf.get(0).getBundleContext();
final Collection<ServiceReference<WebContainer>> serviceReferences = cxfBundleContext.getServiceReferences(WebContainer.class, null);
final WebContainer otherWebContainer = cxfBundleContext.getService(serviceReferences.iterator().next());
return otherWebContainer;
}
}https://stackoverflow.com/questions/7448792
复制相似问题