0

I'm integrating single page application into Spring Boot project. The context of the UI (SPA) is http://localhost:8080/ui/

The context of Spring Boot application itself is http://localhost:8080/. Controllers have different context that has nothing to do with UI context.

There is a case when UI changes browser address line to URL that server does not know about, but does not send request to server. After such thing, if I refresh the page, server responds with 404. However I need to return the default index.html page.

Example: I go to http://localhost:8080/ui/, UI changes this to http://localhost:8080/ui/mainpage. I refresh the page and get 404.

I have found similar question, but I would like to do it a bit differently, then answered there.

I need to return default resource (index.html) when there is a request to http://localhost:8080/ui/**, if request is made to http://localhost:8080/context1/blablabla, I would like to return 404.

After debugging and googling about this I came with next solution:


    @Configuration
    public static class WebConfig implements WebMvcConfigurer {

        @Override
        public void addResourceHandlers(ResourceHandlerRegistry registry) {
            registry
                    .addResourceHandler("/ui/**")
                    .addResourceLocations("/ui/")
                    .resourceChain(false)
                    .addResolver(new PathResourceResolver() {
                        @Override
                        protected Resource getResource(String resourcePath, Resource location) throws IOException {
                            Resource resource = super.getResource(resourcePath, location);
                            return Objects.isNull(resource) ? super.getResource("index.html", location) : resource;
                        }
                    });
        }

        @Override
        public void addViewControllers(ViewControllerRegistry registry) {
            registry.addViewController("/ui/").setViewName("index.html");
        }
    }


The approach here is to add manually PathResourceResolve and override its method getResource, so when resource is null, call for index.html resource. This way I can be sure that I return default page only when request is made to http://localhost:8080/ui/** and all other requests will return 404 as usual.

I do not think that this is the right solution, to me it looks like hack. I thought maybe resource handlers have some config like default resource, but I did not found anything about that.

My question is how to do it properly? Appreciate any suggestions.

netstalk3r
  • 1
  • 1
  • 2
  • Just use a Filter mapped to /ui/** and forwarding every GET request to /index.html. – JB Nizet Jul 06 '19 at 06:39
  • Simple forwarding every GET request will not work, because there are some resources on the same level as index.html that should be sent to UI. If checking in the Filter that resource in request path does not have extension, then redirect to index.html, that way it might work, however it looks more complicated than my solution. – netstalk3r Jul 06 '19 at 12:54
  • You might find this helpful https://stackoverflow.com/questions/38777723/how-i-create-an-error-handler-404-500-in-spring-boot-mvc – Omar.Nassar Jul 06 '19 at 17:32
  • @Omar.Nassar thanks for the link. I can create error handler for 404 status and there check the path. If it starts with /ui/ I can redirect to default index.html page. – netstalk3r Jul 06 '19 at 20:30
  • @netstalk3r glad that you solved your case. But I think this is a workaround, not the best solution to follow. So, I recommend that you catch and redirect the 404 to your customized page. – Omar.Nassar Jul 07 '19 at 11:30

0 Answers0