IntelliJ IDEA部署Web应用到Tomcat

  对于习惯Eclipse/MyEclipse的人来说,初次使用IntelliJ IDEA开发Web项目并发布它到Tomcat的时候,那就会觉得非常陌生并且无所适从。或许这也是大多数Eclipse使用者不愿意转型的原因,并且Eclipse是那么的流行,中文学习资料也多,工作方式也非常符合常规思路(比如部署Web应用到Tomcat上),而IntelliJ IDEA在工作方式上比起Eclipse有很多不同之处(有些还是很特别的),学习资料大多是英文的,所以学习曲线相对前者来说是比较陡峭了。

最基本的流程

既然要学习怎么用这个IDE进行部署Web应用,并研究一下其中的一些问题,那就得先把这个过场从头到尾走一遍。

创建项目

基本设置

  • 首先肯定是选择创建的是Java Enterprise下的Web Application项目,这个就是Web工程
    一些设置:
    ①:JavaEE版本
    ②:Web应用服务器
    ③:Web应用版本
    ④:是否创建web.xml
    这些都根据你的需求来设置就行了,这里全部默认。
  • 输入对应的项目名和模块名(这个随便),此处项目名是PracticeDeploy,模块名是first-web-app
  • 创建完成后的目录是这样的

创建演示用的资源

  • 1个自定义ServletFirstServlet,在web.xml内对它进行配置

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    package org.makwan.servlet;    

    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;

    public class FirstServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    resp.setContentType("text/html; charset=utf-8");
    PrintWriter writer = resp.getWriter();
    writer.write("Web应用被部署在: " + getServletContext().getRealPath("/"));
    writer.close();
    }
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    <servlet>
    <servlet-name>FirstServlet</servlet-name>
    <servlet-class>org.makwan.servlet.FirstServlet</servlet-class>
    </servlet>

    <servlet-mapping>
    <servlet-name>FirstServlet</servlet-name>
    <url-pattern>/firstServlet</url-pattern>
    </servlet-mapping>
  • 2个HTMLa.htmlb.html

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>A页面</title>
    </head>
    <body>
    <h1>A page -> 这是A页面</h1>
    </body>
    </html>
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>B页面</title>
    </head>
    <body>
    <h1>B page -> 这是B页面</h1>
    </body>
    </html>


部署以及访问

部署前的设置

如下图所示,从IntelliJ IDEA工具栏的这里,选Edit Configurations...就可以查看Tomcat的设置。

如果还没有Tomcat实例,那可以先点左上角的+按钮创建,并且给它命名。

接着在右边的Server选项卡点Configure...,就会出现以下这个窗口,这里指定Tomcat具体在哪。

然后在Deployment选项卡处添加你将要部署到Tomcat的Web应用。

这个是用于部署Web应用的选项卡界面,其中一些功能点:

  • 旁边那个+按钮就是添加所要部署的Web应用的按钮,反之-按钮就是移除已经部署的Web应用。
  • 右边Application context项是配置该Web应用的访问路径,/就代表着该Web应用。

从这里也可以看出:
默认什么都不做的情况下,其实只要配置好Tomcat,Web应用就已经自动地被添加到部署栏上,即IntelliJ IDEA自动把部署配置都给弄好了。

如果不是从头开始新建项目而是导入项目的话,这些设置是不会帮你做好的,你需要自己进行配置。

并且,这个Deployment选项卡是不是看起来有些熟悉?其实这跟MyEclipse里面部署Web应用的这个界面差不多。

运行Tomcat

现在什么都不用去做,直接点那个绿色的三角形运行Tomcat,并访问a.htmlb.html页面。

如果把Deployment子界面中的访问路径配置成/first-web-app

那么访问a.html的路径将是http://localhost:8080/first-web-app/a.html

问题

构件在哪?

到现在,一切都非常顺利,整体操作运作起来跟使用Eclipse/MyEclipse无异,在说问题之前,先来回顾一下部署Web应用到Tomcat的几种方式

此刻,如果你想看一下所部署到Tomcat的Web应用,那你就会发现问题所在:

  • 在Tomcat的${CATALINA_BASE}/webapps目录内根本找不到我们所部署的这个Web应用
  • $CATALINA_BASE/conf/Catalina/localhost也找不到任何与这个Web应用相关的xml配置文件

