26

I'm currently needing to serve my React app with Spring Boot. It is working for the root url - localhost:8080/, but of course none of the sub-routes are recognized by the Spring Controller.

I'm not sure how to get the React Routing and Spring request mapping to line up without hard-coding in every possible route to map to index.html - and then some of the routes have variable sub-routes.


Here is my HomeController that serves the index.html

@Controller
public class HomeController {

    @RequestMapping(value = "/")
    public String index() {
        return "index.html";
    }
}

Here is the Routing render in my React App

const Root = ({ store }) => (
  <Provider store={store}>
    <Router history={browserHistory}>
      <Route path="/" component={App}>
        <IndexRedirect to="users"/>
        <Route path="/org" component={OrgSearch}>
          {<Route path="/org/:orgId" component={Org}/>}
        </Route>
        <Route path="/users" component={UserSearch}>
          {<Route path="/users/:userId" component={User} />}
        </Route>
      </Route>
    </Router>
  </Provider>
)

Any help is greatly appreciated!


EDIT: I tried adding some wildcard functionality, and it is presenting some strange behavior. Here is the updated code for the HomeController.

@Controller
public class HomeController {

    @RequestMapping(value = {"/", "/users/**", "/org/**"})
    public String index() {
        return "index.html";
    }
}

I can access / and /users but not /users/ or /users/2545.

Here is the error when I try to access the latter.

2017-04-14 09:21:59.896 ERROR 58840 --- [nio-8080-exec-3] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Circular view path [index.html]: would dispatch back to the current handler URL [/users/index.html] again. Check your ViewResolver setup! (Hint: This may be the result of an unspecified view, due to default view name generation.)] with root cause

javax.servlet.ServletException: Circular view path [index.html]: would dispatch back to the current handler URL [/users/index.html] again. Check your ViewResolver setup! (Hint: This may be the result of an unspecified view, due to default view name generation.)
    at org.springframework.web.servlet.view.InternalResourceView.prepareForRendering(InternalResourceView.java:205) ~[spring-webmvc-4.3.7.RELEASE.jar:4.3.7.RELEASE]
    at org.springframework.web.servlet.view.InternalResourceView.renderMergedOutputModel(InternalResourceView.java:145) ~[spring-webmvc-4.3.7.RELEASE.jar:4.3.7.RELEASE]
    at org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:303) ~[spring-webmvc-4.3.7.RELEASE.jar:4.3.7.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1282) ~[spring-webmvc-4.3.7.RELEASE.jar:4.3.7.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1037) ~[spring-webmvc-4.3.7.RELEASE.jar:4.3.7.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:980) ~[spring-webmvc-4.3.7.RELEASE.jar:4.3.7.RELEASE]

3 Answers 3

23

For me, I tried the answer in this link. I did not have a controller.

Basically it is about defining the addViewController...

@Configuration
public class WebConfiguration implements WebMvcConfigurer {

  @Override
  public void addViewControllers(ViewControllerRegistry registry) {
      registry.addViewController("/{spring:\\w+}")
            .setViewName("forward:/");
      registry.addViewController("/**/{spring:\\w+}")
            .setViewName("forward:/");
      registry.addViewController("/{spring:\\w+}/**{spring:?!(\\.js|\\.css)$}")
            .setViewName("forward:/");
  }
}
Sign up to request clarification or add additional context in comments.

1 Comment

note that the \\w+ regex does not match the hyphen character, so you may need to adjust depending on your routes
1

I had the same issue, and this mapping worked for me:

@RequestMapping(value = {"/","/users/{id}"})

Comments

1

I had a similar problem and solved it with separation of URLs with '**' into separate annotated methods like:

@Controller
public class HomeController {

    @RequestMapping(value = {"/"})
    public String index() {
        return "index.html";
    }

    @RequestMapping(value = {"/users/{**}"})
    public String users() {
        return "/";
    }

    @RequestMapping(value = {"/org/{**}"})
    public String org() {
        return "/";
    }
}

1 Comment

This post is a bit old but I am hitting the same issue. If I return "index.html" , I actually get text "index.html" on the browser. I do have react's packaged index.html in the static folder. Not sure what am I missing here ?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.