在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>