Categories: AngularSpring Boot

Make Spring Boot surrender routing control to Angular

In a multi module application Spring Boot should surrender routing control to Angular, otherwise trying to access any route other than the root page will result in a Whitelabel Error Page:

"There was an unexpected error (type=Not Found, status=404)"

All paths supported by Angular are accessible when the app server is started with the following command:

$ ng serve

However, when you build the whole project with Maven and run it, the app will break cause the Spring Boot will still be trying to manage paths by itself.

While the root path (e.g. http://localhost:8080/) will still work, accessing any other route (e.g. http://localhost:8080/dashboard) will give you the following error:

To fix it, you have to customize the MVC Configuration.

In a project built with Spring Boot 2.0.4 you can create a config directory and the MvcConfiguration class in it. The following code is responsible for redirecting all requests to the index.html – as a result, your Angular app will be able to handle them:

// spring-boot-angular-scaffolding/backend/src/main/java/in/keepgrowing/springbootangularscaffolding/config/MvcConfiguration.java
package in.keepgrowing.springbootangularscaffolding.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.resource.PathResourceResolver;

import java.io.IOException;

@Configuration
public class MvcConfiguration implements WebMvcConfigurer {
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/**")
                .addResourceLocations("classpath:/static/")
                .resourceChain(true)
                .addResolver(new PathResourceResolver() {
                    @Override
                    protected Resource getResource(String resourcePath, Resource location) throws IOException {
                        Resource requestedResource = location.createRelative(resourcePath);

                        return requestedResource.exists() && requestedResource.isReadable() ? requestedResource
                                : new ClassPathResource("/static/index.html");
                    }
                });
    }
}

The "/**" path pattern will be matched by AntPathMatcher to zero or more directories in a path, so this configuration will be applied to all routes in our project. Next, a resolver – created with dependency to PathResourceResolver – will try to find a resource under the given location and all requests that are not handled by Spring Boot will be redirected to index.html allowing Angular to take care of them.

Remember to add @Configuration annotation and to implement the WebMvcConfigurer interface.

You can check out my example Angular Spring Boot scaffolding project and inspect the code from this post in the commit 3a57e01056c8183d87a9eb167aebd7994d23d55f.

This solution is based on this StackOverflow answer.

Photo by Matthew Henry on StockSnap

 

little_pinecone

View Comments

Recent Posts

Simplify the management of user roles in Spring Boot

Spring Security allows us to use role-based control to restrict access to API resources. However,…

3 years ago

Create a custom annotation to configure Spring Boot tests

A custom annotation in Spring Boot tests is an easy and flexible way to provide…

3 years ago

Keycloak with Spring Boot #4 – Simple guide for roles and authorities

Delegating user management to Keycloak allows us to better focus on meeting the business needs…

3 years ago

Keycloak with Spring Boot #3 – How to authorize requests in Swagger UI

Swagger offers various methods to authorize requests to our Keycloak secured API. I'll show you…

3 years ago

Keycloak with Spring Boot #2 – Spring Security instead of Keycloak in tests

Configuring our Spring Boot API to use Keycloak as an authentication and authorization server can…

3 years ago

Keycloak with Spring Boot #1 – Configure Spring Security with Keycloak

Keycloak provides simple integration with Spring applications. As a result, we can easily configure our…

3 years ago