花了半天时间终于成功,记录以备查阅。css
部署部分参考的是:把spring-boot项目部署到tomcat容器中前端
目标:把spring-boot项目按照日常的web项目同样发布到tomcat容器下java
在pom.xml里设置 <packaging>war</packaging>web
<groupId>com.study</groupId>
<artifactId>test</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
在pom.xml里找到spring-boot-starter-web
依赖节点,在其中添加以下代码:spring
<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>
下面两种方式均可以,任选其一apache
<dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> <scope>provided</scope> </dependency>
<dependency> <groupId>org.apache.tomcat</groupId> <artifactId>tomcat-servlet-api</artifactId> <version>8.0.36</version> <scope>provided</scope> </dependency>
咱们日常用main方法启动的方式,都有一个App的启动类,代码以下:bootstrap
@SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
直接让启动类继承SpringBootServletInitializer,并覆盖configure()方法:后端
@SpringBootApplication public class Application extends SpringBootServletInitializer { @Override protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) { // 注意这里要指向原先用main方法执行的Application启动类 return builder.sources(Application.class); } public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
在项目根目录下(即包含pom.xml的目录),在命令行里输入: mvn clean package便可, 等待打包完成,出现[INFO] BUILD SUCCESS即为打包成功。 mvn clean package 命令能够按须要添加参数, -DskipTests 不执行测试用例,但编译测试用例类生成相应的class文件至target/test-classes下。 -Dspring.profiles.active=dev 若是配置了多环境,能够设置打包到哪一个环境。 而后把target目录下的war包放到tomcat的webapps目录下,启动tomcat,便可自动解压部署。 最后在浏览器中输入 http://localhost:[端口号]/[打包项目名]/ 发布成功
IDEA上方工具栏:Run->Edit Configurationsapi
打开配置界面,左边"+"号->Tomcat Server->Local浏览器
完成后以下所示
而后在Deployment中点击"+"号,选择client:war,这样每次server启动的时候都会去打包一次war包(我的理解),而后去运行war包。
而后保存就能够了,而后启动项目就运行起来了。
log4j.appender.dailyFile.File=${catalina.base}/logs/guandata/log.log4j
在启动第三方Tomcat时,Tomcat会去环境变量中寻找叫CATALINA_HOME、CATALINA_BASE的环境变量,并将它们加入到Tomcat到系统变量中,这样咱们就能在项目中使用它们了。
举例:
本来在springboot内置Tomcat中运行项目,资源访问路径URL相似于:http://localhost:8080/css/bootstrap.min.css 可是打包部署到第三方Tomcat中,Tomcat默认会在路径中加上项目名,相似于:http://localhost:8080/myproject/css/bootstrap.min.css 这样就致使了访问不到静态资源 404
缘由:
因为在前端引用资源时使用了绝对路径:
<link href="/css/bootstrap.min.css" rel="stylesheet">
这样默认在 http://localhost:8080/css/bootstrap.min.css 下面寻找,所以,咱们须要在前面加上项目名,可是写死的话万一改项目名就很麻烦,固然是有办法解决的。
解决:
1. 在Java后端定义一个拦截器,用来获取 request.getContextPath() 而后传到前端,request.getContextPath() 获得的是项目的根路径,具体参考:关于request.getServletPath(),request.getContextPath()的总结
1 @Component 2 public class CommonIntercepter implements HandlerInterceptor { 3 4 private final Logger logger = LoggerFactory.getLogger(this.getClass()); 5 6 @Override 7 public boolean preHandle(HttpServletRequest request, 8 HttpServletResponse response, Object handler) throws Exception { 9 return true; 10 } 11 12 @Override 13 public void postHandle(HttpServletRequest request, 14 HttpServletResponse response, Object handler, 15 ModelAndView modelAndView) throws Exception { 16 request.setAttribute("ctx", request.getContextPath()); 17 request.setAttribute("version", DateTimeUtils.currentTimeMillis()); 18 } 19 20 @Override 21 public void afterCompletion(HttpServletRequest request, 22 HttpServletResponse response, Object handler, Exception ex) 23 throws Exception { 24 25 } 26 27 28 }
2. 前端在静态资源访问url前加上${ctx!},注意我用的是freemarker模版
<link href="${ctx!}/css/bootstrap.min.css" rel="stylesheet"> <link href="${ctx!}/css/font-awesome.min.css" rel="stylesheet"> <link href="${ctx!}/css/plugins/bootstrap-table/bootstrap-table.min.css" rel="stylesheet"> <link href="${ctx!}/css/animate.css" rel="stylesheet"> <link href="${ctx!}/css/style.css" rel="stylesheet">
这样就能正确访问到静态资源啦。
sudo chmod 777 /Library/Tomcat/apache-tomcat-9.0.10/bin/*.sh