Maven如何知道将源文件放在哪个exploded目录下?

3

我正在学习Maven,尽管过去曾经使用过Ant。

我正在试图弄清楚当执行命令mvn install或mvn compile时会发生什么。我主要感兴趣的是项目构建的方式,例如挑选用于构建的资源位置以及构建后放置它们的位置。

我的项目源代码结构如下:

src > main > java > java files
src > main > resources > reources like spring config atc
src > main > webapp > static files like js,css etc
src > main > webapp > WEB-INF > web.xml and jsp files

当我执行mvn package或mvn clean命令时,我会看到下面这个名为myProject的目录(这是我的重点),以及其他文件,如war包和classes等。myProject目录的结构如下:

1) All files from (src > main > webapp) including WEB-INF gets copied under myProject
2) All files from (src > main > resources) gets copied under myProject > WEB-INF/Classes
3) All files from (src > main > java) gets copied under myProject > WEB-INF/Classes

根据我的理解,当我们执行mvn install或mvn compile或mvn package时,所有编译阶段都会被执行。但我的问题是,Maven如何知道在exploded目录下放置源文件?这是Maven遵循的标准吗?
以下是我使用的pom.xml代码片段作为参考:
<artifactId>myProject</artifactId>
    <packaging>war</packaging>
    <name>myProject</name>
.....

<build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <executions>
                    <execution>
                        <phase>compile</phase>
                        <goals>
                            <goal>exploded</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <overlays>

                    </overlays>
                </configuration>
            </plugin>
            <plugin>
                <groupId>net.alchim31.maven</groupId>
                <artifactId>yuicompressor-maven-plugin</artifactId>
                <executions>
                    <execution>
                        <phase>compile</phase>
                        <goals>
                            <goal>jslint</goal>
                            <goal>compress</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <aggregations>
                    </aggregations>
                </configuration>
            </plugin>
        </plugins>
    </build>
1个回答

2
当Maven将编译后的文件放置在WEB-INF/classes中时,它遵循Java标准

来自Java EE 6教程的说明

这个目录包含服务器端的类:servlets、工具类和JavaBeans组件。这些类仅对servlet可见,不是公共的。
来自Java Servlet 3.1规范:
10.5 目录结构
应用程序层次结构中存在一个名为“WEB-INF”的特殊目录。该目录包含与应用程序相关的所有内容,这些内容不在应用程序的文档根目录中。WEB-INF节点中的大部分内容都不是应用程序的公共文档树的一部分。除了打包在WEB-INF/lib目录下的JAR文件的META-INF/resources中的静态资源和JSP之外,容器不会直接向客户端提供WEB-INF目录中包含的其他文件。但是,ServletContext使用getResource和getResourceAsStream方法调用可以查看WEB-INF目录的内容,并可以使用RequestDispatcher调用来公开它们。因此,如果应用程序开发人员需要从servlet代码中访问他不希望直接暴露给Web客户端的应用程序特定配置信息,则可以将其放置在此目录下。

第二点:10.5说“然而,WEB-INF目录的内容对于使用ServletContext上的getResource和getResourceAsStream方法调用的servlet代码是可见的”。我的理解是位于WEB-INF/classes下的servlet可以轻松访问WEB-INF/classes或WEB-INF/lib文件夹下的任何类/资源。那么为什么这里说“servlet代码可以使用ServletContext上的getResource和getResourceAsStream方法调用来访问WEB-INF目录的内容”? - M Sach
@MSach 对于第一个问题,是的,你说得对,但是异常不在WEB-INF/lib/META-INF/resources上,而是在位于WEB-INF/lib中的JAR文件的META-INF/resources上。这并不完全相同,你错过了JAR文件。对于第二个问题,规范只是指定了应该如何访问它。即使你的servlet可以访问WEB-INF/classes下的所有内容,你也应该使用这些方法,否则在打包应用程序(例如war或ear)后会遇到问题。 - alain.janinm
例如,如果您尝试使用new File()访问图像或使用InputStream读取文件,则无法正常工作,因为图像/文件不在文件系统中,而是在war或ear中。因此,您必须使用这些方法来访问它们。这个答案很好地解释了getResource()的含义:https://dev59.com/h2Yq5IYBdhLWcg3w7E0F#14089228 - alain.janinm
哦,明白了。这意味着对于任何Java类都是适用的,无论是Servlet还是任何服务类。 - M Sach
是的,基本上适用于所有需要“可移植”的应用程序。即使是 Swing 桌面应用程序,您也必须使用 getResource 从 JAR 中加载图像或其他内容。 - alain.janinm
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接