springboot项目打成war包丢到tomcat webapps下能启动却访问不了相关的接口

  • 背景
    1. springboot 项目,在idea中正常运行(内置tomcat),外部(前端)访问接口正常;
        确认已添加依赖
    <!--打包形式-->
    <packaging>war</packaging>
    ...
    <dependency>
    	<groupId>org.springframework.boot</groupId>
    	<artifactId>spring-boot-starter-tomcat</artifactId>
    	<scope>provided</scope>
    </dependency>
    <!--		该依赖的作用是:在项目打包时,剔除springboot内置tomcat。-->
    <!--		如果没有该步骤,打成的war包内,会有关于内置tomcat的多余的jar包,但是并不影响项目最终的部署与运行。-->
    2. 利用 maven 打包成 war:mvn clean install  --->> xx.war
    3. 机器下载的tomcat 8.5xx 压缩包,解压安装。
        (1) 编辑 tomcat 配置文件设置 访问端口为 项目配置文件中配置的端口号(保持访问端口不变)
        (2) 将打包好的 war 包复制到 tomcat/webapps 目录下
        (3) 启动 tomcat:bin/startup.xx
        (4) 启动成功,访问接口-->> 404
  • 解决方法
    1. 参考 
        项目在intellij idea里配置tomcat可以启动访问, 打成war包丢到tomcat webapps下能启动却访问不了相关的接口
        这个问题是因为idea会默认将项目以ROOT为目录的文件
        而丢到tomcat的webapps下面则是解压成你项目名称为目录的文件,和ROOT是同级的
        可以有以下几种解决方案
        一:将你的war名称改成作为ROOT.war
        二:在tomcat的server.xml文件的Host标签内配置<Context path="/" docBase="你项目的地址" reloadable="true"/>
        三:用tomcat发布时,将前端请求的路径加上你的项目名称
    2. tomcat 版本问题
       换成 tomcat 9.0xx,同样的步骤,访问成功
       tomcat 8.5xx,访问路径设置无效,访问时不能加项目名称,查看tomcat文件,发现项目war包被解压成两份,ROOT下一份
    3. springboot项目内置tomcat问题,以及tomcat版本的支持,重点(可以看后续)
        考虑到springboot web启动器包含内置tomcat,改用外部 tomcat
        (1) 依赖,(虽然已经添加依赖打包是剔除springboot的tomcat)
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        <!-- 移除嵌入式tomcat插件 -->
        <exclusions>
            <exclusion>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-tomcat</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <!-- 添加servlet-api依赖 -->
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>3.1.0</version>
        <scope>provided</scope>
    </dependency>

      (2) 修改启动类,并重写初始化方法:让启动类继承SpringBootServletInitializer,并覆盖configure()方法

    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.boot.builder.SpringApplicationBuilder;
    import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
    
    @SpringBootApplication
    public class Application extends SpringBootServletInitializer {
    	public static void main(String[] args) {
    		SpringApplication.run(Application.class, args);
    	}
    
    	@Override
    	protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        // 注意这里要指向原先用main方法执行的Application启动类
    		return application.sources(Application.class);
    	}
    }

    (3) idea中指定tomcat容器,配置访问端口和路径,启动--成功
    (4) 打包,或者将(3)中启动后生成的war包(target下),复制到tomcat目录下,记得设置tomcat的访问端口号
    (5) 启动tomcat 成功,可访问

  • 原因
        (1) Tomcat 9.0设计用于运行在Java se 8及以后的版本 -- 项目用的是jdk1.8
        (2) 不同 tomcat 版本针对不同版本的 jdk 项目,需要进行特殊的配置(修改配置文件)
        (3) springboot内置tomcat的处理,在低版本的tomcat中未进行适应性处理
  • 总结
    本人对照了很多配置项,除了端口基本都属于默认配置,对网上较多的所谓解决方法的配置修改来看,都没有实际效果,而且启动均是正常,如果是访问路径设置的问题,总有一个访问路径是可以访问到的才对,不管是在tomcat中指定项目路径,还是在访问路径上加上项目名或者不加或者加上两个项目名都访问不到,最终,也是找到原因 tomcat 版本和springboot版本的不适配,最好还是直接换成 tomcat 9.0,完全没得什么问题。
     
  • 对 tomcat 8x 8.5x 和 9.0x 的各种发行可能没有详细了解,希望对遇到同样问题的你有帮助,如有不对或者疑问的地方,请大方指出,相互学习
     
  • 后续
    springboot 指定 外部 tomcat 运行
    Error:Cannot build artifact 'tube (1):war exploded' because it is included i
    1. 将 tomcat 整合进 idea,指定 tomcat 8.5xx 运行,正常运行,接口可访问
    2. 拿到 上面 打包好的 xx.war 复制到 tomcat 8.5xx 的 webapps 目录下,启动,接口可访问!!!且此处设置路径有效

Guess you like

Origin blog.csdn.net/huofuman960209/article/details/105489978