如何在基于Maven的Java WAR项目中设置Angular 4?

29
我因为找不到一个指南来设置在 Java war 项目中与 Maven 一起构建并在 Wildfly 服务器上运行的 Angular 4 应用程序而有些疯狂。

有什么帮助吗?

谢谢


2
建议:研究一下JHipster。 - OneCricketeer
@Giamma:https://dev59.com/questions/uFkT5IYBdhLWcg3weffR - Parth Ghiya
这是针对Angular 2而不是Angular 4的。 - Giamma
我使用了frontend-maven-plugin[https://github.com/eirslett/frontend-maven-plugin]。借助这个插件,我能够使用单个命令`mvn clean package`构建Angular项目并将其放置在war中。 - TimeTraveler
@TimeTraveler 有任何例子吗?谢谢。 - Giamma
显示剩余2条评论
3个回答

44

我有类似的要求,需要一个源代码项目,其中包含Java Web服务项目和基于Angular CLI的Angular项目,并且使用Maven构建应该创建一个包含所有Angular文件的WAR文件。我使用maven-frontend-plugin并进行了一些配置更改以设置基本路径。

目标是创建一个带有所有Java代码和AOT编译的Angular代码的WAR文件,在WAR的根文件夹中,只用单个命令mvn clean package即可完成所有这些工作。

还有一件事,为了使这一切正常工作,需要避免Angular应用程序路由器URL和Java应用程序URL之间的冲突,您需要使用HashLocationStrategy。一种方法是在app.module.ts中进行如下设置:

app.module.ts -

providers: [
    { provide: LocationStrategy, useClass: HashLocationStrategy },

]

Angular App的文件夹结构如下所示:

angular-project

  • dist
  • e2e
  • node_modules
  • public
  • src
    • app
    • assets
    • environments
    • favicon.ico
    • index.html
    • main.ts
    • polyfills.ts
    • style.css
    • tsconfig.json
    • typings.d.ts
    • 等等
  • tmp
  • .angular-cli.json
  • .gitignore
  • karma.conf.js
  • package.json
  • README.md
  • tslint.json
  • 等等

Maven项目 -

  • src
    • main
      • java
      • resources
      • webapp
        • WEB-INF
        • web.xml
  • angular-project (将你的 Angular 项目放在这里)
  • node_installation
  • pom.xml

在pom.xml中添加maven-frontend-plugin配置。

 <properties>
    <angular.project.location>angular-project</angular.project.location>
    <angular.project.nodeinstallation>node_installation</angular.project.nodeinstallation>
</properties>

 <plugin>
            <groupId>com.github.eirslett</groupId>
            <artifactId>frontend-maven-plugin</artifactId>
            <version>1.0</version>
            <configuration>
                <workingDirectory>${angular.project.location}</workingDirectory>
                <installDirectory>${angular.project.nodeinstallation}</installDirectory>
            </configuration>
            <executions>
                <!-- It will install nodejs and npm -->
                <execution>
                    <id>install node and npm</id>
                    <goals>
                        <goal>install-node-and-npm</goal>
                    </goals>
                    <configuration>
                        <nodeVersion>v6.10.0</nodeVersion>
                        <npmVersion>3.10.10</npmVersion>
                    </configuration>
                </execution>

                <!-- It will execute command "npm install" inside "/e2e-angular2" directory -->
                <execution>
                    <id>npm install</id>
                    <goals>
                        <goal>npm</goal>
                    </goals>
                    <configuration>
                        <arguments>install</arguments>
                    </configuration>
                </execution>
                <!-- It will execute command "npm build" inside "/e2e-angular2" directory 
                    to clean and create "/dist" directory -->
                <execution>
                    <id>npm build</id>
                    <goals>
                        <goal>npm</goal>
                    </goals>
                    <configuration>
                        <arguments>run build</arguments>
                    </configuration>
                </execution>
            </executions>
        </plugin>

        <!-- Plugin to copy the content of /angular/dist/ directory to output 
            directory (ie/ /target/transactionManager-1.0/) -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-resources-plugin</artifactId>
            <version>2.4.2</version>
            <executions>
                <execution>
                    <id>default-copy-resources</id>
                    <phase>process-resources</phase>
                    <goals>
                        <goal>copy-resources</goal>
                    </goals>
                    <configuration>
                        <overwrite>true</overwrite>
                        <!-- This folder is the folder where your angular files 
                        will be copied to. It must match the resulting war-file name.
                        So if you have customized the name of war-file for ex. as "app.war"
                        then below value should be ${project.build.directory}/app/ 
                        Value given below is as per default war-file name -->
                        <outputDirectory>${project.build.directory}/${project.artifactId}-${project.version}/</outputDirectory>
                        <resources>
                            <resource>
                                <directory>${project.basedir}/${angular.project.location}/dist</directory>
                            </resource>
                        </resources>
                    </configuration>
                </execution>
            </executions>
        </plugin>

由于上述插件内部调用了“npm run build”,因此请确保 package.json 中的脚本中应该包含以下类似的构建命令 -

package.json

"scripts": {
    -----//-----,
    "build": "ng build --prod",
   -----//------
}

当有人从浏览器访问应用程序时,应始终加载index.html,因此将其作为欢迎文件。对于Web服务,假设我们有路径/rest-services/*,稍后会解释这一点。

web.xml -

<welcome-file-list>
    <welcome-file>index.html</welcome-file>
</welcome-file-list>

<servlet-mapping>
    <servlet-name>restservices</servlet-name>
    <url-pattern>/restservices/*</url-pattern>
</servlet-mapping>

如果您的应用程序没有任何上下文路径并且部署在服务器的根路径上,则上述配置就足够了。但是,如果您的应用程序具有任何上下文路径,例如http://localhost:8080/myapplication/,则还需要更改index.html文件 -

angular-project/src/index.html - 这里document.location将是myapplication /(您的应用程序的上下文路径,否则如果应用程序没有上下文路径,则为/)

使上下文路径成为Angular应用程序的基本路径的目的是每当您从Angular发出ajax http调用时,它都会将基本路径前置到URL。例如,如果我尝试调用'restservices/persons',它实际上会调用'http://localhost:8080/myapplication/restservices/persons'

index.html

 <!doctype html>
 <html lang="en">
 <head>
   <meta charset="utf-8">
   <title>E2E</title>
   <script>document.write('<base href="' + document.location + '" />');     </script>

   <meta name="viewport" content="width=device-width, initial-scale=1">
   <link rel="icon" type="image/x-icon" href="favicon.ico">
 </head>
 <body>
   <app-root></app-root>
 </body>

在进行以上所有更改后,运行mvn clean package,它将创建所需的war文件。检查angular 'dist'文件夹的所有内容是否都在war文件的根目录中。


这里的dist文件夹包含什么? - Abhijeet Mohanty
@abhijeet-mohanty,这是一个用于构建Angular工件的目标目录,类似于Maven的目标目录,最终生成war或jar文件。Angular CLI将所有TypeScript代码转译为JavaScript并将其放置在dist目录中。 - TimeTraveler
2
不要将任何东西放在node_installation文件夹中。这是一个占位符,前端插件会自动下载和安装nodejs。您可以选择不同的名称,但需要在pom.xml中提到相同的名称,以便插件知道它。 - TimeTraveler
请检查pom.xml文件中'maven-resources-plugin'的配置。该插件决定了war包内部的内容。XML标签'resource/directory'是'dist',而标签'outputDirectory'是'${project.build.directory}/${project.artifactId}-${project.version}/',这将变成target/appname-appversion/。这意味着dist目录下的内容将放置在war包的根目录下。您可能需要自定义此插件的配置以满足您的要求。 - TimeTraveler
让我们在聊天中继续这个讨论 - mutlei
显示剩余13条评论

0

我有一个类似的问题:我有一个名为Tourism-Services的Maven Web应用程序模块,其中包含Web服务和一个包含Angular项目的Maven项目(我在src/main/angular5/tourism文件夹中使用CLI创建了Angular项目)

enter image description here

与此帖子相反,根据Parth Ghiya提供的以下链接(如何集成Angular 2 + Java Maven Web应用程序),我认为Angular项目应该放置在Tourism-Services模块项目的webapp文件夹中。考虑到这一点,我有进一步的问题:

  1. 通常情况下,所有编译结果都应该放在dist文件夹下的webapp文件夹中。但是在dist文件夹中,并不包含所有Angular项目资源(例如图片、CSS应该存在于Angular资产文件夹中,我是对的吗?)

  2. 考虑到node_modules中的Angular依赖项,我们是否也应该将它们集成到webapp文件夹中?有一个障碍:首先,有TypeScript文件,应该编译后才能被服务器解释,但是当它们被导入到自定义应用程序Angular文件中时,它们可能已经被编译并添加了。解决方案是什么?

  3. 我们是否应该在webapp文件夹中包含来自Angular项目的其他类型的资源?(如Scrambo在上面链接帖子中建议的typings文件夹)


我认为你可以将Angular项目放在任何地方,但在pom.xml中提供其正确的相对路径。1. war插件会选择webapp文件夹中的所有内容并将其放置在war文件的根目录中。如果您将dist的内容放入webapp中,则它将进入war的根目录。在我的答案中,我们使用maven-resources-plugin将dist文件夹的内容复制到war的根目录中,而不是将dist文件夹放入webapp中。两种方式都会得到相同的结果。dist文件夹包含所有依赖项,包括asset文件夹。2.正如我所说,dist文件夹包含所有依赖项,无需集成node_modules。3.不是必要的。 - TimeTraveler
Web服务器不会解释TypeScript,angular-cli已经将其转译为JavaScript和CSS。之后,Web服务器只充当HTTP服务器,将JavaScript和CSS作为静态内容提供服务。 - TimeTraveler
最终,我决定将我的项目分为两部分:第一部分是一个包含所有后端服务(如数据库管理器、REST服务等)的EAR文件和JAR文件以及WAR文件,第二部分是一个包含所有前端内容的Angular项目。最终,第一部分部署在JBoss中,第二部分则部署在普通网站上(例如Apache)。我认为这是最好的解决方案。 - Giamma
@giamma 是的,那是最好的。 - TimeTraveler

0

我尝试了这些指示和其他文章。 它们很好,但有点模糊不清。 所以那些不能一次理解的人会查看这个。

GitHub

按照以下说明进行操作..

  1. 将您的Angular项目添加到Java项目下。 我的Angular项目名称是tdf project structure

2.打开app.module.ts文件(在您的Angular项目/src/app/app.module.ts中) 添加导入和提供程序

import { LocationStrategy, HashLocationStrategy } from '../../node_modules/@angular/common';

      providers: [
        { provide: LocationStrategy, useClass: HashLocationStrategy },
      ],

3. 打开 package.json 文件 (angularproject/package.json) 在下面添加 "build": "ng build --prod"

{
  "name": "tdf",
  "version": "0.0.0",
  "scripts": {
    "ng": "ng",
    "start": "ng serve",
     **"build": "ng build --prod",** //change like this
    "test": "ng test",
    "lint": "ng lint",
    "e2e": "ng e2e"
  },

4. 更新你的 pom.xml 文件 - 添加前端 Maven 插件 - 添加 ng build 目录

      <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>angular</groupId>
          <artifactId>angular7java</artifactId>
          <version>0.0.1-SNAPSHOT</version>
          <packaging>war</packaging>

          <name>angular7java</name>
          <url>http://maven.apache.org</url>

          <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>   
            **<angular.project.location>tdf</angular.project.location>**
            <!--your project name -->
            <angular.project.nodeinstallation>node_installation</angular.project.nodeinstallation>
          </properties>

          <dependencies>
            <dependency>
              <groupId>junit</groupId>
              <artifactId>junit</artifactId>
              <version>3.8.1</version>
              <scope>test</scope>
            </dependency>
          </dependencies>

          <build>
           <plugins>    
                <plugin>
                        <groupId>com.github.eirslett</groupId>
                        <artifactId>frontend-maven-plugin</artifactId>
                        <version>1.6</version>
                        <configuration>
                        <workingDirectory>${angular.project.location}</workingDirectory>
                        <installDirectory>${angular.project.nodeinstallation}</installDirectory>
                         </configuration>
                        <executions>
                            <execution>
                                <id>install node and npm</id>
                                <goals>
                                    <goal>install-node-and-npm</goal>
                                </goals>
                                <configuration>
                                   <nodeVersion>v9.9.0</nodeVersion>
                                </configuration>
                            </execution>

                            <execution>
                                <id>npm install</id>
                                <goals>
                                    <goal>npm</goal>
                                </goals>
                                <!-- Optional configuration which provides for running any npm command -->
                                <configuration>
                                    <arguments>install</arguments>
                                </configuration>
                            </execution>

                             <execution>
                            <id>npm build</id>
                            <goals>
                                <goal>npm</goal>
                            </goals>
                            <configuration>
                                <arguments>run build</arguments>
                            </configuration>
                        </execution>

                        </executions>
                    </plugin>

                <!-- Plugin to copy the content of /angular/dist/ directory to output 
                    directory (ie/ /target/transactionManager-1.0/) -->
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-resources-plugin</artifactId>
                    <version>2.4.2</version>
                    <executions>
                        <execution>
                            <id>default-copy-resources</id>
                            <phase>process-resources</phase>
                            <goals>
                                <goal>copy-resources</goal>
                            </goals>
                            <configuration>
                                <overwrite>true</overwrite>
                                <!-- This folder is the folder where your angular files 
                                will be copied to. It must match the resulting war-file name.
                                So if you have customized the name of war-file for ex. as "app.war"
                                then below value should be ${project.build.directory}/app/ 
                                Value given below is as per default war-file name -->
                                <outputDirectory>${project.build.directory}/${project.artifactId}-${project.version}/</outputDirectory>
                                <resources>
                                    <resource>
                                        <directory>${project.basedir}/${angular.project.location}/dist</directory>
                                    </resource>
                                </resources>
                            </configuration>
                        </execution>
                    </executions>
                </plugin>
                <plugin>
            <artifactId>maven-war-plugin</artifactId>
            <configuration>
                <failOnMissingWebXml>false</failOnMissingWebXml>
        <!--         <attachClasses>true</attachClasses>
                <webXml>target/web.xml</webXml>
                <webResources>
                    <resource>
                        <directory>src/main/webapp</directory>
                        <filtering>true</filtering>
                    </resource>
                </webResources> -->
            </configuration>
        </plugin>

                    <plugin>
                        <artifactId>maven-compiler-plugin</artifactId>
                        <version>3.1</version>
                        <configuration>
                            <fork>true</fork>
                            <executable>C:\Program Files\Java\jdk1.8.0_181\bin\javac.exe</executable>

<!--make sure above directory is correct (make it same as your local javac.exe-->
                        </configuration>
                    </plugin>
            </plugins>
        </build>



        </project>

5. 右键单击您的Maven项目,选择maven - maven install 或者 终端:mvn clean install

等待直到安装完成。 一旦安装完成,您可以看到node-installation文件夹和war文件已创建 输入图像描述


1
@HemanthPoluru 是的,你可以。这个项目是为Java和Angular设计的。将你的Java逻辑放在/src目录下(就像普通的Java项目一样)。当你获得war文件(通过maven install)后,你会发现你的Java代码也与Angular一起在里面。 - Energy
除了哈希路由策略,我们还能使用其他的路由策略吗? - Hemanth Poluru
1
@HemanthPoluru 可以,但你具体想做什么?有几种将Java和Angular集成的方法。这个答案是使用eirslett插件,但另一种方法使用另一个库。或者你也可以使用Spring Boot(https://dzone.com/articles/angular-7-spring-boot-application-hello-world-exam)。 - Energy
我有一个需求,需要连接到另一个API,但该API不接受包含“#”的路由。感谢您的快速响应。 - Hemanth Poluru
我已经找到了从URL中排除“#”的解决方案。请访问以下链接:https://dev59.com/QlgR5IYBdhLWcg3wH6ds - Hemanth Poluru
显示剩余4条评论

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