score:0

  • here is an updated version of the controller previously posted:
@controller
public class reactappcontroller {

    @requestmapping(value = { "/", "/{x:[\\w\\-]+}", "/{x:^(?!api$).*$}/*/{y:[\\w\\-]+}","/error"  })
    public string getindex(httpservletrequest request) {
        return "/index.html";
    }

}

score:9

i use a filter to forward requests to index.html if it's not a static resource or not an api call.

static resources are automatically served by spring boot if they are in /resources/static. i keep them in a specific folder /resources/static/rct for easy filtering. (i do not want headaches with regex)

index.html path to react app:

<script type="text/javascript" src="http://localhost:8080/rct/js/myreactapp.js"></script>

now the filter redirecttoindexfilter.java

@component
public class redirecttoindexfilter implements filter {
    private final logger logger = loggerfactory.getlogger(this.getclass());

    @override
    public void dofilter(servletrequest request,
                         servletresponse response,
                         filterchain chain) throws ioexception, servletexception {

        httpservletrequest req = (httpservletrequest) request;
        string requesturi = req.getrequesturi();

        if (requesturi.startswith("/api")) {
            chain.dofilter(request, response);
            return;
        }

        if (requesturi.startswith("/rct")) {
            chain.dofilter(request, response);
            return;
        }

        // all requests not api or static will be forwarded to index page. 
        request.getrequestdispatcher("/").forward(request, response);
    }

}

controller to server index.html

@controller
public class appcontroller {
    private final logger logger = loggerfactory.getlogger(this.getclass());

    @getmapping(value = {"/", ""})
    public string getindex(httpservletrequest request) {
        return "/rct/index.html";
    }

}

controller to server api calls

@restcontroller
public class projectcontroller {

    private final projectservice projectservice;

    public projectcontroller(projectservice projectservice) {
        this.projectservice = projectservice;
    }

    @getmapping("/api/v1/projects/{id}")
    public projectdata getproject(@pathvariable long id) {
        projectservice.get(id);
        ...
    }

so any call that is not api or static is forwarded to index. by forwarding you keep the url as needed by react router but forward to index.html

score:10

a simple approach that will send everything that isn't under api to your react app is to create an api controller that uses regex:

import javax.servlet.http.httpservletrequest;

import org.springframework.stereotype.controller;
import org.springframework.web.bind.annotation.requestmapping;

@controller
public class reactappcontroller {

    @requestmapping(value = { "/", "/{x:[\\w\\-]+}", "/{x:^(?!api$).*$}/**/{y:[\\w\\-]+}" })
    public string getindex(httpservletrequest request) {
        return "/index.html";
    }

}

this controller simply redirects everything to index.html, allowing react and react-router to work its magic.

the regex works like this:

  • '/' - matches root
  • '/{x:[\\w\\-]+}' - matches everything up to the second \. eg. \foo
  • '/{x:^(?!api$).*$}/**/{y:[\\w\\-]+}' - matches everything that doesn't start with api. eg. \foo\bar?page=1

Related Query

More Query from same tag