化石原创文章,转载请注明来源并保留原文链接
背景
一个Intellij,mavn工程 (无关是intellij pro或者community版)。
1、使用了local的jar作为lib
2、使用main()方法作为入口方法
3、使用ftl文件作为模板(FreeMarker)
在使用Intellij开发的时候,没有任何问题。现在要发布到外部机器,希望用户能通过web默认端口80访问。
需要的步骤
1、通过Intellij的maven工具,package(默认在intellij IDE的右侧边栏,Lifecycle目录下有package这个工具)命令打包成war文件或者是war同等的文件夹。这个涉及到在pom文件中需要有war的字眼(后面有具体配置),如果没有这个字眼,那么package命令出来的是默认的jar文件,也就是个独立的java程序。
可能会遇到的问题:
因为使用local的jar,而不是maven reposity的,而local jar是通过File|Project Structure… |Library添加,所以package命令不能成功,遇上这个jar找不到问题。
解决方案:
在项目的pom.xml中,加入使用<systemPath>的<dependency>项,告知maven工具local的jar路径
注意:
如果项目非有springboot initializer生成,那么还需要在pom.xml中加入
<!-- 手工设置:让打包成war的设置 -->
<packaging>war</packaging>
和
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
一个完整的的pom.xml如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>wlxsphb</artifactId>
<version>1.0-SNAPSHOT</version>
<!-- 手工设置:让打包成war的设置 -->
<packaging>war</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.1.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongodb-driver</artifactId>
<version>3.11.2</version>
</dependency>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20190722</version>
</dependency>
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>2.10.5</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.google.guava/guava -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>28.1-jre</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.sun.mail/javax.mail -->
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>javax.mail</artifactId>
<version>1.6.2</version>
</dependency>
<dependency>
<groupId>it.sauronsoftware</groupId>
<artifactId>base64</artifactId>
<version>1.3.1</version>
<scope>system</scope>
<systemPath>C:/Users/HanIT/.m2/repository/it/sauronsoftware/base64/javabase64-1.3.1.jar</systemPath>
</dependency>
</dependencies>
<properties>
<java.version>1.8</java.version>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
2、在main()中,有初始化的代码,会在springboot模块前后初始化自己的类
可能会遇到的问题:
发布到外部tomcat,这个main就不会被主动运行。tomcat会由spring boot去寻找SpringBootServletInitializer继承类的configure()方法运行(代替这个main)。所以,所有的初始化没有机会,就导致后续的各种错误,而导致服务无法正常,最常见的就是各种NullException的发生。
解决方案:
1、在Override的configure()中,拷贝对应的初始化方法。视confiure()为入口方法。
有了上面两个大前提,把一个这样的web application放置到外部tomcat的步骤就是:
1、删空tomcat webapps下的ROOT文件夹下所有默认文件(这个方式让web application的根目录替代默认的网站根目录)
2、使用maven的package,打包出target下的war,同时会有同名目录放在war旁
3、拷贝这个同名目录到ROOT下,spring boot工程会出两个文件夹,一个为WEB-INF,另外一个为META-INF。WEB-INF中,含两个目录:classes和lib。classes包含的是Intellij项目中java(src目录)下的java代码产生的class(按原目录组织)文件和resources下所有文件(文件夹);lib下是项目中用到的maven引用的其他jar。META-INF文件夹可能是空的。
注意:
默认的工程可能是不是针对tomcat容器配置的,也就是main方法所在的class没有继承任何其他的class。想配置在tomcat容器中,需要让这个class继承SpringBootServletInitializer,典型的入口class最后成型大致这样:
@SpringBootApplication
public class Program extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(Program.class, args);
}
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
return builder.sources(Program.class);
}
}
查错
发布到外部的tomcat,启动服务后,看不到自己的网站页面,或者看页面时见到错误。查错的方式是看tomcat的日志:在tomcat安装目录下,有logs文件夹,启动服务后会出现很多的log文件,主要是stderr字眼的文件和stdout字眼的文件。严重的错误,比如spring boot前就发生的错误,比如configure()方法就发生了导致springboot不能继续的错误,在stderr中能看到。而后续的各种mapping错误,信息等,都可以在stdout中看到。
常见的System.out.println()发出的信息,在这些文件里都会存在。
修改默认的8080端口
打开tomcat安装目录下的conf文件夹下的server.xml,查找8080字眼,应该能看到未注释的如下字眼:
<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />
改动其中的8080到80,保存。然后重启tomcat即可。
化石原创文章,转载请注明来源并保留原文链接