Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SPA with Spring Boot - serve index.html for non-API requests

I'm currently working on a webpage that should use a single page React front-end. For the back-end, I'm using the spring boot framework.

All api calls shall use a url prefixed with /api and should be handled by the REST controllers.

All other urls should simply serve the index.html file. How would I achieve this with spring?

like image 261
irundaia Avatar asked Aug 18 '16 11:08

irundaia


1 Answers

The easiest way to achieve what you want is to implement custom 404 handler.

Add these params to your application.properties:

spring.resources.add-mappings=false
spring.mvc.throw-exception-if-no-handler-found=true

First property removes all default static resource handling, second property disables Spring's default whitelabel page (by default Spring catches NoHandlerFoundException and serves standard whitelabel page)

Add 404 handler to your application context:

import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.servlet.NoHandlerFoundException;
import javax.servlet.http.HttpServletRequest;

@ControllerAdvice
public class PageNotFoundController {
    @ExceptionHandler(NoHandlerFoundException.class)
    public String handleError404() {
            return "redirect:/index.html";
    }
}

At the end you will need to add your custom view resolver for serving your static content (index.html in this case)

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceView;
import org.springframework.web.servlet.view.UrlBasedViewResolver;

@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/index.html").addResourceLocations("classpath:/static/index.html");
        super.addResourceHandlers(registry);
    }

    @Bean
    public ViewResolver viewResolver() {
        UrlBasedViewResolver viewResolver = new UrlBasedViewResolver();
        viewResolver.setViewClass(InternalResourceView.class);
        return viewResolver;
    }

}

Your index.html should be placed in /resources/static/ directory.

like image 173
Maciej Marczuk Avatar answered Nov 07 '22 03:11

Maciej Marczuk