OSGI web開發環境下實現bundle間的共享session

在web開發過程中,很痛苦的事情就是很多的模塊,代碼都集中在一個web工程下,我們在osgi環境下,可以把項目分成很多bundle來開發,但是,如果面對web應用,需要面對的就是如何在各個bundle之間共享session。我們的項目是利用pax-web工具進行開發的,據官網聲稱,4.0.0將推出共享session機制。

今天想做一個測試,嘗試解決一下這個問題,看現有的pax-web是否支持。

bundleA做一個serverServlet,只是在session裏面插入一條記錄。

public class ServerServlet extends HttpServlet {
    @Override
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        HttpSession session = request.getSession();
        session.setAttribute("test","test");
    }
}

bundleB做一個ClientServlet,獲得session中的這個記錄。

public class ClientServlet extends HttpServlet {
    private BundleContext bundleContext;
    @Override
    public void init(ServletConfig config) throws ServletException {
        super.init(config);
        bundleContext = (BundleContext) config.getServletContext().getAttribute("osgi-bundlecontext");
        // TODO: Initialize the Reporting Engine
       }
    @Override
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        HttpSession session = request.getSession(true);
       String str=(String) session.getAttribute("test");
        if (str.equals("test"))
            System.out.print("it is ok");

    }
}
試了半天,發現pax-web的一個類:SharedWebContainerContext,感覺這個類應該會起到作用。最後結果如下:

bundleA的activator類:

public final class ExampleActivator
    implements BundleActivator
{
    /**
     * Called whenever the OSGi framework starts our bundle
     */
    private ServiceReference m_webContainerRef;
    public void start( BundleContext bc )
        throws Exception
    {
        this.m_webContainerRef = bc.getServiceReference(WebContainer.class.getName());
        if (this.m_webContainerRef != null) {
            WebContainer webContainer = (WebContainer) bc.getService(this.m_webContainerRef);
            webContainer.getDefaultSharedHttpContext().registerBundle(bc.getBundle()) ;
            HttpContext httpContext = webContainer.getDefaultSharedHttpContext();

            webContainer.registerServlet("/test/server", new ServerServlet(),null, httpContext);
        }
        // Register our example service implementation in the OSGi service registry
       
    }

    /**
     * Called whenever the OSGi framework stops our bundle
     */
    public void stop( BundleContext bc )
        throws Exception
    {
        System.out.println( "STOPPING com.sunlf.tp.testbirt" );

        // no need to unregister our service - the OSGi framework handles it for us
    }
}

bundleB的activator類:

import org.ops4j.pax.web.service.WebContainer;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import org.osgi.service.http.HttpContext;

import java.util.Dictionary;
import java.util.Properties;

/**
 * Extension of the default OSGi bundle activator
 */
public final class ExampleActivator
        implements BundleActivator {
    /**
     * Called whenever the OSGi framework starts our bundle
     */
    private ServiceReference m_webContainerRef;
    public void start(BundleContext bc)
            throws Exception {

        // Register our example service implementation in the OSGi service registry
        this.m_webContainerRef = bc.getServiceReference(WebContainer.class.getName());
        if (this.m_webContainerRef != null) {
            WebContainer webContainer = (WebContainer) bc.getService(this.m_webContainerRef);
            HttpContext httpContext = webContainer.getDefaultSharedHttpContext();
            webContainer.registerServlet("/test/mytest", new ClientServlet(),null, httpContext);
        }

    }

    /**
     * Called whenever the OSGi framework stops our bundle
     */
    public void stop(BundleContext bc)
            throws Exception {
        System.out.println("STOPPING com.liming.bp.demo");

        // no need to unregister our service - the OSGi framework handles it for us
    }
}

裏面的關鍵在於servlet的註冊,需要傳遞同一個httpContext,在瀏覽器中,先訪問clientServlet,然後再訪問serverServlet,發現session是可以正常獲得的。

另外,附上pax-web的maven配置:

<dependency>
            <groupId>org.ops4j.pax.web</groupId>
            <artifactId>pax-web-jetty-bundle</artifactId>
            <version>3.0.0.RC</version>
        </dependency>
        <dependency>
            <groupId>org.ops4j.pax.web</groupId>
            <artifactId>pax-web-jsp</artifactId>
            <!--<classifier>sources</classifier>-->
            <version>3.0.0.RC</version>
        </dependency>
        <dependency>
            <groupId>org.ops4j.pax.web</groupId>
            <artifactId>pax-web-extender-war</artifactId>
            <!--<classifier>sources</classifier>-->
            <version>3.0.0.RC</version>
        </dependency>
        <dependency>
            <groupId>org.ops4j.pax.web</groupId>
            <artifactId>pax-web-extender-whiteboard</artifactId>
            <version>3.0.0.RC</version>
        </dependency>
        <dependency>
            <groupId>org.ops4j.pax.web</groupId>
            <artifactId>pax-web-spi</artifactId>
            <version>3.0.0.RC</version>
        </dependency>



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章