设为首页 收藏本站
查看: 1189|回复: 0

[经验分享] osgi内嵌jetty容器添加过滤器

[复制链接]

尚未签到

发表于 2017-3-1 12:21:31 | 显示全部楼层 |阅读模式
一、 osgi内嵌jetty
     1、在MANIFEST.MF中添加"Service-Component : service.xml"
     2、通过注册HttpService的方式来注入eclipse自己的实现,然后通过httpService对象来添加servlet拦截请求。核心xml配置如下:

<?xml version="1.0" encoding="UTF-8"?>
<scr:component xmlns:scr= "http://www.osgi.org/xmlns/scr/v1.1.0" name="org.guanmu.jetty"
    activate="startup" deactivate= "shutdown">
   <implementation class="org.guanmu.jetty.JettyService" />
   <reference bind="setHttpService" name= "httpService"
       interface="org.osgi.service.http.HttpService" policy="static"/>
</scr:component>
     
     3、通过httpService对象的registerServlet方法添加servlet。

二、问题描述
     httpService接口只提供了registerServlet、registerResources和unregister方法。没有添加过滤器的方法,所以当需要过滤需求(过滤非本地请求)时,则没法实现。

三、解决方案
     打断点可以发现,在jetty调用servlet的service方法之前,是由一个ProxyServlet类中完成的,调用时先判断是否有过滤器,没有过滤器时才走到service中。进一步发现ProxyServlet的过滤器list是在org.eclipse.equinox.http.servlet.internal.HttpServiceImpl中有添加过滤器的方法。打断点发现注入的httpService对象的实际就是该类实现的,所以将httpService对象强转为httpServiceImpl对象就可以添加过滤器了。由于是osgi插件开发,导入插件依赖后,发现还是无法导入该类,在build path中去掉插件访问权限的限制,就可以引入了。虽然检查没有错误,但是运行osgi时还是报错。

     1、由于能看到源码,所以尝试使用反射试试,没想到在有HttpServiceImpl 实例的情况下使用反射功能非常简单。实现如下:

            Class<?> implClass = httpService.getClass();
            Method method = implClass.getMethod("registerFilter", new Class[]{String.class,Filter.class,Dictionary.class,HttpContext.class});
            if (method == null) {
                logger.error("the httpService is not HttpServiceImpl.[" + httpService.getClass().getName() + "]");
                return;
            }
            method.invoke(httpService, new Object[]{"/", responseFilter, null, null});
     讲解:先获取到Classs对象(org.eclipse.equinox.http.servlet.internal.HttpServiceImpl类的),然后找到registerFilter方法,然后调用注册过滤器方法。该方案可以在不知道具体实现类的情况下直接调用某方法,如果没有该方法异常处理。

     2、通过看源码发现org.eclipse.equinox.http.servlet包有两个公开接口除了HttpService还有一个ExtendedHttpService,ExtendedHttpService继承HttpService接口,内部访问类HttpServiceImpl就是实现了ExtendedHttpService接口,且registerFilter方法就是在ExtendedHttpService接口中定义,所以直接将httpService对象转化为ExtendedHttpService类型的实例就可以调用registerFilter方法,比反射看起来更舒服。实现如下:

            if (!(httpService instanceof ExtendedHttpService)) {
                logger.error("the httpService is not ExtendedHttpService.[" + httpService.getClass().getName() + "]");
                return;               
            }
            ExtendedHttpService extendHttpService = (ExtendedHttpService) httpService;
            extendHttpService.registerFilter("/", responseFilter, null, null);
     
     3、通过service.xml配置发现,注入时指定了类型是HttpService,假如直接指定为ExtendedHttpService类型呢?实验结果是ok的,这样就可以直接使用ExtendedHttpService类型的对象。但这个方法通过配置将类型写死了,如果是另外一种实现可能会出问题,还是没有第二种好,兼容其他情况。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-348822-1-1.html 上篇帖子: Jetty应用服务器的安装详解 下篇帖子: Maven Jetty插件配置
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表