知识点17--如何将spring boot项目布置在外部tomcat中
我们前面的知识点使用spring boot开发了一个用户管理的demo,但是启动的时候我们都使用的是spring-boot-web依赖导入的内置tomcat,这在正式的开发中一般是不提倡的,除非开发的系统在使用上要求不高,而且很多时候网络策略只给了少量的端口,因此你办不到模块都用不同的内置web软件并占用不同的端口,所以单凭内置的tomcat是无法保证系统正常的运行的,这时通常的开发手动就是部署到外置的tomcat上。现在我们一起看一下如何部署。
第一步:首先我们需要在maven的pom中直接修改打包方式为war
<packaging>war</packaging>
第二步:既然使用外部tomcat那就必须保证没有任何的内置web插件,我们前面的知识点教大家使用了undertow
内置web插件,同理我们只需要删掉它的依赖,并保持内置tomcat是禁用的
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
第三步:我们需要在项目中准备一个配置类,这个类如果有SSM基础的朋友,应该知道spring容器有一种手动写启动类的方式,作为兄弟的spring-boot当然也有,只是这个类并不是让我们手动运行的,而是默许tomcat这类web链接软件去调用启动spring-boot的一个类
package com.wy.scjg.config;
import com.wy.scjg.ScjgApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
/**
* @创建人 wangyang
* @创建时间 2022/10/1
* @描述
*
* 外部web链接软件 配置类
* 必须重写configure方法并指定该项目的系统类
*/
public class MySpringBootServletIni extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
return builder.sources(ScjgApplication.class);
}
}
第四步:在build
标签中添加一个打包名,这个名字决定了打包后的包名,这个设置主要是因为正式开发中很少一个项目从根目录开始开发,而是项目根目录下又分为各个子模块,所以需要告诉maven打包后的总包名字是什么
<finalName>scjg</finalName>
第五步:在打包之前,如果你的项目中使用了javax.servlet
包下的资源,你会发现项目中报错,是因为上面删除了内置web链接软件因此相关依赖没有了,我们单独导入一下即可
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
第六步:打包,但是打包之前,一定要点击下图这个图标,不让maven进行test不然会报错
打好包后将war包放在tomcat的webapps文件夹下,并运行bin目录下的startup.bat
启动的黑窗口不报错就可以了,但在这个时候要知道一个问题,默认情况下:用外部的web链接软件启动后,springboot项目中配置的端口、项目名就失效了,统一按照所使用的的web软件的访问方式,例如此时的tomcat需要使用 “默认8080端口+项目名+请求路径” 进行访问
,但是对于springboot项目来说这其中就涉及到一个问题,见特别说明
特别说明
你要把一个本来是内置web软件的spring boot项目变成外置部署的方式,且这个项目不是前后端分离的开发形式
,那么一定要检查你所使用的外部软件的配置,需要检查它的访问方式是否已改成不需要项目名的方式
,因为内置web软件时,你的所有请求路径是例如localhost:91:/login
的这种springboot内置访问方式,而你外置之后根据不同的外置web软件你需要注意请求路径发生的改变
就像上面截图中的http://localhost:8080/scjg/user/toLogin
一样,它在内置web时访问的路径应该是http://localhost:91/user/toLogin
,端口号不需要你担心,但是端口号和请求路径中间多了一个项目名,这个就会导致你首次手动输入的路径可以正常访问,但是之后的系统运行都是写好的代码,由于没有项目名导致全是404
,到此给大家附上修改tomcat不要项目名访问的配置方式
打开tomcat的server.xml配置文件
我们需要将配置中的HOST
修改一下,修改前是如下值
<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true">
修改后如下,注意把你的项目名改好
<Host name="localhost" appBase="" unpackWARs="true" autoDeploy="true">
<Context docBase="webapps/你的项目名" path="" reloadable="true" source="org.eclipse.jst.jee.server:你的项目名"/>
这样你才可以正常的访问在外置tomcat上的springboot项目
这个时候或许有人会想到和SSM那样使用试图解析器
解决项目名的问题,但是根据本作者实操发现这个方法行不通,首先面临的第一个问题就是springboot前端页面开发方式中相对成体系的不再和SSM一样只有jsp了,这就导致不同的前端技术所用的配置试图解析方式是不同的,就比如本系列知识点中用的是freemaker,它的视图解析配置是spring.freemarker.prefix和spring.freemarker.suffix
。同时实操的时候使用了这个的配置,可是在tomcat运行后发现请求路径是没有错,但是前端所有的返回都是问号未知错误。
而且springboot是一个倾向于前后端分离模块化开发方式的框架,同时正式开发中后端大多都是API接口而不是单纯的跳转。就算你人为干预开发成只跳转的项目,可是对后端控制解析器路径来说有多少个前端模块和前端模块的路径是什么,这些均是未知数。并且改tomcat的好处还有一点,你可以将多个模块的项目结合成一个总项目打包,并放到tamcat上,不用费劲的区分项目名了。