Spring Boot 2.1.0 only serve index.html if resource not resolved (SPA, react-router)












7















I am serving an SPA made with create-react-app and react-router using Spring Boot 2.1.0 with this configuration



import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebMvcConfiguration implements WebMvcConfigurer {

@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/**/{path:[^\.]+}")
.setViewName("forward:/");
}
}


Basically what it does is always serve index.html unless there's a period in the path. I would like to align this with create-react-app's provided .htaccess. How can I make Spring Boot match this functionality?



RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.html [L]









share|improve this question



























    7















    I am serving an SPA made with create-react-app and react-router using Spring Boot 2.1.0 with this configuration



    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
    import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

    @Configuration
    public class WebMvcConfiguration implements WebMvcConfigurer {

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
    registry.addViewController("/**/{path:[^\.]+}")
    .setViewName("forward:/");
    }
    }


    Basically what it does is always serve index.html unless there's a period in the path. I would like to align this with create-react-app's provided .htaccess. How can I make Spring Boot match this functionality?



    RewriteEngine on
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule . /index.html [L]









    share|improve this question

























      7












      7








      7


      1






      I am serving an SPA made with create-react-app and react-router using Spring Boot 2.1.0 with this configuration



      import org.springframework.context.annotation.Configuration;
      import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
      import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

      @Configuration
      public class WebMvcConfiguration implements WebMvcConfigurer {

      @Override
      public void addViewControllers(ViewControllerRegistry registry) {
      registry.addViewController("/**/{path:[^\.]+}")
      .setViewName("forward:/");
      }
      }


      Basically what it does is always serve index.html unless there's a period in the path. I would like to align this with create-react-app's provided .htaccess. How can I make Spring Boot match this functionality?



      RewriteEngine on
      RewriteCond %{REQUEST_FILENAME} !-f
      RewriteCond %{REQUEST_FILENAME} !-d
      RewriteRule . /index.html [L]









      share|improve this question














      I am serving an SPA made with create-react-app and react-router using Spring Boot 2.1.0 with this configuration



      import org.springframework.context.annotation.Configuration;
      import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
      import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

      @Configuration
      public class WebMvcConfiguration implements WebMvcConfigurer {

      @Override
      public void addViewControllers(ViewControllerRegistry registry) {
      registry.addViewController("/**/{path:[^\.]+}")
      .setViewName("forward:/");
      }
      }


      Basically what it does is always serve index.html unless there's a period in the path. I would like to align this with create-react-app's provided .htaccess. How can I make Spring Boot match this functionality?



      RewriteEngine on
      RewriteCond %{REQUEST_FILENAME} !-f
      RewriteCond %{REQUEST_FILENAME} !-d
      RewriteRule . /index.html [L]






      reactjs spring-mvc spring-boot react-router single-page-application






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Nov 20 '18 at 12:34









      Roberto GrahamRoberto Graham

      508




      508
























          3 Answers
          3






          active

          oldest

          votes


















          1





          +100









          To reroute "404 : file not found" to "forward:/", which I think is what the .htaccess does, change your WebMvcConfiguration to...



          @Configuration
          public class WebMvcConfiguration implements ErrorViewResolver
          {

          @Override
          public ModelAndView resolveErrorView(HttpServletRequest request, HttpStatus status, Map<String, Object> model) {
          if (status == HttpStatus.NOT_FOUND) {
          return new ModelAndView("forward:/");
          }
          return null;
          }

          }





          share|improve this answer

































            2














            You can catch-all unhandled view controller like below when no other route has been found.



            @Configuration
            public class WebMvcConfiguration implements WebMvcConfigurer {

            @Override
            public void addViewControllers(ViewControllerRegistry registry) {
            registry.setOrder(Ordered.LOWEST_PRECEDENCE);
            registry.addViewController("/**").setViewName("forward:/index.html");
            }
            }





            share|improve this answer
























            • Thanks for the response. When I go to a route configured with react-router now and refresh the page, I get a whitelabel error page which I didn't get with the previous config

              – Roberto Graham
              Nov 24 '18 at 15:53











            • @RobertoGraham Can you show your directory structure?

              – Sukhpal Singh
              Nov 25 '18 at 15:18



















            0














            Following Kotlin code might help:



            @Configuration
            class WebMvcConfig(val resourceProperties: ResourceProperties) : WebMvcConfigurer {

            override fun addResourceHandlers(registry: ResourceHandlerRegistry) {
            registry.addResourceHandler("/**")
            .addResourceLocations(*resourceProperties.staticLocations)
            .resourceChain(resourceProperties.chain.isCache)
            .addResolver(FallbackPathResourceResolver())
            }

            private class FallbackPathResourceResolver : PathResourceResolver() {
            override fun resolveResource(
            request: HttpServletRequest?,
            requestPath: String,
            locations: MutableList<out Resource>,
            chain: ResourceResolverChain
            ): Resource? {
            return super.resolveResource(request, requestPath, locations, chain) ?: super.resolveResource(
            request,
            "/index.html",
            locations,
            chain
            )
            }
            }
            }


            Reference: https://jira.spring.io/browse/SPR-16788






            share|improve this answer























              Your Answer






              StackExchange.ifUsing("editor", function () {
              StackExchange.using("externalEditor", function () {
              StackExchange.using("snippets", function () {
              StackExchange.snippets.init();
              });
              });
              }, "code-snippets");

              StackExchange.ready(function() {
              var channelOptions = {
              tags: "".split(" "),
              id: "1"
              };
              initTagRenderer("".split(" "), "".split(" "), channelOptions);

              StackExchange.using("externalEditor", function() {
              // Have to fire editor after snippets, if snippets enabled
              if (StackExchange.settings.snippets.snippetsEnabled) {
              StackExchange.using("snippets", function() {
              createEditor();
              });
              }
              else {
              createEditor();
              }
              });

              function createEditor() {
              StackExchange.prepareEditor({
              heartbeatType: 'answer',
              autoActivateHeartbeat: false,
              convertImagesToLinks: true,
              noModals: true,
              showLowRepImageUploadWarning: true,
              reputationToPostImages: 10,
              bindNavPrevention: true,
              postfix: "",
              imageUploader: {
              brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
              contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
              allowUrls: true
              },
              onDemand: true,
              discardSelector: ".discard-answer"
              ,immediatelyShowMarkdownHelp:true
              });


              }
              });














              draft saved

              draft discarded


















              StackExchange.ready(
              function () {
              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53393115%2fspring-boot-2-1-0-only-serve-index-html-if-resource-not-resolved-spa-react-rou%23new-answer', 'question_page');
              }
              );

              Post as a guest















              Required, but never shown

























              3 Answers
              3






              active

              oldest

              votes








              3 Answers
              3






              active

              oldest

              votes









              active

              oldest

              votes






              active

              oldest

              votes









              1





              +100









              To reroute "404 : file not found" to "forward:/", which I think is what the .htaccess does, change your WebMvcConfiguration to...



              @Configuration
              public class WebMvcConfiguration implements ErrorViewResolver
              {

              @Override
              public ModelAndView resolveErrorView(HttpServletRequest request, HttpStatus status, Map<String, Object> model) {
              if (status == HttpStatus.NOT_FOUND) {
              return new ModelAndView("forward:/");
              }
              return null;
              }

              }





              share|improve this answer






























                1





                +100









                To reroute "404 : file not found" to "forward:/", which I think is what the .htaccess does, change your WebMvcConfiguration to...



                @Configuration
                public class WebMvcConfiguration implements ErrorViewResolver
                {

                @Override
                public ModelAndView resolveErrorView(HttpServletRequest request, HttpStatus status, Map<String, Object> model) {
                if (status == HttpStatus.NOT_FOUND) {
                return new ModelAndView("forward:/");
                }
                return null;
                }

                }





                share|improve this answer




























                  1





                  +100







                  1





                  +100



                  1




                  +100





                  To reroute "404 : file not found" to "forward:/", which I think is what the .htaccess does, change your WebMvcConfiguration to...



                  @Configuration
                  public class WebMvcConfiguration implements ErrorViewResolver
                  {

                  @Override
                  public ModelAndView resolveErrorView(HttpServletRequest request, HttpStatus status, Map<String, Object> model) {
                  if (status == HttpStatus.NOT_FOUND) {
                  return new ModelAndView("forward:/");
                  }
                  return null;
                  }

                  }





                  share|improve this answer















                  To reroute "404 : file not found" to "forward:/", which I think is what the .htaccess does, change your WebMvcConfiguration to...



                  @Configuration
                  public class WebMvcConfiguration implements ErrorViewResolver
                  {

                  @Override
                  public ModelAndView resolveErrorView(HttpServletRequest request, HttpStatus status, Map<String, Object> model) {
                  if (status == HttpStatus.NOT_FOUND) {
                  return new ModelAndView("forward:/");
                  }
                  return null;
                  }

                  }






                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  edited Nov 29 '18 at 17:14

























                  answered Nov 29 '18 at 16:38









                  pcoatespcoates

                  951128




                  951128

























                      2














                      You can catch-all unhandled view controller like below when no other route has been found.



                      @Configuration
                      public class WebMvcConfiguration implements WebMvcConfigurer {

                      @Override
                      public void addViewControllers(ViewControllerRegistry registry) {
                      registry.setOrder(Ordered.LOWEST_PRECEDENCE);
                      registry.addViewController("/**").setViewName("forward:/index.html");
                      }
                      }





                      share|improve this answer
























                      • Thanks for the response. When I go to a route configured with react-router now and refresh the page, I get a whitelabel error page which I didn't get with the previous config

                        – Roberto Graham
                        Nov 24 '18 at 15:53











                      • @RobertoGraham Can you show your directory structure?

                        – Sukhpal Singh
                        Nov 25 '18 at 15:18
















                      2














                      You can catch-all unhandled view controller like below when no other route has been found.



                      @Configuration
                      public class WebMvcConfiguration implements WebMvcConfigurer {

                      @Override
                      public void addViewControllers(ViewControllerRegistry registry) {
                      registry.setOrder(Ordered.LOWEST_PRECEDENCE);
                      registry.addViewController("/**").setViewName("forward:/index.html");
                      }
                      }





                      share|improve this answer
























                      • Thanks for the response. When I go to a route configured with react-router now and refresh the page, I get a whitelabel error page which I didn't get with the previous config

                        – Roberto Graham
                        Nov 24 '18 at 15:53











                      • @RobertoGraham Can you show your directory structure?

                        – Sukhpal Singh
                        Nov 25 '18 at 15:18














                      2












                      2








                      2







                      You can catch-all unhandled view controller like below when no other route has been found.



                      @Configuration
                      public class WebMvcConfiguration implements WebMvcConfigurer {

                      @Override
                      public void addViewControllers(ViewControllerRegistry registry) {
                      registry.setOrder(Ordered.LOWEST_PRECEDENCE);
                      registry.addViewController("/**").setViewName("forward:/index.html");
                      }
                      }





                      share|improve this answer













                      You can catch-all unhandled view controller like below when no other route has been found.



                      @Configuration
                      public class WebMvcConfiguration implements WebMvcConfigurer {

                      @Override
                      public void addViewControllers(ViewControllerRegistry registry) {
                      registry.setOrder(Ordered.LOWEST_PRECEDENCE);
                      registry.addViewController("/**").setViewName("forward:/index.html");
                      }
                      }






                      share|improve this answer












                      share|improve this answer



                      share|improve this answer










                      answered Nov 23 '18 at 15:58









                      Sukhpal SinghSukhpal Singh

                      879110




                      879110













                      • Thanks for the response. When I go to a route configured with react-router now and refresh the page, I get a whitelabel error page which I didn't get with the previous config

                        – Roberto Graham
                        Nov 24 '18 at 15:53











                      • @RobertoGraham Can you show your directory structure?

                        – Sukhpal Singh
                        Nov 25 '18 at 15:18



















                      • Thanks for the response. When I go to a route configured with react-router now and refresh the page, I get a whitelabel error page which I didn't get with the previous config

                        – Roberto Graham
                        Nov 24 '18 at 15:53











                      • @RobertoGraham Can you show your directory structure?

                        – Sukhpal Singh
                        Nov 25 '18 at 15:18

















                      Thanks for the response. When I go to a route configured with react-router now and refresh the page, I get a whitelabel error page which I didn't get with the previous config

                      – Roberto Graham
                      Nov 24 '18 at 15:53





                      Thanks for the response. When I go to a route configured with react-router now and refresh the page, I get a whitelabel error page which I didn't get with the previous config

                      – Roberto Graham
                      Nov 24 '18 at 15:53













                      @RobertoGraham Can you show your directory structure?

                      – Sukhpal Singh
                      Nov 25 '18 at 15:18





                      @RobertoGraham Can you show your directory structure?

                      – Sukhpal Singh
                      Nov 25 '18 at 15:18











                      0














                      Following Kotlin code might help:



                      @Configuration
                      class WebMvcConfig(val resourceProperties: ResourceProperties) : WebMvcConfigurer {

                      override fun addResourceHandlers(registry: ResourceHandlerRegistry) {
                      registry.addResourceHandler("/**")
                      .addResourceLocations(*resourceProperties.staticLocations)
                      .resourceChain(resourceProperties.chain.isCache)
                      .addResolver(FallbackPathResourceResolver())
                      }

                      private class FallbackPathResourceResolver : PathResourceResolver() {
                      override fun resolveResource(
                      request: HttpServletRequest?,
                      requestPath: String,
                      locations: MutableList<out Resource>,
                      chain: ResourceResolverChain
                      ): Resource? {
                      return super.resolveResource(request, requestPath, locations, chain) ?: super.resolveResource(
                      request,
                      "/index.html",
                      locations,
                      chain
                      )
                      }
                      }
                      }


                      Reference: https://jira.spring.io/browse/SPR-16788






                      share|improve this answer




























                        0














                        Following Kotlin code might help:



                        @Configuration
                        class WebMvcConfig(val resourceProperties: ResourceProperties) : WebMvcConfigurer {

                        override fun addResourceHandlers(registry: ResourceHandlerRegistry) {
                        registry.addResourceHandler("/**")
                        .addResourceLocations(*resourceProperties.staticLocations)
                        .resourceChain(resourceProperties.chain.isCache)
                        .addResolver(FallbackPathResourceResolver())
                        }

                        private class FallbackPathResourceResolver : PathResourceResolver() {
                        override fun resolveResource(
                        request: HttpServletRequest?,
                        requestPath: String,
                        locations: MutableList<out Resource>,
                        chain: ResourceResolverChain
                        ): Resource? {
                        return super.resolveResource(request, requestPath, locations, chain) ?: super.resolveResource(
                        request,
                        "/index.html",
                        locations,
                        chain
                        )
                        }
                        }
                        }


                        Reference: https://jira.spring.io/browse/SPR-16788






                        share|improve this answer


























                          0












                          0








                          0







                          Following Kotlin code might help:



                          @Configuration
                          class WebMvcConfig(val resourceProperties: ResourceProperties) : WebMvcConfigurer {

                          override fun addResourceHandlers(registry: ResourceHandlerRegistry) {
                          registry.addResourceHandler("/**")
                          .addResourceLocations(*resourceProperties.staticLocations)
                          .resourceChain(resourceProperties.chain.isCache)
                          .addResolver(FallbackPathResourceResolver())
                          }

                          private class FallbackPathResourceResolver : PathResourceResolver() {
                          override fun resolveResource(
                          request: HttpServletRequest?,
                          requestPath: String,
                          locations: MutableList<out Resource>,
                          chain: ResourceResolverChain
                          ): Resource? {
                          return super.resolveResource(request, requestPath, locations, chain) ?: super.resolveResource(
                          request,
                          "/index.html",
                          locations,
                          chain
                          )
                          }
                          }
                          }


                          Reference: https://jira.spring.io/browse/SPR-16788






                          share|improve this answer













                          Following Kotlin code might help:



                          @Configuration
                          class WebMvcConfig(val resourceProperties: ResourceProperties) : WebMvcConfigurer {

                          override fun addResourceHandlers(registry: ResourceHandlerRegistry) {
                          registry.addResourceHandler("/**")
                          .addResourceLocations(*resourceProperties.staticLocations)
                          .resourceChain(resourceProperties.chain.isCache)
                          .addResolver(FallbackPathResourceResolver())
                          }

                          private class FallbackPathResourceResolver : PathResourceResolver() {
                          override fun resolveResource(
                          request: HttpServletRequest?,
                          requestPath: String,
                          locations: MutableList<out Resource>,
                          chain: ResourceResolverChain
                          ): Resource? {
                          return super.resolveResource(request, requestPath, locations, chain) ?: super.resolveResource(
                          request,
                          "/index.html",
                          locations,
                          chain
                          )
                          }
                          }
                          }


                          Reference: https://jira.spring.io/browse/SPR-16788







                          share|improve this answer












                          share|improve this answer



                          share|improve this answer










                          answered Nov 27 '18 at 8:20









                          SolaSola

                          613




                          613






























                              draft saved

                              draft discarded




















































                              Thanks for contributing an answer to Stack Overflow!


                              • Please be sure to answer the question. Provide details and share your research!

                              But avoid



                              • Asking for help, clarification, or responding to other answers.

                              • Making statements based on opinion; back them up with references or personal experience.


                              To learn more, see our tips on writing great answers.




                              draft saved


                              draft discarded














                              StackExchange.ready(
                              function () {
                              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53393115%2fspring-boot-2-1-0-only-serve-index-html-if-resource-not-resolved-spa-react-rou%23new-answer', 'question_page');
                              }
                              );

                              Post as a guest















                              Required, but never shown





















































                              Required, but never shown














                              Required, but never shown












                              Required, but never shown







                              Required, but never shown

































                              Required, but never shown














                              Required, but never shown












                              Required, but never shown







                              Required, but never shown







                              Popular posts from this blog

                              android studio warns about leanback feature tag usage required on manifest while using Unity exported app?

                              SQL update select statement

                              'app-layout' is not a known element: how to share Component with different Modules