1. 使用spring boot initializr创建一个restful API项目(springboot官网示例项目https://spring.io/guides/gs/rest-service/)。确保可以直接使用jar包成功运行。运行类代码:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Demo004Application{
public static void main(String[] args) {
SpringApplication.run(Demo004Application.class, args);
}
}
2. 添加extends SpringBootServletInitializer类的新类SpringBootStartApplication,代码如下:
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
public class SpringBootStartApplication extends SpringBootServletInitializer{
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(Demo004Application.class);
}
}
3. 修改build.gradle文件,添加war插件(id 'war')
plugins {
id 'org.springframework.boot' version '2.1.8.RELEASE'
id 'io.spring.dependency-management' version '1.0.8.RELEASE'
id 'java'
id 'war'
}
添加starter-tomcat依赖,要改为providedRuntime
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
4. 使用gradlew build进行编译,在项目build\libs目录下生成war包。
demo004-0.0.1-SNAPSHOT.war
5. 将war包部署到tomcat中。
注意要确保版本兼容。我是使用的springboot2.x+Jdk1.8+Tomcat8.5,如果使用tomcat7.0会出现war包加载失败的异常(比较坑,下面是异常信息),会导致访问对应url时出现404。换成tomcat8.5之后就正常了。
1 九月 09, 2019 1:55:17 下午 org.apache.catalina.startup.HostConfig undeploy
2 信息: Undeploying context [/demo004-0.0.1-SNAPSHOT]
3 九月 09, 2019 1:55:17 下午 org.apache.catalina.startup.HostConfig deployWAR
4 信息: Deploying web application archive /var/lib/tomcat7/webapps/demo004-0.0.1-SNAPSHOT.war
5 九月 09, 2019 1:55:17 下午 org.apache.catalina.core.ContainerBase addChildInternal
6 严重: ContainerBase.addChild: start:
7 org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[/demo004-0.0.1-SNAPSHOT]]
8 at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:154)
9 at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:901)
10 at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:877)
11 at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:632)
12 at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:1073)
13 at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:1857)
14 at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:473)
15 at java.util.concurrent.FutureTask.run(FutureTask.java:262)
16 at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1152)
17 at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:622)
18 at java.lang.Thread.run(Thread.java:748)
19 Caused by: java.lang.UnsupportedClassVersionError: org/springframework/web/SpringServletContainerInitializer : Unsupported major.minor version 52.0 (unable to load class org.springframe work.web.SpringServletContainerInitializer)
20 at org.apache.catalina.loader.WebappClassLoader.findClassInternal(WebappClassLoader.java:2970)
21 at org.apache.catalina.loader.WebappClassLoader.findClass(WebappClassLoader.java:1209)
22 at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1689)
23 at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1570)
24 at java.lang.Class.forName0(Native Method)
25 at java.lang.Class.forName(Class.java:278)
26 at org.apache.catalina.startup.WebappServiceLoader.loadServices(WebappServiceLoader.java:187)
27 at org.apache.catalina.startup.WebappServiceLoader.load(WebappServiceLoader.java:152)
28 at org.apache.catalina.startup.ContextConfig.processServletContainerInitializers(ContextConfig.java:1533)
29 at org.apache.catalina.startup.ContextConfig.webConfig(ContextConfig.java:1255)
30 at org.apache.catalina.startup.ContextConfig.configureStart(ContextConfig.java:863)
31 at org.apache.catalina.startup.ContextConfig.lifecycleEvent(ContextConfig.java:371)
32 at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:117)
33 at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:90)
34 at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5401)
35 at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
36 ... 10 more
37
38 九月 09, 2019 1:55:17 下午 org.apache.catalina.startup.HostConfig deployWAR
39 严重: Error deploying web application archive /var/lib/tomcat7/webapps/demo004-0.0.1-SNAPSHOT.war
40 java.lang.IllegalStateException: ContainerBase.addChild: start: org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost].Stand ardContext[/demo004-0.0.1-SNAPSHOT]]
41 at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:904)
42 at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:877)
43 at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:632)
44 at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:1073)
45 at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:1857)
46 at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:473)
tomcat解压war之后得到的文件目录
tree demo004-0.0.1-SNAPSHOT
demo004-0.0.1-SNAPSHOT
├── META-INF
│ ├── MANIFEST.MF
│ └── war-tracker
├── org
│ └── springframework
│ └── boot
│ └── loader
│ ├── archive
│ │ ├── Archive.class
│ │ ├── Archive$Entry.class
│ │ ├── Archive$EntryFilter.class
│ │ ├── ExplodedArchive$1.class
│ │ ├── ExplodedArchive.class
│ │ ├── ExplodedArchive$FileEntry.class
│ │ ├── ExplodedArchive$FileEntryIterator.class
│ │ ├── ExplodedArchive$FileEntryIterator$EntryComparator.class
│ │ ├── JarFileArchive.class
│ │ ├── JarFileArchive$EntryIterator.class
│ │ └── JarFileArchive$JarFileEntry.class
│ ├── data
│ │ ├── RandomAccessData.class
│ │ ├── RandomAccessDataFile$1.class
│ │ ├── RandomAccessDataFile.class
│ │ ├── RandomAccessDataFile$DataInputStream.class
│ │ └── RandomAccessDataFile$FileAccess.class
│ ├── ExecutableArchiveLauncher.class
│ ├── jar
│ │ ├── AsciiBytes.class
│ │ ├── Bytes.class
│ │ ├── CentralDirectoryEndRecord.class
│ │ ├── CentralDirectoryFileHeader.class
│ │ ├── CentralDirectoryParser.class
│ │ ├── CentralDirectoryVisitor.class
│ │ ├── FileHeader.class
│ │ ├── Handler.class
│ │ ├── JarEntry.class
│ │ ├── JarEntryFilter.class
│ │ ├── JarFile$1.class
│ │ ├── JarFile$2.class
│ │ ├── JarFile.class
│ │ ├── JarFileEntries$1.class
│ │ ├── JarFileEntries.class
│ │ ├── JarFileEntries$EntryIterator.class
│ │ ├── JarFile$JarFileType.class
│ │ ├── JarURLConnection$1.class
│ │ ├── JarURLConnection.class
│ │ ├── JarURLConnection$JarEntryName.class
│ │ ├── StringSequence.class
│ │ └── ZipInflaterInputStream.class
│ ├── JarLauncher.class
│ ├── LaunchedURLClassLoader.class
│ ├── LaunchedURLClassLoader$UseFastConnectionExceptionsEnumeration.class
│ ├── Launcher.class
│ ├── MainMethodRunner.class
│ ├── PropertiesLauncher$1.class
│ ├── PropertiesLauncher$ArchiveEntryFilter.class
│ ├── PropertiesLauncher.class
│ ├── PropertiesLauncher$PrefixMatchingArchiveFilter.class
│ ├── util
│ │ └── SystemPropertyUtils.class
│ └── WarLauncher.class
└── WEB-INF
├── classes
│ ├── application.properties
│ ├── com
│ │ └── example
│ │ └── demo004
│ │ ├── Demo004Application.class
│ │ ├── Greeting.class
│ │ ├── GreetingController.class
│ │ └── SpringBootStartApplication.class
│ ├── static
│ └── templates
├── lib
│ ├── classmate-1.4.0.jar
│ ├── hibernate-validator-6.0.17.Final.jar
│ ├── jackson-annotations-2.9.0.jar
│ ├── jackson-core-2.9.9.jar
│ ├── jackson-databind-2.9.9.3.jar
│ ├── jackson-datatype-jdk8-2.9.9.jar
│ ├── jackson-datatype-jsr310-2.9.9.jar
│ ├── jackson-module-parameter-names-2.9.9.jar
│ ├── jboss-logging-3.3.3.Final.jar
│ ├── jul-to-slf4j-1.7.28.jar
│ ├── log4j-api-2.11.2.jar
│ ├── log4j-to-slf4j-2.11.2.jar
│ ├── logback-classic-1.2.3.jar
│ ├── logback-core-1.2.3.jar
│ ├── slf4j-api-1.7.28.jar
│ ├── snakeyaml-1.23.jar
│ ├── spring-aop-5.1.9.RELEASE.jar
│ ├── spring-beans-5.1.9.RELEASE.jar
│ ├── spring-boot-2.1.8.RELEASE.jar
│ ├── spring-boot-autoconfigure-2.1.8.RELEASE.jar
│ ├── spring-boot-starter-2.1.8.RELEASE.jar
│ ├── spring-boot-starter-json-2.1.8.RELEASE.jar
│ ├── spring-boot-starter-logging-2.1.8.RELEASE.jar
│ ├── spring-boot-starter-web-2.1.8.RELEASE.jar
│ ├── spring-context-5.1.9.RELEASE.jar
│ ├── spring-core-5.1.9.RELEASE.jar
│ ├── spring-expression-5.1.9.RELEASE.jar
│ ├── spring-jcl-5.1.9.RELEASE.jar
│ ├── spring-web-5.1.9.RELEASE.jar
│ ├── spring-webmvc-5.1.9.RELEASE.jar
│ └── validation-api-2.0.1.Final.jar
└── lib-provided
├── javax.annotation-api-1.3.2.jar
├── spring-boot-starter-tomcat-2.1.8.RELEASE.jar
├── tomcat-embed-core-9.0.24.jar
├── tomcat-embed-el-9.0.24.jar
└── tomcat-embed-websocket-9.0.24.jar18 directories, 93 files
6. 在浏览器中查询结果
curl -d 'name=1234' "http://192.168.7.56:8080/demo004-0.0.1-SNAPSHOT/greeting"
{"id":8,"content":"Hello, 1234!"}