问题:Tomcat运行起来,Web应用已经可以被我们访问了,这证明部署成功了,但却在Tomcat里找不到它的踪影,这是最奇怪的。

揭开谜团

  其实想要知道所访问的Web应用被IntelliJ IDEA放到哪方法很简单,之前所写的那个FirstServlet正是为此而准备的,访问它就会显示该Web应用所部署在的真实路径。

从路径上看,IntelliJ IDEA把应部署给Tomcat的Web应用放在了默认编译输出路径<project_folder>/out目录里,只不过多了1级子目录artifacts

  关于这个,MyEclipse与之比较起来就很不同了,MyEclipse对普通Java项目的编译输出就像是一样,只不过MyEclipse默认是把编译好的字节码文件都放到对应工程目录内的bin,但Web项目,MyEclipse把字节码放到bin,但里面的字节码并不是部署的Web应用运行时所用到的字节码。默认情况下,MyEclipse部署Web应用到Tomcat时会把字节码以及Web应用的其他各种资源拷贝到${CATALINA_BASE}/webapps以Web项目名命名的文件夹内。

当然,你可以通过Project Structure配置窗口对项目构件在构建时的输出路径进行配置,将构件的输出目录配置为Tomcatwebapps目录。

其实MyEclipse也有同样的配置窗口,只不过我们一般也很少去动它,都是用默认值。


如何部署?

  通过上面这些细节,我们搞清楚了IntelliJ IDEA把已经部署到Tomcat的Web应用构件放在了<project_folder>/out/artifacts,但这还是有一个问题,现在只是知道构件放哪了,还不知道IntelliJ IDEA是如何让该构件部署到Tomcat上的,更直白地说是不知道IntelliJ IDEA如何让该构件与Tomcat关联起来。

答案隐藏在Tomcat启动时IntelliJ IDEA控制台的信息里。在当我们通过IntelliJ IDEA启动Tomcat时,控制台就会打印出以下这些信息:

G:\apache-tomcat-8.5.16\bin\catalina.bat run
[2017-08-31 01:33:10,610] Artifact first-web-app:war exploded: Waiting for server connection to start artifact deployment...
Using CATALINA_BASE:   "C:\Users\plaYwiThsouL\.IntelliJIdea2017.2\system\tomcat\Tomcat_8_5_16_PracticeDeploy"
Using CATALINA_HOME:   "G:\apache-tomcat-8.5.16"
Using CATALINA_TMPDIR: "G:\apache-tomcat-8.5.16\temp"
Using JRE_HOME:        "E:\Program\Java\jdk1.8.0_121"
Using CLASSPATH:       "G:\apache-tomcat-8.5.16\bin\bootstrap.jar;G:\apache-tomcat-8.5.16\bin\tomcat-juli.jar"

下面的打印消息省略前缀:day-month-year HH:mm:ss.SS 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log

Server version:        Apache Tomcat/8.5.16
Server built:          Jun 21 2017 17:01:09 UTC
Server number:         8.5.16.0
OS Name:               Windows 7
OS Version:            6.1
Architecture:          amd64
Java Home:             E:\Program\Java\jdk1.8.0_121\jre
JVM Version:           1.8.0_121-b13
JVM Vendor:            Oracle Corporation
CATALINA_BASE:         C:\Users\plaYwiThsouL\.IntelliJIdea2017.2\system\tomcat\Tomcat_8_5_16_PracticeDeploy
CATALINA_HOME:         G:\apache-tomcat-8.5.16

其中有几条都出现了同一个目录的路径,这是关键信息。

1
C:\Users\plaYwiThsouL\.IntelliJIdea2017.2\system\tomcat\Tomcat_8_5_16_PracticeDeploy

打开它可以看到以下这些内容:

而这个first-web-app.xml文件的内容:

1
2
<?xml version="1.0" encoding="UTF-8"?>
<Context path="/first-web-app" docBase="G:\IdeaProjects\PracticeDeploy\out\artifacts\first_web_app_war_exploded" />

  从这个现象来看,IntelliJ IDEA所用的部署方式还是沿用那篇文章所讲的第三种方式。但却又有所不同,因为这个目录并不在Tomcat的安装目录内,所以这时那就要看这篇文章进一步补充了。

综上所述,IntelliJ IDEA是结合Tomcat多实例的方式来部署每一个Web应用的。

小结

