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

Spring Boot中getServletNames()返回空,如何获取实际Servlet列表?

获取Spring Boot中实际的Servlet列表

在Spring Boot 2.7.7中,直接注入的ServletContext是Spring封装后的实例,其getServletNames()方法会返回空枚举。可以通过以下几种方式获取真实的Servlet列表:

方法一:通过WebApplicationContext获取ServletRegistrationBean

Spring Boot中注册的Servlet(包括自定义和内置的DispatcherServlet)都会以ServletRegistrationBean的形式存在于容器中,直接获取这类Bean即可得到Servlet信息:

@RestController
public class HomeController {
    @Autowired
    private WebApplicationContext webApplicationContext;

    @GetMapping
    int home() {
        // 获取所有ServletRegistrationBean实例
        Map<String, ServletRegistrationBean> servletRegBeans = webApplicationContext.getBeansOfType(ServletRegistrationBean.class);
        
        servletRegBeans.values().forEach(bean -> {
            System.out.println("Servlet名称:" + bean.getServletName());
            System.out.println("映射路径:" + bean.getUrlMappings());
            System.out.println("Servlet类:" + bean.getServlet().getClass().getName());
        });
        return 200;
    }
}

方法二:通过当前请求获取原生ServletContext

当前请求对应的ServletContext是嵌入式容器(如Tomcat)提供的真实实例,能直接获取到所有注册的Servlet:

@RestController
public class HomeController {
    @GetMapping
    int home() {
        // 获取当前请求的ServletContext
        ServletContext realServletContext = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes())
                .getRequest()
                .getServletContext();
        
        Enumeration<String> servletNames = realServletContext.getServletNames();
        while (servletNames.hasMoreElements()) {
            String servletName = servletNames.nextElement();
            System.out.println("Servlet名称:" + servletName);
            // 获取对应的Servlet对象
            Servlet servlet = realServletContext.getServlet(servletName);
            System.out.println("Servlet类:" + servlet.getClass().getName());
        }
        return 200;
    }
}

方法三:依赖具体嵌入式容器API(以Tomcat为例)

如果你的应用固定使用Tomcat作为嵌入式容器,可以直接通过Tomcat的API获取Servlet信息,这种方式能拿到容器层面的所有Servlet:

@RestController
public class HomeController {
    @Autowired
    private TomcatServletWebServerFactory tomcatServerFactory;

    @GetMapping
    int home() {
        Server tomcatServer = tomcatServerFactory.getTomcat().getServer();
        // 遍历Tomcat的服务、连接器、主机、上下文,获取所有Servlet
        for (Service service : tomcatServer.findServices()) {
            for (Connector connector : service.findConnectors()) {
                Engine engine = (Engine) connector.getContainer();
                for (Host host : engine.findChildren()) {
                    for (Context context : host.findChildren()) {
                        Map<String, ? extends Servlet> servlets = context.getServlets();
                        servlets.forEach((name, servlet) -> {
                            System.out.println("Servlet名称:" + name);
                            System.out.println("Servlet类:" + servlet.getClass().getName());
                        });
                    }
                }
            }
        }
        return 200;
    }
}

注意事项

  • 方法一通用性最强,不依赖具体容器,推荐优先使用;
  • 方法二需要在请求上下文环境中执行,无法在启动时直接调用;
  • 方法三仅适用于Tomcat容器,更换容器时需要修改代码。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 19:15:52