You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

OSGi环境下如何动态增删Web上下文内的Servlet?

Great question! Let’s tackle this for your OSGi environment, since dynamic Servlet management in embedded containers can be tricky depending on your choice of server.

Undertow: Native Support for Dynamic Servlet Management in OSGi

First off, Undertow was built with flexibility front and center, and it natively supports adding/removing Servlets to an existing context out of the box. It fully implements the Servlet 3.0+ dynamic registration API, and its OSGi-friendly design makes it easy to integrate with bundle-based deployments.

How Undertow Enables Dynamic Servlet CRUD

Undertow uses a DeploymentManager to handle web application deployments, and once a context is deployed, you can directly access its ServletContext to register or unregister Servlets at runtime. No need for hacks or custom extensions—this functionality is baked into its core.

Step-by-Step Implementation Example

Initializing Undertow in OSGi

First, set up your Undertow server and deploy a base context (you’d typically wrap this in an OSGi component or activator):

import io.undertow.servlet.api.DeploymentManager;
import io.undertow.servlet.api.ServletDeploymentInfo;
import io.undertow.servlet.Servlets;
import io.undertow.Undertow;

// Define your base web context
ServletDeploymentInfo deploymentInfo = Servlets.deployment()
        .setContextPath("/my-osgi-app")
        .setDeploymentName("my-osgi-app.war");

// Deploy the context via Undertow's container
DeploymentManager manager = Servlets.defaultContainer().addDeployment(deploymentInfo);
manager.deploy();

// Start the Undertow server
Undertow server = Undertow.builder()
        .addHttpListener(8080, "0.0.0.0")
        .setHandler(manager.start())
        .build();
server.start();

Dynamically Adding a Servlet

Once the server is running, grab the ServletContext from the deployment manager and register your Servlet:

// Get the active ServletContext
ServletContext servletContext = manager.getDeployment().getServletContext();

// Create your Servlet instance (could also come from an OSGi service)
MyDynamicServlet dynamicServlet = new MyDynamicServlet();

// Register and map the Servlet
ServletRegistration.Dynamic registration = servletContext.addServlet("MyDynamicServlet", dynamicServlet);
registration.addMapping("/dynamic/*");
registration.setLoadOnStartup(1); // Optional: load immediately

Dynamically Removing a Servlet

To remove a Servlet at runtime, fetch its registration and unregister it:

ServletRegistration registration = servletContext.getServletRegistration("MyDynamicServlet");
if (registration != null) {
    registration.unregister();
}

OSGi Service Integration (Declarative Services)

To make this truly OSGi-native, use Declarative Services (DS) to automatically register/unregister Servlets when they’re published as OSGi services:

import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
import javax.servlet.Servlet;
import javax.servlet.ServletRegistration;

@Component
public class ServletDynamicRegistrar {

    private DeploymentManager deploymentManager;

    // Inject the pre-configured DeploymentManager via OSGi DS
    @Reference
    public void setDeploymentManager(DeploymentManager manager) {
        this.deploymentManager = manager;
    }

    // Listen for Servlet services being added
    @Reference(
        service = Servlet.class,
        cardinality = ReferenceCardinality.MULTIPLE,
        policy = ReferencePolicy.DYNAMIC
    )
    public void addServlet(Servlet servlet, java.util.Map<String, Object> serviceProps) {
        String servletName = (String) serviceProps.get("servlet.name");
        String urlPattern = (String) serviceProps.get("servlet.url.pattern");
        
        if (servletName == null || urlPattern == null) {
            return; // Skip invalid services
        }

        ServletContext context = deploymentManager.getDeployment().getServletContext();
        ServletRegistration.Dynamic registration = context.addServlet(servletName, servlet);
        registration.addMapping(urlPattern);
    }

    // Listen for Servlet services being removed
    public void removeServlet(Servlet servlet, java.util.Map<String, Object> serviceProps) {
        String servletName = (String) serviceProps.get("servlet.name");
        if (servletName == null) {
            return;
        }

        ServletContext context = deploymentManager.getDeployment().getServletContext();
        ServletRegistration registration = context.getServletRegistration(servletName);
        if (registration != null) {
            registration.unregister();
        }
    }
}
Pax Web: OSGi-Optimized Alternative

If you want a solution that’s purpose-built for OSGi, Pax Web is an excellent choice. It’s an OSGi Http Service implementation that supports Jetty, Tomcat, and Undertow as underlying containers—and it natively handles dynamic Servlet deployment via OSGi services.

Why Pax Web is a Great Fit for OSGi

Pax Web abstracts away the container-specific details. Instead of writing custom code to manage Servlets, you just publish your Servlet as an OSGi service with specific properties, and Pax Web automatically deploys it to the web context. When the service is unregistered, it removes the Servlet automatically.

Simplified Dynamic Deployment with Pax Web

Here’s how easy it is to deploy a dynamic Servlet with Pax Web using DS:

import org.osgi.service.component.annotations.Component;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Component(
    property = {
        "osgi.http.servlet.name=MyPaxServlet",
        "osgi.http.servlet.pattern=/pax-dynamic/*",
        "osgi.http.context.path=/my-osgi-app" // Optional: bind to a specific context
    }
)
public class MyPaxServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        resp.getWriter().write("Hello from Pax Web dynamic Servlet!");
    }
}

That’s it—no manual registration code needed. Pax Web handles all the dynamic lifecycle management for you.

Jetty vs. Undertow/Pax Web Recap
  • Jetty: As you noted, Jetty doesn’t natively support dynamic Servlet CRUD on existing contexts without extra work. You’d need to use MutableServletContextHandler or build custom extensions to enable this, which adds complexity.
  • Undertow: Native support for dynamic Servlet operations via standard Servlet API and its own deployment model, making it a solid choice for embedded OSGi deployments.
  • Pax Web: The most OSGi-native option, leveraging OSGi service lifecycle to handle dynamic Servlet deployment automatically—ideal if you want to align with OSGi best practices.

内容的提问来源于stack exchange,提问作者Martin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:09:33