在Windows下,当我们创建了Web项目时,IntelliJ IDEA在默认情况下都会遵循这两个步骤:

  • 构建

    • 对Web项目进行构建后所形成的构件(artifact)会被放在<project_folder>/out/artifacts
    • Web应用构件是一个被命名为moduleName_war_exploded文件夹,它将要被部署到Tomcat
  • 部署

    • 每当通过IntelliJ IDEA运行Tomcat时,那才会对我们想要部署的Web应用进行部署
    • 部署Web应用之前,IntelliJ IDEA先会在${User home}\.IntelliJIdeaXX\system\tomcat内创建供该Web应用使用的Tomcat工作目录
    • 工作目录名为Tomcat_tomcatVersionCode_projectName,比如在这演示的就是Tomcat_8_5_16_PracticeDeploy
    • 在这个工作目录内的conf\Catalina\localhost,创建一个名为moduleName.xml的文件,用于配置对应的Web应用
    • 在这个xml文件内,都会配置上对应Web应用构件的具体物理路径<project_folder>/out/artifacts/moduleName_war_exploded

这样看下来,IntelliJ IDEA对于构建部署Web应用的步骤也不算特别复杂,就是和我们所习惯的不同而已。

依赖管理

现在开发项目基本都用Maven了,不用Maven那就是落伍甚至给自己找麻烦。

不用Maven的情形

添加额外的jar并使用它,按照开发Java Web最常规的做法就是在WEB-INF新建一个lib目录,然后将所想要的jar复制到那里。

不遵照这个约定也是可以的,直接通过IntelliJ IDEA添加额外的jar或库,但这种约定还是遵照着做才是最好的。

正如那样,这里光复制dom4j-2.0.0.jarWEB-INF/lib内还是不能用的,还必须进行额外的设置,让它成为该模块的依赖:

  • 打开Project StructureModules
  • 选左边的Modules选项
  • 选右边的Dependencies子窗口,点击+按钮选择JARs or directories,添加本模块下WEB-INF/lib

这里所有操作的思路和使用Eclipse/MyEclipse的思路是基本一致的,出来的效果如下图:

但光这样还不够,在构建后,输出目录里根本就没有包含我们所添加的这个依赖目录WEB-INF/lib

所以,必须在Project StructureArtifacts子选项对应的界面进行额外的配置。

从上图我们可以看到IntelliJ IDEA非常人性化地提示我们必须给这个模块的构件添加上lib库,做法很简单:

  • 方式1:看见右下角那个Fix按钮了吗?点一下然后再选第一个,这就可以把lib添加到构件里去了。 Available Elements里面所显示的都是未被添加到构件的内容。在部署并运行Web应用前必须先到这里查看还有什么遗漏的内容未添加到构件中。
    至于要知道在此处进行什么操作来进行内容添加则更好办了,点Available Elements旁边的?就会显示方式了。比如这里显示了一个还未被添加到构件的dom4j-2.0.0.jar,那么只需要在Available Elements进行这3种操作的其中1种:
    - 双击dom4j-2.0.0.jar
    - 按着dom4j-2.0.0不动将其拖过去左边构件目录结构那一栏里的你所期望的目录,当然还是要先创建lib子目录
    - 右键单击根目录dom4j-2.0.0.jar,在弹出菜单选中Put into Output Root

内容添加完成后,构件输出目录就成了这样了。

现在一切都准备好了,可以写代码了,这里同样写一个Servlet。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package org.makwan.servlet;

import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class SecondServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Document document = DocumentHelper.createDocument();
Element rootElt = DocumentHelper.createElement("root");
document.add(rootElt);
rootElt.addElement("a").setText("test data - 测试数据");

resp.setContentType("text/xml; charset=utf-8");

XMLWriter xmlWriter = new XMLWriter(
resp.getWriter(),
OutputFormat.createPrettyPrint()
);
xmlWriter.write(document);
xmlWriter.close();
}
}

web.xml对它进行相关的配置。

1
2
3
4
5
6
7
8
<servlet>
<servlet-name>SecondServlet</servlet-name>
<servlet-class>org.makwan.servlet.SecondServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>SecondServlet</servlet-name>
<url-pattern>/secondServlet</url-pattern>
</servlet-mapping>

启动Tomcat访问该Servlet的运行结果,一切正常运作完全没问题。

