Search code examples
springspring-boothttp-redirectvue.jshttp-status-code-404

Vue.JS & Spring Boot - Redirect to homepage on 404


I am building a Vue.JS & Spring Boot app which I am running through a docker container. The dist folder for Vue is copied to resources/public path and served through the Spring Boot service.

I have set up routes using vue router, but all of these routes return 404 - Not found when entered directly into the browser (but work fine when accesses through the Vue app).

The vue router:

export default new Router({
  mode: 'history',
  routes: [{
      path: '/',
      name: 'home',
      component: Home
    },
    {
      path: '/result',
      name: 'result',
      component: Result,
      props: true
    },
    {
      path: '/result/:userid',
      name: 'autoResult',
      component: Result,
      props: true
    }
  ]
})

I need the /result/userid to not return a 404 - instead it should get the userid & render the result page. Is this possible to get to work?

Another thing I want to do is to redirect all 404-pages that are not mapped to any api / vue page to return to the start page. I have tried using the spring boot implements ErrorController but I cannot get the redirect to work.

Edit:

I tried adding the following Controller Advice:

@ControllerAdvice
public class WebConfig {

    @ExceptionHandler(NoHandlerFoundException.class)
    public String renderDefaultPage(NoHandlerFoundException e) {
        return "classpath:public/index.html";
    }

}

And the following properties:

spring.mvc.throw-exception-if-no-handler-found=true
spring.resources.add-mappings=false
spring.mvc.static-path-pattern=/static/**
spring.resources.static-locations=classpath:public/static/

But when I try to access the frontpage now (or any other URL) i get the stackOverflowException and the server starts doing an infinite loop saying this:

2019-03-05 13:26:24.298  WARN 22044 --- [nio-8080-exec-1] o.s.web.servlet.PageNotFound             : No mapping for GET /classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/classpath:public/index.html

Solution

  • Solved with the following code:

    @Controller
    public class RoutesController implements ErrorController {
        private static final String PATH = "/error";
    
        @RequestMapping(value = PATH)
        public String error() {
            return "forward:/";
        }
    
        @Override
        public String getErrorPath() {
            return PATH;
        }
    }