展开菜单
首页 精品内容 本月促销 装机必备 Windows PDF教程 macOS软件 IOS软件 Android AI 专题
全部分类

当前位置:

首页 > 编程开发 > 详解Springboot工程中如何快速判断web应用服务器类型

详解Springboot工程中如何快速判断web应用服务器类型

SpringBoot判断Web服务器类型的方法有:调用ServletContext.getServerInfo()最直接可靠;检查特定类是否存在;使用@ConditionalOnClass注解;监听WebServerInitializedEvent事件。检查类存在性为替代方案,条件注解适用于按类型加载Bean。

本文目录

    在 Spring Boot 工程中快速判断 Web 应用服务器类型,可以从运行时环境、Spring Boot 特有 API、底层类加载器、HTTP 响应和外部命令等多个层面入手。下面是几种常见方法的速览表:

    方法原理简述代码复杂度通用性推荐度
    注入 ServletContext直接调用 getServerInfo() 获取服务器信息★☆☆☆☆极高 (适用于所有 Servlet 容器)⭐⭐⭐⭐⭐
    检查特定类是否存在通过 Class.forName() 加载特定服务器的关键类★★☆☆☆高⭐⭐⭐⭐
    利用 Spring Boot 条件注解使用 @ConditionalOnClass 注解声明 Bean★★☆☆☆一般 (适用于 Spring 环境)⭐⭐⭐
    监听容器初始化事件在应用启动时监听 ServletWebServerInitializedEvent 事件★★☆☆☆一般 (适用于 Spring Boot)⭐⭐⭐
    查看启动日志直接观察应用启动时的控制台日志输出☆☆☆☆☆极高⭐⭐⭐⭐⭐
    使用 Actuator 端点访问 /actuator/env 端点查看服务器相关配置★★☆☆☆一般⭐⭐⭐
    检查特定系统属性或 JMX读取 ja va.vm.vendor 或查询 JMX MBean★★★☆☆中⭐⭐
    通过外部命令或端口号推断使用 netstat 或 ps 命令在操作系统层面查询★★★☆☆低 (仅限手动排查)⭐

    方法一:通过 ServletContext 获取服务器信息(推荐)

    这是最直接、也最可靠的方式。你可以在任何 Spring Bean 中注入 ServletContext 对象,然后调用 getServerInfo() 方法。这个方法会返回一个字符串,里面包含了当前 Servlet 容器的名称和版本信息,一目了然。

    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    import ja vax.servlet.ServletContext;
    @Service
    public class ServerInfoService {
        @Autowired
        private ServletContext servletContext;
        public void printServerInfo() {
            String serverInfo = servletContext.getServerInfo();
            System.out.println("服务器信息: " + serverInfo);
            // 对于 Tomcat,输出可能是 "Apache Tomcat/9.0.83" 
            // 对于 Jetty,输出可能是 "Jetty/9.4.53.v20231009"
            // 对于 Undertow,输出可能是 "Undertow - 2.2.24.Final"
        }
    }

    根据 getServerInfo() 返回的内容进行判断时,注意对版本号部分进行清理,避免因版本差异导致匹配失败。

    方法二:检查特定类的存在性

    通过 Class.forName() 方法检测特定服务器的关键类是否存在于当前应用的 Classpath 中,从而判断其类型。这种方式很直接,也是一个稳妥的选择。

    import org.springframework.stereotype.Component;
    import ja vax.annotation.PostConstruct;
    @Component
    public class ServerDetector {
        public enum ServerType {
            TOMCAT, JETTY, UNDERTOW, JBOSS, WEBLOGIC, WEBSPHERE, UNKNOWN
        }
        private static ServerType detectedServer;
        @PostConstruct
        public void detect() {
            detectedServer = determineServerType();
            System.out.println("检测到服务器类型: " + detectedServer);
        }
        public static ServerType determineServerType() {
            if (isClassPresent("org.apache.catalina.startup.Tomcat")) return ServerType.TOMCAT;
            if (isClassPresent("org.eclipse.jetty.server.Server")) return ServerType.JETTY;
            if (isClassPresent("io.undertow.Undertow")) return ServerType.UNDERTOW;
            if (isClassPresent("org.jboss.Main")) return ServerType.JBOSS;
            if (isClassPresent("weblogic.Server")) return ServerType.WEBLOGIC;
            if (isClassPresent("com.ibm.websphere.product.VersionInfo")) return ServerType.WEBSPHERE;
            return ServerType.UNKNOWN;
        }
        private static boolean isClassPresent(String className) {
            try {
                Class.forName(className);
                return true;
            } catch (ClassNotFoundException e) {
                return false;
            }
        }
    }

    方法三:利用 Spring Boot 的条件注解

    这种方式适合用于控制某些特定服务器下 Bean 的加载,是一种声明式的判断方法。说白了,就是让 Spring 自己根据环境来决定要不要加载某个 Bean,省心省力。

    import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    @Configuration
    public class ServerSpecificConfig {
        @Bean
        @ConditionalOnClass(name = "org.apache.catalina.startup.Tomcat")
        public String tomcatOnlyBean() {
            return "仅当应用运行在 Tomcat 服务器上时,此 Bean 才会被创建";
        }
    }

    这个例子其实也能作为快速判断的依据——当你看到 tomcatOnlyBean 在应用上下文中被创建了,那基本就能确定当前运行的是 Tomcat 容器。

    方法四:监听容器初始化事件

    通过实现 ApplicationListener 接口,可以在 Servlet 容器完成初始化后获取 WebServer 实例,从而获取服务器的具体实现类,反推出其类型。这个思路也相当巧妙。

    import org.springframework.boot.web.context.WebServerInitializedEvent;
    import org.springframework.context.ApplicationListener;
    import org.springframework.stereotype.Component;
    @Component
    public class WebServerListener implements ApplicationListener {
        @Override
        public void onApplicationEvent(WebServerInitializedEvent event) {
            // 获取 WebServer 实例,其实现类通常是 TomcatWebServer、JettyWebServer、UndertowWebServer 等
            Class webServerClass = event.getWebServer().getClass();
            System.out.println("WebServer 实现类: " + webServerClass.getName());
            // 可根据实现类名判断服务器类型
            if (webServerClass.getName().contains("Tomcat")) {
                System.out.println("当前运行在 Tomcat 服务器上");
            }
        }
    }

    补充说明

    通用性与准确性:ServletContext.getServerInfo() 是标准 Ja va Servlet 规范的一部分,在所有支持 Servlet 规范的容器中均可使用,且直接提供官方定义的服务器名称,是最可靠的方法。

    为什么可能有“多种判断”:在某些特殊场景下(例如需要与不支持 Servlet API 的老旧代码集成),可能需要采用其他方式。另外,getServerInfo() 返回的字符串版本号格式因服务器而异,有时需要自行解析。

    方法选择建议:对绝大多数 Spring Boot 应用,最推荐 ServletContext.getServerInfo()。若无法获取 ServletContext,可使用“检查类是否存在”的方法作为替代。若要根据服务器类型选择性加载 Bean,应优先使用 Spring 的条件注解。

    方法补充

    该代码片段通过检查 Spring 应用上下文中的 Bean 定义来判断当前使用的是 Tomcat 还是 Jetty 容器。使用 @PostConstruct 注解在初始化时执行检测逻辑,通过扫描 Bean 名称是否包含 EmbeddedTomcat 或 EmbeddedJetty 来设置相应的布尔标志,并输出日志记录检测结果。这种动态识别方式适用于需要针对不同嵌入式容器做差异化处理的场景。

    核心源码

        boolean isTomcat;
        
        boolean isJetty;
        
        @Autowired
        ApplicationContext applicationContext;
        
        @PostConstruct
        private void init()
        {
            isTomcat = Stream.of(applicationContext.getBeanDefinitionNames()).anyMatch(name -> StringUtils.containsIgnoreCase(name, "EmbeddedTomcat"));
            isJetty = Stream.of(applicationContext.getBeanDefinitionNames()).anyMatch(name -> StringUtils.containsIgnoreCase(name, "EmbeddedJetty"));
            log.info("#### isTomcat: {}", isTomcat);
            log.info("#### isJetty: {}", isJetty);
        }
    

    典型应用

    import ja va.io.File;
    import ja va.io.IOException;
    import ja va.util.stream.Stream;
    
    import ja vax.annotation.PostConstruct;
    
    import org.apache.commons.io.FileUtils;
    import org.apache.commons.lang3.RandomUtils;
    import org.apache.commons.lang3.StringUtils;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.ApplicationContext;
    import org.springframework.web.bind.annotation.PostMapping;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestParam;
    import org.springframework.web.bind.annotation.RestController;
    import org.springframework.web.multipart.MultipartFile;
    
    import com.fly.demo.common.JsonResult;
    
    import io.swagger.annotations.Api;
    import io.swagger.annotations.ApiOperation;
    import lombok.extern.slf4j.Slf4j;
    
    @Slf4j
    @Api(tags = "文件上传(simple)")
    @RestController
    @RequestMapping("/simple/file")
    public class SimpleFileController
    {
        boolean isTomcat;
        
        boolean isJetty;
        
        @Autowired
        ApplicationContext applicationContext;
        
        @PostConstruct
        private void init()
        {
            isTomcat = Stream.of(applicationContext.getBeanDefinitionNames()).anyMatch(name -> StringUtils.containsIgnoreCase(name, "EmbeddedTomcat"));
            isJetty = Stream.of(applicationContext.getBeanDefinitionNames()).anyMatch(name -> StringUtils.containsIgnoreCase(name, "EmbeddedJetty"));
            log.info("#### isTomcat: {}", isTomcat);
            log.info("#### isJetty: {}", isJetty);
        }
        
        @ApiOperation("文件上传")
        @PostMapping("/upload")
        public JsonResult upload(@RequestParam MultipartFile file)
            throws IOException
        {
            File rootDir = new File("upload");
            File dest;
            if (isTomcat)
            {
                if (RandomUtils.nextBoolean())
                {
                    log.info("### transferTo");
                    dest = new File(rootDir.getCanonicalPath() + File.separator + file.getOriginalFilename());
                    file.transferTo(dest);
                }
                else
                {
                    log.info("### copyInputStreamToFile");
                    dest = new File(rootDir, file.getOriginalFilename());
                    FileUtils.copyInputStreamToFile(file.getInputStream(), dest);
                }
            }
            else
            {
                log.info("### copyInputStreamToFile");
                dest = new File(rootDir, file.getOriginalFilename());
                FileUtils.copyInputStreamToFile(file.getInputStream(), dest);
            } 
            return JsonResult.success(dest.getName());
        }
    }
    
    
    本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系bd@zhengruan.com
    作者最新文章
    编程开发
    相关文章 更多
    精品专题 更多
    装机必备

    正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

    Windows

    正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

    PDF教程

    正软商城PDF教程频道提供PDF编辑、转换、合并、拆分、压缩及格式处理方法,同时介绍常用PDF软件和工具的使用技巧。

    macOS软件

    正软商城macOS软件专区,精选适用于Mac电脑的办公、设计、影音、效率、开发和系统工具,提供软件功能介绍、macOS兼容版本、正版授权及购买下载服务。

    IOS软件

    正软商城iOS软件专区,精选适用于iPhone和iPad的办公、学习、影音、设计、效率及AI应用,提供功能介绍、适用设备、系统要求和正版获取方式等信息。

    AI

    正软商城AI软件专区,汇集AI写作、AI绘画、AI视频、AI办公、AI编程、AI翻译、智能客服和数据分析等人工智能工具,提供功能介绍、适用平台、收费方式及正版购买信息。

    Mac软件 更多
    AirBuddy 3 macOS版
    AirBuddy 3 macOS版

    AirBuddy 3 是面向 macOS 的蓝牙外设增强工具,可集中查看 AirPods、Beats 与苹果设备电量,提供快速连接、播放控制、电量提醒、桌面小组件和多台 Mac 外设接力等功能。

    AirServer macOS版
    AirServer macOS版

    AirServer macOS版可把 Mac 转换为无线投屏接收端,通过 AirPlay 或 Google Cast 接收手机、平板和电脑画面,并支持多设备同时连接、高清镜像及会话录制,适合家庭娱乐、课堂教学、会议演示和应用展示。

    AnyDesk macOS版
    AnyDesk macOS版

    AnyDesk macOS版是一款适用于远程办公、设备维护和客户支持的远程桌面工具,可连接并操作异地计算机,支持文件传输、无人值守访问、会话权限控制及跨平台协作。

    Beamer 4 macOS版
    Beamer 4 macOS版

    Beamer 4是面向macOS的本地视频投屏工具,可将Mac中的影片投放到Apple TV、Chromecast及兼容设备,支持常见格式、多类字幕、环绕声、播放列表和电视遥控操作。

    Boom 3D macOS版
    Boom 3D macOS版

    Boom 3D macOS版是一款系统级音效增强工具,可为音乐、电影、游戏和流媒体提供3D虚拟环绕声、31段均衡器、音量增强及应用独立音量控制,并支持本地播放器与多种音频输出设备。

    Boris FX macOS版
    Boris FX macOS版

    Boris FX macOS版是一套面向剪辑、合成、调色及动态图形工作的专业后期工具,涵盖视觉特效、平面与三维跟踪、转描、画面修复、粒子动画和音频清理,可配合多种主流宿主软件使用。

    Capto macOS版
    Capto macOS版

    Capto 是面向 macOS 的屏幕截图、高清录屏与媒体编辑工具,支持区域及整屏捕获、网页长截图、双音轨处理、图片和视频标注、素材分类与多渠道分享,适合教师、学生、内容创作者及需要制作演示教程的用户。

    ChemDraw macOS版
    ChemDraw macOS版

    ChemDraw macOS版是一款面向化学学习、科研和制药工作的专业结构绘图工具,可创建分子、反应及生物聚合物图形,并提供结构整理、格式转换和科研成果展示能力。

    Cursor Crane macOS版
    Cursor Crane macOS版

    Cursor Crane 是一款仅面向 macOS 的键盘操控效率工具,可通过提示标签、网格、文字查找和窗口模式完成点击、滚动、定位与切换,并支持屏幕内容提取、脚本及工作流扩展。

    Deep Freeze 冰点还原 macOS版
    Deep Freeze 冰点还原 macOS版

    Deep Freeze 冰点还原 macOS版通过冻结系统配置,让受保护的Mac在重新启动后回到预设状态,并提供解冻空间、维护计划、密码保护及Apple Remote Desktop管理能力。

    Focusky macOS版
    Focusky macOS版

    Focusky macOS版是一款面向教学课件、商务汇报、产品展示和动画宣传内容的演示制作工具。它通过无限画布、路径编排、缩放旋转转场及多媒体编辑,将传统逐页幻灯片转化为更具空间感的动态演示。

    Folder Colorizer 2 macOS版
    Folder Colorizer 2 macOS版

    Folder Colorizer 2 macOS版是一款直观的文件夹外观定制工具,可更换颜色,添加表情、贴纸及图片背景,并支持批量处理、智能推荐和恢复默认样式,帮助用户更快辨认工作、学习与生活资料。

    WINDOWS 更多
    讯飞绘文 网页版
    讯飞绘文 网页版

    讯飞绘文网页版是科大讯飞推出的AI图文创作与内容运营工具,覆盖热点选题、文章生成、稿件校对、智能配图、排版发布和数据复盘等环节,适合自媒体创作者及内容团队在线使用。

    AirServer Windows版
    AirServer Windows版

    AirServer Windows版可把电脑变成AirPlay、Google Cast和Miracast无线投屏接收端,适合会议演示、课堂教学及家庭大屏分享。发送设备通常无需另装客户端,并可同时接收和智能排列多个镜像会话。

    AlwaysUp Windows版
    AlwaysUp Windows版

    AlwaysUp是一款面向Windows的系统服务注册与程序托管工具,可让普通应用、脚本及批处理在无人登录时随系统启动,并通过状态检测、异常重启、资源监控和邮件通知保障关键任务持续运行。

    AnyDesk Windows版
    AnyDesk Windows版

    AnyDesk Windows版是一款轻量化远程桌面与技术支持工具,可用于控制异地电脑、传输文件、远程打印及无人值守访问。它兼顾连接响应、安全权限和部署灵活性,适合个人远程办公、企业设备维护与客服支持。

    Boom 3D Windows版
    Boom 3D Windows版

    Boom 3D Windows版是一款面向音乐、电影和游戏场景的系统级音效增强工具,支持虚拟3D环绕声、31段均衡器、预设音效、应用音量控制及本地音乐播放,可配合耳机、扬声器和蓝牙耳机使用。

    Boris FX Windows版
    Boris FX Windows版

    Boris FX Windows版是一套服务于影视剪辑、视觉特效、运动跟踪、转描、图像修饰及音频修复的专业创作工具集合,可作为插件接入多种主流后期宿主,也包含可独立运行的应用,适合剪辑师、特效师与内容创作者使用。

    ChemDraw Windows版
    ChemDraw Windows版

    ChemDraw Windows版是一款面向化学研究、药物研发、材料科学和教学工作的专业结构绘图工具,可快速绘制分子、反应式及生物聚合物,并提供结构整理、格式转换、性质计算和科研文档协作能力。

    CODESOFT Windows版
    CODESOFT Windows版

    CODESOFT Windows版是一套企业级条码与RFID标签设计打印工具,可连接Excel、Access、SQL及云端数据源,支持变量、表单、GS1条码、数据库记录和多种工业打印机,适合制造、仓储、物流及合规标识场景。

    Deep Freeze 冰点还原 Windows版
    Deep Freeze 冰点还原 Windows版

    Deep Freeze 冰点还原 Windows版通过重启恢复技术保护系统盘及指定分区,自动撤销恶意程序、误操作和配置漂移造成的改动,并支持密码保护、解冻空间与多硬盘管理,适合学校机房、公共电脑、办公终端及家庭电脑使用。

    EDIUS Windows版
    EDIUS Windows版

    EDIUS 11 Windows版是一款面向影视制作、广播电视、纪录片、短视频及教育机构的专业非线性编辑工具,支持4K/8K、多格式混编、HDR调色、字幕、音频处理和后台渲染,并提供素材管理及丰富的导出预设。

    FastStone Capture Windows版
    FastStone Capture Windows版

    FastStone Capture Windows版是一款轻量级屏幕捕捉、录屏与图像编辑工具,可截取窗口、区域、菜单和滚动页面,并提供标注、模糊、取色、OCR、录音录像及多格式导出能力,适合办公说明、教程制作和问题反馈。

    Focusky Windows版
    Focusky Windows版

    Focusky Windows版是一款动画演示与交互课件制作工具,通过无限画布、缩放旋转镜头、模板素材和对象动画组织内容,可导入PPTX,并输出视频、EXE、PDF、网页等格式,适用于课堂教学、微课、商务汇报及产品展示。