使用Maven

  开发简单玩具性质的小项目,纯手工管理jar和构建确实可以,但如果开发大项目则不行了,因为需要依赖的jar太多了,它们的版本以及之间的关系也非常复杂,不用Maven管理是不行了,并且,Maven可以在构建这块也有非常大的作用。

添加Maven支持

现在就把这个first-web-app加上Maven的支持,方法很简单:右键选该模块,选择弹出菜单中的Add Framework Support...

加入Maven支持后,first-web-app模块的目录就会变成这样了。

自定义目录结构

IntelliJ IDEA中给Web项目加入Maven支持后,项目并非完全遵守Maven默认约定的目录结构:除了存放Web应用的目录外,其他默认都是遵守的。

但按照我的个人习惯(估计大多数人?),特别是用于存放项目源码、资源文件、测试源码的目录都不会遵照Maven的约定:

  • 因为默认的约定目录太深了,查看和使用都不太方便
  • 习惯问题

所以我们可以在pom.xml对这些不遵照约定的目录进行配置,不遵守约定那肯定得多花些功夫,幸好这些配置还是挺简单的。

针对该模块,我们只需配置源码目录即可。此处将源码目录配置为src

1
2
3
4
5
<build>
...
<sourceDirectory>${basedir}/src</sourceDirectory>
...
</build>

配置完了还不行,要把那些类以及包含它们的包目录一并移动到src之下,至于Maven所生成的那些默认目录可以删除了,这里还用不上。

用Maven管理依赖

首先我们把WEB-INF/lib删掉,然后在Project Structure内把它以及IDE添加的Servlet与JSP的依赖Tomcat库都移除。

接着肯定是在pom.xml中配置上刚才所移除的那些依赖。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>

<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>javax.servlet.jsp-api</artifactId>
<version>2.3.1</version>
<scope>provided</scope>
</dependency>

<dependency>
<groupId>org.dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>2.0.0</version>
</dependency>
</dependencies>

构件输出这里也必须进行必要的配置。

那现在整个模块的目录就成了这样了。


尝试构建并运行

现在还不能使用Maven对模块进行构建,因为编译时有可能会出问题,因为Maven编译插件的版本过低,因此还是需要进行编译插件的配置。

1
2
3
4
5
6
7
8
9
10
11
<build>
...
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
</plugin>
</plugins>
...
</build>

运行Mavencompile这样就把模块给编译构建好了,然后按照最开始那样部署到Tomcat然后运行它。

你会发现基本上都可以正常访问了,唯独一个使用了第三方jardom4j那个Servlet不能正常访问。

这是因为之前在构件输出目录的配置界面把手工添加的WEB-INF/lib给删除了,而Maven虽然可以很方便地管理依赖,但仍要由你决定是否进行添加。

此时还是要到Project Structure中对构件进一步地配置:把我们在Maven配置的依赖都添加到输出目录中。

可以看到,还有两个Maven依赖还没添加到构件的输出目录中。

添加方法也是跟以前那样,添加之后是这样的。

IDE会自动地将所需的依赖都输出到WEB-INF/lib中,注意,我们并没有创建WEB-INF/lib的实际目录,这里显示的只是构建后构件的目录。

现在就运行Tomcat,再访问这个使用了dom4j的Servlet,现在就可以正常访问了。

Maven配置与IDE设置

  我们可以通过IntelliJ IDEA的一些设置对Web项目进行配置,同样地,我们也可以通过Maven来对Web项目相同的点进行配置,那么它们两者的关系到底是如何的呢?更具体来说,我们有没有必要同时两个都进行配置,因为这里面的工作大多数都是重复的,搞清楚了会让开发更加得心应手。
  为了不与之前的演示混淆而让演示更加复杂化,在此从新创建一个Web模块作为演示,也便于复习一下前面所演示的步骤。

演示起始

创建模块

按照之前所说的步骤一样,首先创建一个Web Application项目,在这我把这个模块命名为second-web-app
现在second-web-app只是一个普通的Web应用模块,还没有添加Maven的支持。

添加Maven支持

second-web-app添加Maven支持:鼠标右击该模块,选中Add Frameworks Support...,在左边的列表选中Maven,然后点OK确定即可。

做到这一步你会发现模块的目录结构没有任何变化,其实现在还没算真正地让Maven管理该模块的,还必须做点微小的工作。

加入Maven后,IntelliJ IDEA右下角会弹出一个提示:
Import Changes即可,如果你不小心把那个提示关掉也无所谓,在pom.xml文件中点右键选Maven中的Reimport

