4

I've got a spring boot app with angular on the frontend.

I'm using ui-router with html5 mode and I would like spring to render the same index.html on all unknown routes.

// Works great, but it also overrides all the resources
@RequestMapping
public String index() {
    return "index";
}

// Seems do be the same as above, but still overrides the resources
@RequestMapping("/**")
public String index() {
    return "index";
}

// Works well but not for subdirectories. since it doesn't map to those
@RequestMapping("/*")
public String index() {
    return "index";
}

So my question is how can i create a fallback mapping but that lets through the resources?

Leon Radley
  • 7,596
  • 5
  • 35
  • 54

4 Answers4

5

The simplest way I found was implementing a custom 404 page.

@Configuration
public class MvcConfig {

    @Bean
    public EmbeddedServletContainerCustomizer notFoundCustomizer(){
        return new NotFoundIndexTemplate();
    }

    private static class NotFoundIndexTemplate implements EmbeddedServletContainerCustomizer {
        @Override
        public void customize(ConfigurableEmbeddedServletContainer container) {
            container.addErrorPages(new ErrorPage(HttpStatus.NOT_FOUND, "/"));
        }
    }
}

Neil McGuigan propopes a HandlerInterceptor, but I wasn't able to understand how that would be implemented. I't would be great to see how this would be implemented, as single page applications using html5 history push state will want this behaviour. And I have not really found any best practices to this problem.

Leon Radley
  • 7,596
  • 5
  • 35
  • 54
1

Define an entry point for all the urls in your web.xml file like following:

<error-page> 
    <error-code>404</error-code>
    <location>/Error_404</location>
</error-page>

This would catch all 404 i.e page not found errors and throw /Error_404 url, catch it in your controller and push to desired place.

Darshan Lila
  • 5,772
  • 2
  • 24
  • 34
1

You could handle all of non-matched requests in 404 handler. Take a look at this, there are several options

Another thing you could do is to override DefaultAnnotationHandlerMapping, and to add a sort of catch-all controller by setting the defaultHandler property.

public void setDefaultHandler(Object defaultHandler)
Set the default handler for this handler mapping. This handler will be returned if no specific mapping was found. Default is null, indicating no default handler.

Predrag Maric
  • 23,938
  • 5
  • 52
  • 68
  • DefaultAnnotationHandlerMapping Deprecated in Spring 3.2 in favor of RequestMappingHandlerMapping. I can't find a defaultHandler in the new handler :( – Leon Radley Feb 18 '15 at 14:36
  • Actually, `defaultHandler` is defined in [AbstractHandlerMapping](http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/servlet/handler/AbstractHandlerMapping.html), which `RequestMappingHandlerMapping` also extends, so it should still work. – Predrag Maric Feb 18 '15 at 15:36
1

try to use @ExceptionHandler in your controller, change Exception.class by the class of the exception who you want to handle.

@ExceptionHandler(value = {Exception.class})
public String notFoundErrorHandler() {
  return "index";
}
tcharaf
  • 630
  • 1
  • 5
  • 11