2

I am very much new to angular and spring. I might have made some silly mistakes. I have Angular + Spring app which displays login screen and after that it shows menu. This works perfectly when not deployed (i.e. when Angular & Spring are running parallel) But when I deploy the app on tomcat, it does not show login form. I followed below steps for deployment -

  1. ng build --base-href=./
  2. copy all files from angular dist folder to spring static folder
  3. create .war file in spring and deploy it in tomcat

my pom.xml

<groupId>com.techence</groupId>
        <artifactId>new</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <packaging>war</packaging>

        <name>LoginDemoBackend</name>
        <description>Demo project for Spring Boot</description>

        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.0.4.RELEASE</version>
            <relativePath/> <!-- lookup parent from repository -->
        </parent>

        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
            <java.version>1.8</java.version>
        </properties>

        <dependencies>

        <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>

            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <scope>runtime</scope>
            </dependency>


            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-jdbc</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-configuration-processor</artifactId>
                <optional>true</optional>
            </dependency>

                <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-tomcat</artifactId>
                <version>1.5.7.RELEASE</version>
                <scope>provided</scope>
                </dependency>
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>3.1.0</version>
        <scope>provided</scope>
    </dependency>

            <dependency>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>3.1.0</version>
                <type>maven-plugin</type>
            </dependency>
        </dependencies>

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


        <dependencyManagement>
            <dependencies>
                <dependency>
                    <groupId>javax.servlet</groupId>
                    <artifactId>servlet-api</artifactId>
                    <version>2.4</version>
                </dependency>
            </dependencies>
        </dependencyManagement>
    </project>

My app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { LoginFormComponent } from './login-form/login-form.component';
import { HttpModule } from '@angular/http';
import { FormsModule} from '@angular/forms';
import { LoginServiceService } from './login-service.service';
import { HttpClientModule } from '@angular/common/http';
import { MenubarComponent } from './menubar/menubar.component';
import { BranchCreationComponent } from './menubar/branch-creation/branch-
creation.component';
import { RouterModule,Routes } from '@angular/router';
import { LedgerCreationComponent } from './menubar/ledger-creation/ledger-creation.component';

import { LocationStrategy } from '@angular/common';

import { HashLocationStrategy } from '@angular/common';

import { ForgotPasswordComponent } from './forgot-password/forgot-
password.component';

const routes: Routes = [    
    { path: '', component : LoginFormComponent}, 

    { path: 'menubar', component: MenubarComponent }, 

    { path: 'branchCreation', component: BranchCreationComponent },

    { path: 'ledgerCreation', component: LedgerCreationComponent } 
];

@NgModule({
declarations: [

    AppComponent,

    LoginFormComponent,

    MenubarComponent,

    BranchCreationComponent,

    LedgerCreationComponent,

    ForgotPasswordComponent

  ],
  imports: [ 
    BrowserModule,

FormsModule,

HttpModule,

HttpClientModule,

RouterModule.forRoot(routes),

  ],


  providers: [
              LoginServiceService,
             { provide: LocationStrategy, useClass: HashLocationStrategy },
            ],
  bootstrap: [AppComponent]
})
export class AppModule { }
4
  • Try to add /index.html after you tomcat server address. Commented Oct 8, 2018 at 10:25
  • doesn't work. it gives error - This localhost page can’t be found Commented Oct 8, 2018 at 10:47
  • try setting server.servlet.context-path=/yourapp in your Spring Boot application.properties file. afterwards try to access your app via http://localhost:<port>/yourapp. given an index.html file in your project's webapp directory you should be able to access that page. if you deploy your spring boot app to an external tomcat webcontainer (not embedded!), it will be served under a specific contextpath because a single tomcat instance can host multiple apps served under the same port. with the Spring Boot property server.servlet.context-path you can explicitly configure this contextpath. Commented Oct 8, 2018 at 11:46
  • I tried the application.properties setting but same problem. Commented Oct 8, 2018 at 12:35

1 Answer 1

5

Try to add this in your Spring Boot code:

@Bean
public ErrorViewResolver customErrorViewResolver() {
    final ModelAndView redirectToIndexHtml = new ModelAndView("forward:/index.html", Collections.emptyMap(), HttpStatus.OK);
    return (request, status, model) -> status == HttpStatus.NOT_FOUND ? redirectToIndexHtml : null;
}

It works for me and even Angular routing is working. I found it here.

Sign up to request clarification or add additional context in comments.

2 Comments

this works with tomcat 10 and angular 9. I would like to hear some explanation if possible. So that I could understand the reason behind this
@rahal-kanishka When you are requesting for your spring app resource (in this case path in your angular app) and spring doesn't have registered mapping or static file for that url it will return 404 error. ErrorViewResolver is for determine what should be returned to you in case of error (by default Whitelabel Error Page with some message). Solution is based on that if spring can't find something maybe it is placed in your angular app.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.