简体   繁体   中英

How to integrate an Angular 4 app with a Spring Boot stack?

i would like to integrate an Angular 4 client app with a Java Spring application working on http://localhost:8080/ and offering some Rest endpoints. My goal is to be able to call the Angular app from a url like http://localhost:8080/adminisitration . How can I do that?

Thanks in advance,

You would need to prod build your ng app and place that in spring-boot folder:

  1. Create a public folder under resources in your spring-boot project

  2. ng build --prod , type this command on you angular project which will create a dist folder under your angular project directory

  3. Copy files from you dist folder and place it in public folder under resources of your spring-boot project.

This will help you run your angular-app under spring-boot.

Then hit http://localhost:8080/adminisitration, it should work fine

There are two ways first is that you serve angular app from your spring boot application as static resources so you need to pack it into jar and that's not easy when you have two different repositories for frontend and backend and doesn't look to good from maintenance point of view.

Second is that you have angular static resources on nginx and spring boot app is reachable to angular thru reverse proxy configured on nginx like

location /api/ {
    proxy_pass http://localhost:8080/api/;
}

So when angular asks for GET http://localhost/api/somerest it forwards it to GET http://localhost:8080/api/somerest

Take a look at this tutorial might help you link

You can also use angular cli in this tutorial and point it to a resource folder (the one you create... ie front end) then set up that as a resource in your maven pom.xml.

The easiest way to serve an angular front-end from a spring-boot application , is to have a multi-module project. Then automate the build process to copy the dist folder from the ui module into the service module during maven clean install itself.This way, you could have a single executable jar that serves the angular as well.For instance, consider the following project structure :

SampleMultiModuleProject
 |__SampleMultiModuleService
 |__SampleMultiModuleUI

In this case, you will have three different pom files like as follows.

SampleMultiModuleProject main pom.xml : (where all main dependencies are present)

<modules>
    <module>SampleMultiModuleUI</module>
    <module>SampleMultiModuleService</module>
</modules>

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.2.2.RELEASE</version>
    <relativePath/>
</parent>

//add rest of the dependencies here.

SampleMultiModuleService service pom.xml : (for service module and add the springboot maven plugin to make it executable with embedded tomcat, and add other dependencies that are needed in service module , for instance lombok)

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

and finally configure the ui module to build angular like SampleMultiModuleUI pom.xml :

<build>
    <plugins>
        <plugin>
            <groupId>com.github.eirslett</groupId>
            <artifactId>frontend-maven-plugin</artifactId>
            <version>1.9.1</version>
            <configuration>
                <workingDirectory>./</workingDirectory>
                <nodeVersion>v13.3.0</nodeVersion>
                <npmVersion>6.13.1</npmVersion>
                <nodeDownloadRoot>http://nodejs.org/dist/</nodeDownloadRoot>
                <npmDownloadRoot>http://registry.npmjs.org/npm/-/</npmDownloadRoot>
                <installDirectory>./</installDirectory>
                <npmInheritsProxyConfigFromMaven>false</npmInheritsProxyConfigFromMaven>
            </configuration>
            <executions>
                <execution>
                    <id>install node and npm</id>
                    <goals>
                        <goal>install-node-and-npm</goal>
                    </goals>
                    <phase>generate-resources</phase>
                </execution>
                <execution>
                    <id>npm install</id>
                    <goals>
                        <goal>npm</goal>
                    </goals>
                    <phase>generate-resources</phase>
                  <configuration>
                    <arguments>install</arguments>
                  </configuration>
                </execution>
                <execution>
                    <id>npm run-script build-prod</id>
                    <phase>prepare-package</phase>
                    <goals>
                        <goal>npm</goal>
                    </goals>
                    <configuration>
                        <arguments>run-script build</arguments>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>

</build>

So what happens is when you do maven clean install, it will trigger the build of the ui module which in turn uses the frontend builder to install a local npm which runs the command specified in the arguments. The package.json file in your angular application will by default contain something like :

  "scripts": {
    "ng": "ng",
    "start": "ng serve",
    "build": "ng build --prod",
    "test": "ng test",
    "lint": "ng lint",
    "e2e": "ng e2e",
    "stats": "webpack-bundle-analyzer dist/stats.json"
  },

So you are essentially calling this ng build --prod through this process.Also in angular.json set the output path as the resources folder under the service module in your project, so that the assets will be created there.

  "newProjectRoot": "projects",
  "projects": {
    "SampleMultiModuleUI": {
      "projectType": "application",
      "schematics": {},
      "root": "",
      "sourceRoot": "src",
      "prefix": "app",
      "architect": {
        "build": {
          "builder": "@angular-devkit/build-angular:browser",
          "options": {
            "outputPath": "../SampleMultiModuleService/src/main/resources/static",
       //rest of the config

as i understand your question just create new file named proxy.config.json and paste below code in that file, place file next to .angular-cli.json

{
  "/": {
    "target": "http://localhost:8080",
    "secure": false,
    "logLevel": "debug"
  }
}

for hitting url to backend server don't use http://localhost:8080/administration instead use /administration as we use http://localhost:8080/ in our proxy file. in app.component.ts file place below code in ngOnInit()

this.http.get('/adminisitration',someRequestOption).subscribe(res =>{
  console.log('happy...!');
})

start backend server: (tomcat on port 8080 ) and

start frontend server: ng serve --proxy-config proxy.config.json open browser and type url http://localhost:4200 you will see logs on server and client if any.

NOTE: above ports are default as provided by spring boot and angular 4

I think best way is to separate angular 4 app and java spring app.

In my case java spring app is API handling all requests from angular 4 app via proxy (angular-cli proxy -> easy to configure).

Angular 4 app on node.js, developed in visual studio code, and java spring on embedded tomcat (undertow) developed in eclipse. They can be on separated servers (eg. my angular 4 app is on localhost:4200 while java spring API is on http://mydomain.ch:8900 )

If you need more info then add comment.

Hope in helps

PS. proxy is handled on client side (angular 4 app) not on server side (java spring)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM