-1

This is relatively simple combination of React and Spring, with plenty examples on this and other forums. I am having two profiles: dev and prod. When I build with dev, React is on the Port 3000 and Spring runs on 8080. I am using Okta for authentication and everything works as expected. I can interact with all pages. However, problems start when I build with prod profile. Application starts on port 8080. I get to my home page and I get user authenticated. After that point, I get redirected to my custom error page.

This is really frustrating and my js build is dumping all files to target/classes/public (which what I do expect) and that is also what is in my .jar file when I check it

Here is my App.js. So, nothing besides for the homepage is being served once when we are on the port 8080

class App extends Component {

render() {
    return (
        <CookiesProvider>
            <Router>
                <div>
                    {/* <AppNavbar/> */}
                    <Switch>
                        <Route path='/' exact={true} component={Home}/>
                        <Route path='/alumsum/users' exact={true} component={UserList}/>
                        <Route path='/alumsum/user/:id' exact={true} component={EditUser}/>
                        <Route path='/alumsum/onboarding'  component={Onboarding}/>
                        <Route path='/alumsum/onboardingpersonal' exact={true} component={OnboardingPersonal}/>
                        <Route path='/alumsum/onboardingothers1' exact={true} component={OnboardingOthers1}/>
                        <Route path='/alumsum/onboardingothers2' exact={true} component={OnboardingOthers2}/>
                        <Route path='/alumsum/onboardingothers3' exact={true} component={OnboardingOthers3}/>
                        <Route path='/alumsum/onboardingothers' exact={true} component={OnboardingOthersFullNine} />
                        <Route path='/alumsum/onboardingloans' exact={true} component={OnboardingLoans}/>
                        <Route path='/alumsum/plaid' exact={true} component={Plaid}/>
                        <Route path='/alumsum/privacypolicy' exact={true} component={PrivacyPolicy}/>
                        <Route path='/alumsum/termsofuse' exact={true} component={TermsOfUse}/>
                        <Route path='/alumsum/dashboard' exact={true} component={MainContent}/>
                        <Route path='/alumsum/dashboard/refinance' exact={true} component={Refinance} />
                        <Route path='/alumsum/dashboard/payment' exact={true} component={Payment} />
                    </Switch>
                    <FooterBar/>
                </div>
            </Router>
        </CookiesProvider>
    )
}

Now, if there is a question about the POM files, here they are:

<properties>
    <java.version>1.8</java.version>
    <frontend-maven-plugin.version>1.11.0</frontend-maven-plugin.version>
    <node.version>v15.12.0</node.version>
    <npm.version>7.6.3</npm.version>
</properties>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-oauth2-client</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-oauth2-jose</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-validation</artifactId>
    </dependency>

    <dependency>
        <groupId>com.h2database</groupId>
        <artifactId>h2</artifactId>
        <scope>runtime</scope>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.18</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
        <exclusions>
            <exclusion>
                <groupId>org.junit.vintage</groupId>
                <artifactId>junit-vintage-engine</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>com.kosprov.jargon2</groupId>
        <artifactId>jargon2-api</artifactId>
        <version>1.1.1</version>
    </dependency>
    <dependency>
        <groupId>com.kosprov.jargon2</groupId>
        <artifactId>jargon2-native-ri-backend</artifactId>
        <version>1.1.1</version>
        <scope>runtime</scope>
    </dependency>
    <dependency>
        <groupId>com.plaid</groupId>
        <artifactId>plaid-java</artifactId>
        <version>5.6.0</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-config</artifactId>
    </dependency>
    <dependency>
        <groupId>org.postgresql</groupId>
        <artifactId>postgresql</artifactId>
        <version>42.2.15</version>
        <scope>runtime</scope>
    </dependency>
    <dependency>
        <groupId>org.webjars.npm</groupId>
        <artifactId>react-router-dom</artifactId>
        <version>5.1.2</version>
    </dependency>

</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
        <plugin>
            <groupId>com.github.eirslett</groupId>
            <artifactId>frontend-maven-plugin</artifactId>
            <version>1.6</version>
            <configuration>
                <workingDirectory>js</workingDirectory>
                <installDirectory>target</installDirectory>
            </configuration>
            <executions>
                <execution>
                    <id>install node and npm</id>
                    <goals>
                        <goal>install-node-and-npm</goal>
                    </goals>
                    <configuration>
                        <nodeVersion>${node.version}</nodeVersion>
                        <npmVersion>${npm.version}</npmVersion>
                    </configuration>
                </execution>
                <execution>
                    <id>npm install</id>
                    <goals>
                        <goal>npm</goal>
                    </goals>
                    <configuration>
                        <arguments>install</arguments>
                    </configuration>
                </execution>
                <execution>
                    <id>npm run build</id>
                    <goals>
                        <goal>npm</goal>
                    </goals>
                    <configuration>
                        <arguments>run build</arguments>
                    </configuration>
                </execution>
            </executions>
        </plugin>
        <plugin>
            <artifactId>maven-antrun-plugin</artifactId>
            <executions>
                <execution>
                    <phase>generate-resources</phase>
                    <configuration>
                        <target>
                            <copy todir="${project.build.directory}/classes/public">
                                <fileset dir="${project.basedir}/js/build"/>
                            </copy>
                        </target>
                    </configuration>
                    <goals>
                        <goal>run</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

<profiles>
    <profile>
        <id>dev</id>
        <activation>
            <activeByDefault>true</activeByDefault>
        </activation>
        <properties>
            <spring.profiles.active>dev</spring.profiles.active>
        </properties>
    </profile>
    <profile>
        <id>prod</id>
        <properties>
            <spring.profiles.active>prod</spring.profiles.active>
        </properties>
    </profile>
</profiles>
Bad Vlad
  • 1
  • 2

1 Answers1

0

The answer is in adding an extra controller:

@Controller
class PageController {

    @GetMapping("/**/{path:[^\\.]*}")
    fun forward(request: HttpServletRequest): String? {
        if(request.requestURI.startsWith("/admin")) {
            return "forward:/admin/index.html"
        }
        return "forward:/index.html"
    }
}

Which happens to be the answer to the question Configure Spring Boot For SPA frontend

Bad Vlad
  • 1
  • 2