初步结果

添加Maven支持后,该模块的目录结构就成这样了:

并且pom.xml文件的内容是这样的,当然,该模块的grouIdartifactId以及version三巨头你可以根据自己来进行修改:

1
2
3
4
5
6
7
8
9
10
<?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.makwan.deploy</groupId>
<artifactId>second-web-app</artifactId>
<version>1.0</version>
</project>

查看IDE中的设置

  我们先不急着对Mavenpom.xml文件进行配置,首要是查看IntelliJ IDEA对该模块在Project Structure中各种默认设置是如何的。但现在必须知道的一点是:虽然我们添加了Maven支持并且目录结构也产生了变化,但web这个目录其实还是没遵守Maven的约定的,它依然是保持着IntelliJ IDEA默认的约定。更确定地说,Project Structure中的很多设置其实还是遵守未添加Maven支持前IntelliJ IDEA默认的约定。

项目设置

首先来看Project中的设置
这里确实没什么好说的了,最主要就是设置项目名和项目编译输出目录,其余两项设置得不多,根据自己使用的JDK版本来设置就行了。


模块设置

然后到查看Modules中的设置,这里的设置都很关键,必须要集中精神看清楚,在这里有十分多个细节点是需要我们关注的。

  • second-web-app模块的Sources选项卡
    这个选项卡,最重要的就是可以让我们自定义项目的目录结构,并且指定这个某个目录结构到底是什么成分。

  • second-web-app模块的Paths选项卡
    这里没什么特别,主要就是设置本模块的编译输出目录。

  • second-web-app模块的Dependencies选项卡
    为该模块添加或删除依赖的就在这里进行设置。


库设置

接着看到Libraries
现在没有引入任何第三方的jar或库,所以这里是空空如也。


构面设置

再来看到Facets
光看这个选项Facets这个单词的字面意思:方面琢面刻面等,我们根本不知道这一块到底是什么意思。

同时,细心的话你可以发现在Modules中是有一模一样的设置界面的:

当我们对一种技术有疑惑摸不着头脑的时候其实最好就是去官网看看有没有权威的解释,以下就是IntelliJ IDEA官方文档对Facets的解释:

When you select a framework (a facet) in the element selector pane, the settings for the framework are shown in the right-hand part of the dialog.
当你在元素选择窗格中选择一个框架(一个构面)时,框架的各种设置将显示在对话框中右侧部分。
看完了这段解释再看看IDE的所拥有的这个功能:其实我们可以在该对话框内为这个模块添加其他框架(构面)。
正如下图所示,在这两处我们都可以为模块进行这种操作:
Modules中点那个+添加按钮,在弹出的小浮窗中有很多框架技术,它们都是可以让你添加到该模块的框架。

Facets中同样是点那个+添加按钮,也是有同样的效果。

综上所述:Facets就是构面,结合上下文环境具体来讲构面指的是模块构成的技术层面,即模块是由哪些框架、技术来构成的


构件设置

最后,看构件(Artifacts)这块的设置了,这块的设置是比较重要的。

此处有几个要点要讲:

  1. 构件类型
    如果像我们这样中途才加入Maven支持,那么该Web应用对应的只有Web Application: Exploded这一种类型的构件。
    Web Application: Exploded表示这是一个分解的构件,通俗来说就是这个构件不打包,构件所有内容用一个文件夹来装着,这是默认的构件类型。
    当然,我们也可以在这手工地添加上被打包的构件:
    我们在这看到很多构件类型,其中与Web Application: Exploded对应的是Web Application: Archive,即打包的构件,构件当然是一个war包。
  2. 构件名
    默认情况下对于Web Application: Exploded这种构件类型的构件,IntelliJ IDEA设置的构件名都是以_war_exploded结尾的。
    Web Application: Exploded对应的Web Application: Archive这种构件类型的构件默认的构件名是以_war结尾。

配置Maven而引起的变化

  现在我们已经看过了Project Structure中默认情况下的设置是什么样的,要作更多的设置我们可以在此处进行:比如:修改构件名,修改构件输出路径,增加打包类型构件等,但在加入Maven后,这种做法是十分没必要了,甚至多余。
  此处直接开门见山说结论:其实在加入Maven后,对于大多数配置来说,配置Maven这块就等同于在Project Structure中进行配置。

