Serve static folder with Spring Boot and React Router

I have a React client application which is build and compiled into the Java resource folder


Content of the static folder is then served by standard Spring Boot application with no issues.

However, when I will start to use React Router, I need to be able to resolve this path:


into index.html:


I’m aware that I can do this in Controller as follow:

public class MyController {
    public String getIndex() {
       return "index.html";

However I would like to specify my Controller in more generic way:

  1. If URL {path} ends with any of “.html”, “.js”, “.json”, “.csv”, “.css”, “.png”, “.svg”, “.eot”, “.ttf”, “.woff”, “.appcache”, “.jpg”, “.jpeg”, “.gif”, “.ico”, then return file in /static/{path}
  2. Else return /static/index.html

How can I achieve it?


After lot of research and trying various approaches I have come to conclusion that the simplest solution would be to implement Filter and handle serving of static web files on my own, which bypasses the Spring’s handling:

public class StaticContentFilter implements Filter {
    private List<String> fileExtensions = Arrays.asList("html", "js", "json", "csv", "css", "png", "svg", "eot", "ttf", "woff", "appcache", "jpg", "jpeg", "gif", "ico");
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        doFilter((HttpServletRequest) request, (HttpServletResponse) response, chain);
    private void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
        String path = request.getServletPath();
        boolean isApi = path.startsWith("/api");
        boolean isResourceFile = !isApi &&;
        if (isApi) {
            chain.doFilter(request, response);
        } else if (isResourceFile) {
            resourceToResponse("static" + path, response);
        } else {
            resourceToResponse("static/index.html", response);
    private void resourceToResponse(String resourcePath, HttpServletResponse response) throws IOException {
        InputStream inputStream = Thread.currentThread()
        if (inputStream == null) {
            response.sendError(NOT_FOUND.value(), NOT_FOUND.getReasonPhrase());