如何集成 Angular 2 + Java Maven Web 应用程序
Posted
技术标签:
【中文标题】如何集成 Angular 2 + Java Maven Web 应用程序【英文标题】:how to integrate Angular 2 + Java Maven Web Application 【发布时间】:2016-11-26 16:44:39 【问题描述】:我创建了一个 Angular 2 前端应用程序。我创建了一个连接到数据库的 Java Rest WS 后端应用程序。
Angular 2 App 的文件夹结构如下-
Angular2App
confg
dist
e2e
node_modules
public
src
app
favicon.ico
index.html
main.ts
system-config.ts
tsconfig.json
typings.d.ts
tmp
typings
.editorconfig
.gitignore
angular-cli.json
angular-cli-build.js
package.json
README.md
tslint.json
typings.json
我的 Java Maven Web 应用程序结构如下-
JerseyWebApp
src
main
java
Custom Package
java classes
resources
webapp
WEB-INF
web.xml
index.html
pom.xml
我想知道如何将这两个应用程序集成到一个只生成一个war文件的应用程序中。
【问题讨论】:
我使用 spring boot 构建我的应用程序,我们为 angular2 制作 jars。样品请参考github.com/Kiran-N/springboot-and-angular2 有类似的任务,这是我的方法***.com/questions/37512154/… 【参考方案1】:我建议让两个应用程序分开,这样你就有了模块化。 这样您就可以在不影响您的服务的情况下更改 Angular 应用程序,反之亦然。其次,您的 apache/nginx 可以更快地从 Angular 而不是 Tomcat 交付您的 js 和 html(例如)。但是如果你仍然想把 Angular 应用程序放在 war 中,模式是所有的 web 资源都在 src/main/webapp 中。
【讨论】:
这样我尝试将所有的网络资源放在 src/main/webapp 下,但在这里我面临一个问题,比如 angular2 是建立在 typescript 上的,所以 tomcat 服务器无法编译这些文件。而且应用程序卡住了。 是的。也许这对你有帮助:***.com/a/37398298/2285259【参考方案2】:有趣的是,我上周就这样做了!
使用 Netbeans 8.1 和 Tomcat servlet 版本 8.0.27
Angular 和 Java 项目文件结构。
Java 项目名为 Foo。 Angular 项目是酒吧
Foo (Java Maven Project)
|__ src
| |__ main
| | |__ webapp (This folder contains the entire Angular Project)
| | | |__ META-INF
| | | | \__ context.xml
| | | |__ WEB-INF
| | | | \__ web.xml
| | | |__ includes
| | | | |__ css
| | | | |__ images
| | | | \__ js
| | | |
| | | | ## Bar project files are located here ##
| | | |
| | | |__ app
| | | | \__ All .ts and compiled .js files are located here
| | | |__ node_modules
| | | | \__ any dependencies used for Bar are located here
| | | |__ typings
| | | | \__ typings for Typescript located here
| | | |
| | | |__ README.txt
| | | |__ index.jsp
| | | |__ package.json
| | | |__ systemjs.config.js
| | | |__ tsconfig.json
| | | |__ typings.json
| | | \ ## Bar project files end here
| | |
| | |__ resources
| | | |__META-INF
| | | | \__ persistence.xml
| | |__ java
| | | |__ hibernate.cfg.xml
| | | |__ com
| | | | |__ orgName
| | | | | |__ packageName
| | | | | | \__ .java files are here
|__ pom.xml
\__ nb-configuration.xml
【讨论】:
【参考方案3】:这是我所做的:-
安装 Nodejs v6.9+ 为 Angular CLI 运行 npm install @angular/cli –g 安装 Apache Maven 或使用任何 Maven 友好的 IDE 使用您所需的 Maven 配置,我使用了简单的 webapp (WAR)。目录结构(除了 ngapp 文件夹其余部分是标准 Maven 结构。)
ngfirst
├── pom.xml
├── src
│ └── main
│ ├── java
│ ├── resources
│ ├── webapp
│ └── ngapp
角部分
在终端打开 ngapp 文件夹并输入 ng init 命令来初始化节点和 npm 配置,结果将是一个简单的 Angular2 示例应用程序,在 ngapp 内的目录结构如下文件夹:-
├── angular-cli.json
├── e2e
├── karma.conf.js
├── node_modules
├── package.json
├── protractor.conf.js
├── README.md
├── tslint.json
├── src
├── app
├── assets
├── environments
├── favicon.ico
├── index.html
├── main.ts
├── polyfills.ts
├── styles.css
├── test.ts
└── tsconfig.json
这个结构是 Angular 等效的 Maven 项目结构,src 目录是 Angular 应用程序的源,就像 maven build 命令在 target 中生成它的输出> 文件夹,ng build 命令在 dist 文件夹中生成其输出。
为了将生成的 Angular 应用程序打包到 Maven 生成的 WAR 中,修改构建配置以将输出文件夹从 dist 更改为 webapp,打开 angular-cli .json 文件并修改其 outDir 如下:-
"outDir": "../webapp/ng"
此时 ng build 命令将在 ngfirst/src/main/webapp 文件夹的 ng 目录中生成已构建的 Angular 应用程序。 p>
Maven 部分
打开pom.xml,配置以下三个maven插件:-
-
compiler-plugin:在 /src/main/ngapp 文件夹中没有要编译的 Java 内容,排除它。
war-plugin:/src/main/ngapp 是 Angular 项目文件夹,不应该打包在 WAR 中,排除它。
exec-plugin:执行 NPM Install 和 Angular-CLI Build 命令,在 webapp 文件夹中生成 Angular Application 以进行最终打包。注意 --base-href 参数,需要从 webapp 的上下文路径加载 Angular 资源。
它应该是这样的:-
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<excludes>
<exclude>ngapp/**</exclude>
</excludes>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.0.0</version>
<configuration>
<excludes>
<exclude>ngapp/**</exclude>
</excludes>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.5.0</version>
<executions>
<execution>
<id>exec-npm-install</id>
<phase>generate-sources</phase>
<configuration>
<workingDirectory>$project.basedir/src/main/ngapp</workingDirectory>
<executable>npm</executable>
<arguments>
<argument>install</argument>
</arguments>
</configuration>
<goals>
<goal>exec</goal>
</goals>
</execution>
<execution>
<id>exec-npm-ng-build</id>
<phase>generate-sources</phase>
<configuration>
<workingDirectory>$project.basedir/src/main/ngapp</workingDirectory>
<executable>ng</executable>
<arguments>
<argument>build</argument>
<argument>--base-href=/ngfirst/ng/</argument>
</arguments>
</configuration>
<goals>
<goal>exec</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
构建 Maven 项目(以及 Angular 应用程序)
在项目根目录ngfirst打开终端并运行mvn package命令,这将在target中生成一个WAR文件(ngfirst.war)文件夹。
在容器中部署ngfirst.war,在浏览器中打开http://localhost:8080/ngfirst/ng/index.html。 (如果需要,调整您的主机名和端口)
如果一切正常,您应该会在浏览器中看到 应用正常工作!,这就是 Angular 应用程序在工作!
JSP 预处理
我们可以利用 Angular 应用程序的 JSP 技术的动态配置和页面渲染功能,Angular SPA 由 Java 容器作为常规 HTML 页面提供服务,在这种情况下 index.html,如果我们配置 JSP引擎也可以预处理 html 文件,然后所有的 JSP 魔法都可以包含在 Angular SPA 页面中,只需在 web.xml
中包含以下内容<servlet-mapping>
<servlet-name>jsp</servlet-name>
<url-pattern>*.html</url-pattern>
</servlet-mapping>
保存,重建 maven 项目,部署 WAR,瞧!!
【讨论】:
我建议使用<warSourceExcludes>ngapp/**</warSourceExcludes>
排除ngapp文件夹或packagingExcludes>
@J_Dev 这工作正常。问题是 jar 还包含节点模块。我怎么能只包含 ng serve --prod
或 ng build
输出?
@J_Dev - 您能解释一下为什么将 ngapp 排除在战争之外。我认为这个问题是关于在同一场战争中集成/捆绑 angular 2 应用程序和 java 代码。如果您将其排除在外,那么角度代码如何部署?
角路由器不需要url重写吗?
@user911 目录ngapp
(Angular 应用程序的源代码)被排除在战争之外,但目录webapp/ng
(Angular 应用程序的可执行文件)包含在战争中。【参考方案4】:
我有一个用于角度源的 maven 模块,称为 prj-angular,还有一个用于战争应用程序的模块,称为 prj-war。
首先构建prj angular:
它使用 maven-exec-plugin 调用npm install
和 ng build
(感谢 @J_Dev!)
将资源默认目录更改为dist/
跳过 jar 清单生成
maven 模块结果:仅包含生成的角度 dist/ 内容的 jar!
然后,第二个 prj_war 正在构建:
有 prj angular 作为依赖项 使用解压阶段将之前的 jar 解压到 Web 应用目标中 此模块使用全新的 angular dist 构建您的应用大战。按照我使用的对应插件配置下:
prj 角度(pom.xml 提取)
<build>
<resources>
<resource>
<directory>dist</directory>
</resource>
</resources>
<plugins>
<!-- skip compile -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<executions>
<execution>
<id>default-compile</id>
<phase />
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<executions>
<execution>
<id>exec-npm-install</id>
<phase>generate-sources</phase>
<configuration>
<workingDirectory>$project.basedir</workingDirectory>
<executable>npm.cmd</executable>
<arguments>
<argument>install</argument>
</arguments>
</configuration>
<goals>
<goal>exec</goal>
</goals>
</execution>
<execution>
<id>exec-npm-ng-build</id>
<phase>generate-sources</phase>
<configuration>
<workingDirectory>$project.basedir/src</workingDirectory>
<executable>ng.cmd</executable>
<arguments>
<argument>build</argument>
<argument>--no-progress</argument>
<argument>--base-href=/app/ng/</argument> <== to update
</arguments>
</configuration>
<goals>
<goal>exec</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<addMavenDescriptor>false</addMavenDescriptor>
<manifest>
<addClasspath>false</addClasspath>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/</exclude>
</excludes>
</filter>
</filters>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
prj 战争(pom.xml 提取)
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>unpack angular distribution</id>
<phase>generate-resources</phase>
<goals>
<goal>unpack</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>com.myapp</groupId> <== to update
<artifactId>prj-angular</artifactId> <== to update
<overWrite>true</overWrite>
<includes>**/*</includes>
</artifactItem>
</artifactItems>
<outputDirectory>$project.build.directory/prjwar/ng</outputDirectory> <== to update
<overWriteReleases>true</overWriteReleases>
<overWriteSnapshots>true</overWriteSnapshots>
</configuration>
</execution>
</executions>
</plugin>
【讨论】:
最近发现github.com/eirslett/frontend-maven-plugin【参考方案5】:我想分享我是如何设置我的 Angular/Java 项目的。一些重要的事情:
只有一个 Maven 项目,它允许我构建整个项目。这样,我可以构建整个项目,也可以分别构建客户端和后端。
我的项目基于 Spring Boot 框架。但是,您可以轻松地根据您的情况调整我的解决方案。我生成的 Angular 项目的 output
代码放在 `META-INF' 文件夹下。如果你不使用 Spring Boot,你显然可以改变它。
在我的项目中,我想在public
文件夹中发布angular项目。
当我开发时,我分别运行 Angular 项目和后端项目:Angular with ng serve
和 IDE (Eclipse) 中的后端项目(Java 部分)。
好的,让我们开始吧。整个项目结构如下图所示。
如您所见,我将 Angular 项目放在 'src\main\ngapp' 文件夹中。对于 Java 项目(后端),我使用 Eclipse IDE,对于 Angular 项目,我使用 Webstorm。您可以选择您喜欢的 IDE 来管理项目。重要的是:您将需要两个 IDE 来管理整个项目。
为了使用 Maven 构建 Angular 项目,我使用了以下 maven 配置文件定义。
<profile>
<id>build-client</id>
<build>
<plugins>
<plugin>
<groupId>com.github.eirslett</groupId>
<artifactId>frontend-maven-plugin</artifactId>
<version>1.3</version>
<configuration>
<nodeVersion>v10.13.0</nodeVersion>
<npmVersion>6.4.1</npmVersion>
<workingDirectory>src/main/ngapp/</workingDirectory>
</configuration>
<executions>
<execution>
<id>install node and npm</id>
<goals>
<goal>install-node-and-npm</goal>
</goals>
</execution>
<execution>
<id>npm install</id>
<goals>
<goal>npm</goal>
</goals>
</execution>
<execution>
<id>npm run build-prod</id>
<goals>
<goal>npm</goal>
</goals>
<configuration>
<arguments>run build</arguments>
</configuration>
</execution>
<execution>
<id>prod</id>
<goals>
<goal>npm</goal>
</goals>
<configuration>
<arguments>run-script build</arguments>
</configuration>
<phase>generate-resources</phase>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
如您所见,我使用com.github.eirslett:frontend-maven-plugin
插件安装node 并运行npm 来构建Angular 项目。这样,当我运行maven配置文件build-client
插件的时候:
检查并安装Angular项目文件夹src/main/ngapp/
中的节点版本v10.13.0
运行命令npm run build
。在 Angular 项目中定义了构建别名在 package.json
"scripts":
"ng": "ng",
"start": "ng serve --proxy-config proxy.conf.json",
"build": "ng build --configuration=production",
"test": "ng test",
"lint": "ng lint",
"e2e": "ng e2e"
Angular 客户端必须放在 Web 应用程序的 public
文件夹中。为此,Angular 项目配置为具有baseHref=/public
。此外,构建的项目必须放在src/main/resources/META-INF/resources/public
。在angular.json
你会发现:
"build":
"builder": "@angular-devkit/build-angular:browser",
"options":
"baseHref":"/public/",
"outputPath": "../resources/META-INF/resources/public",
...
在非 Spring Boot 项目中,您可能需要将构建的 Angular 项目直接放在 src/main/webapp/public
文件夹中。为此,只需根据需要修改angular.json
文件即可。
您可以在my github project 中找到所有项目的代码。插件项目是here。
【讨论】:
我对您的部署有疑问。您是否遇到路由问题/ Maven?如果您在 url 中输入了不指向 /public 的内容(即 /public/user),您会得到一个 while 列表错误页面吗?看起来我们的项目设置与您的类似。这两个应用程序分别部署在 Maven 下,一个用于 java,一个用于 Angular。然后将其配置为将 Angular 应用程序作为静态页面提供服务。【参考方案6】:<plugin>
<groupId>com.github.eirslett</groupId>
<artifactId>frontend-maven-plugin</artifactId>
<version>1.3</version>
<configuration>
<nodeVersion>v10.13.0</nodeVersion>
<npmVersion>6.4.1</npmVersion>
<workingDirectory>src/main/ngapp/</workingDirectory>
</configuration>
<executions>
<execution>
<id>install node and npm</id>
<goals>
<goal>install-node-and-npm</goal>
</goals>
</execution>
<execution>
<id>npm install</id>
<goals>
<goal>npm</goal>
</goals>
</execution>
<execution>
<id>npm run build-prod</id>
<goals>
<goal>npm</goal>
</goals>
<configuration>
<arguments>run build</arguments>
</configuration>
</execution>
<execution>
<id>prod</id>
<goals>
<goal>npm</goal>
</goals>
<configuration>
<arguments>run-script build</arguments>
</configuration>
<phase>generate-resources</phase>
</execution>
</executions>
</plugin>
【讨论】:
欢迎来到 S/O。请在回答时简要说明您正在做什么。【参考方案7】:基于命令行构建angular项目的解决方案
npm install --verbose
npm run ng build
给定
src/main/frontend
src/main/webapp
maven-war-plugin + exec-maven-plugin
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.3</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
<webResources>
<resource>
<directory>src/main/frontend/dist</directory>
</resource>
</webResources>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<id>npm-install</id>
<phase>generate-sources</phase>
<configuration>
<workingDirectory>src/main/frontend</workingDirectory>
<executable>npm</executable>
<arguments>
<argument>install</argument>
</arguments>
</configuration>
<goals>
<goal>exec</goal>
</goals>
</execution>
<execution>
<id>npm-ng-build</id>
<phase>generate-sources</phase>
<configuration>
<workingDirectory>src/main/frontend</workingDirectory>
<executable>npm</executable>
<arguments>
<argument>run</argument>
<argument>ng</argument>
<argument>build</argument>
</arguments>
</configuration>
<goals>
<goal>exec</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
maven-war-plugin + maven-antrun-plugin(无法直接在我的机器上运行 npm,因此依赖于操作系统构建)
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.3</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
<webResources>
<resource>
<directory>src/main/frontend/dist</directory>
</resource>
</webResources>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<id>exec-gen-sources</id>
<phase>generate-sources</phase>
<configuration>
<target name="Build Frontend">
<exec executable="cmd" dir="src/main/frontend" failonerror="true">
<arg line="/c npm install --verbose" />
</exec>
<exec executable="cmd" dir="src/main/frontend" failonerror="true">
<arg line="/c npm run ng build" />
</exec>
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
【讨论】:
以上是关于如何集成 Angular 2 + Java Maven Web 应用程序的主要内容,如果未能解决你的问题,请参考以下文章
集成 Angular + Nodejs + Spring Boot Java REST API 使 Angular Universal 工作
如何将 D3.js 与 Renderer API 与 Angular 2 集成