在看接下来的内容之前我们必须明白一点:当我们每次修改pom.xml过后,IntelliJ IDEA在右下角就会有如下图所示这样的提示。
通俗来说就是Maven配置改变了,那IntelliJ IDEA就需要你在这两个选择中作出一个选择让Maven配置实打实地应用到模块中:

  1. Import Changes表示就把本次Maven改变的配置应用到模块中
  2. Enable Auto-Import表示开启自动把Maven改变的配置应用到模块中(不推荐)

只要每次把pom.xml配置好了,你觉得真的可以了,那么就点一下Import Changes确认把当前的Maven配置应用到模块中。

配置packaging

在本模块的坐标描述之下多加一个packaging元素的配置:

1
2
3
4
<groupId>org.makwan.deploy</groupId>
<artifactId>second-web-app</artifactId>
<version>1.0</version>
<packaging>war</packaging>

配置后,你会发现Project Structure中很多处的设置都发生了变化:

  • ModulesSources选项卡的语言级别由8变成5.0

  • ModulesWeb选项内的Web Resource Directories路径后半段由\web变成\src\main\webapp

  • 同样的,Facets中的Web Resource Directories也有同样的变化

  • Artifacts中也有两个变化:

  1. 多增加了一个构件,其类型是Web Application: Archive
  2. 分解的构件的输出路径的后半段也变成了由MavenartifactIdversion两者组成

  现在看来,这些配置才是Maven默认遵守的。更具地提说,到现在,模块second-web-app才是真正地被Maven约束管理起来。
  这一系列的变化确实很多,但packaging配置所真正影响到的只会是Project Structure中的Artifacts这一处的配置,把它的值指定为war,这样等同于在Artifacts中为second-web-app添加一个Web Application: Archive类型的构件。

配置build内的finalName

之前pom.xml内没有build元素,现在给它添加上,这里的配置是告诉MavenIntelliJ IDEA如何构建该模块。

1
2
3
<build>
<finalName>mk_second_web_app</finalName>
</build>

加入这个配置后,Artifacts内的配置又会产生变化:所输出的构件名都变成了所指定的finalName的值。
war包的名称成了:mk_second_web_app.war

分解的构件的构件名则是mk_second_web_app,因为分解的构件就是用文件夹装着,所以输出路径中最后一个目录名就是该构件的名称。

  • build内增加一个编译插件的配置
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    <build>
    <plugins>
    <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.3</version>
    <configuration>
    <source>1.8</source>
    <target>1.8</target>
    <encoding>utf-8</encoding>
    </configuration>
    </plugin>
    </plugins>
    </build>

再观察一下Modules中的配置,可以发现语言级别从之前的5.0又变回了8
我这个Maven默认约定的只是5.0,所以你想支持更新的语言特性,必须自己配置这个编译插件。

build中增加一个打包插件

其实我们之前也发现了在ModulesWeb中或Facets中,Web Resources Directories所配置的路径变红了,证明配置不正确。

报错,那是当然的,现在Web Resources Directories中配置的可是Maven默认约定的格式,但实际上目录结构又是这样:

同样可以发现,web目录这个图标并没有一个蓝色的亮点,而之前是有的:
这正是因为Maven配置不正确或目录结构没有遵守Maven约定的缘故。

这里我就选择不遵守默认约定的目录结构而是配置一个Maven打包插件来解决这个问题:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<build>
<plugins>
<!-- 打包插件 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
<configuration>
<!-- web资源所在的路径 -->
<warSourceDirectory>${basedir}/web</warSourceDirectory>
<!-- web应用构件(分解的构件)输出路径, 默认配置就是以下路径, 所以不配置也可以 -->
<webappDirectory>${project.build.directory}/${project.build.finalName}</webappDirectory>
</configuration>
</plugin>
</plugins>
</build>

最重要的当然就是这一条了,配置它,就可以让MavenIntelliJ IDEA都知道web这个目录是Web资源目录。

1
<warSourceDirectory>${basedir}/web</warSourceDirectory>

现在到ModulesWeb下或Facets内看到Web Resources Directories所配置的路径正确了,没有再报错。

总结

看了这么多演示,最重要的就是以上演示的那些,其他的就不再一一列举了,可以说:
极大多数情况下只需配置pom.xml,那就相当于在Project Structure中进行了配置(必须Import Changes),那就无需再次多此一举在IDE进行配置。