Spring single page for every url route and subroute “/a/** => /a/index.html except /a/static/**”

孤街浪徒 提交于 2019-12-11 01:33:35

问题


I'm building spring website that has react single page app under subroute and my current url structure should look like

localhost/admin/** => react app
localhost/**       => spring thymeleaf/rest/websocket app for everything else

react app mapping:
localhost/admin/static/**  => static react files
localhost/admin/**         => react index.html for everything else

Example of project resources structure:  
resources/
    admin/         <= my admin react files is here
        index.html
        static/    <= react css, js,  statics
    templates/     <= thymeleaf templates
    static/        <= theamleaf static
    ...

So i need to forward react index.html file for every url route and its subroutes. Basically single page app for everything except static files

Looks like a common task, and here is some things i have already tried:


Full working demo of project spring + react + how gradle builds project and why i can't put react files in different directory (/resources/static for example): https://github.com/varren/spring-react-example

Can't use forward:/admin/index.html for /admin/** because this will create recursion because admin/index.html is also under admin/** and have to intercept admin/static/** somehow.


Can't use addResourceHandlers in WebMvcConfigurerAdapter
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
    registry.addResourceHandler("/admin/**")
            .addResourceLocations("classpath:/admin/");
}

index.html mapped only to /admin/index.html url, and this option almost works but only if you access the react app from localhost/admin/index.html


Saw this and this and this and many other links and i also have kinda solution, but maybe there is generic option i just can't see

回答1:


Right now i'm using custom ResourceResolver to solve this

Demo: https://github.com/varren/spring-react-example

@Configuration
public class BaseWebMvcConfigurerAdapter extends WebMvcConfigurerAdapter {
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {

        ResourceResolver resolver = new AdminResourceResolver();
        registry.addResourceHandler("/admin/**")
                .resourceChain(false)
                .addResolver(resolver);


        registry.addResourceHandler("/admin/")
                .resourceChain(false)
                .addResolver(resolver);
    }


    private class AdminResourceResolver implements ResourceResolver {
        private Resource index = new ClassPathResource("/admin/index.html");

        @Override
        public Resource resolveResource(HttpServletRequest request, String requestPath, List<? extends Resource> locations, ResourceResolverChain chain) {
            return resolve(requestPath, locations);
        }

        @Override
        public String resolveUrlPath(String resourcePath, List<? extends Resource> locations, ResourceResolverChain chain) {
            Resource resolvedResource = resolve(resourcePath, locations);
            if (resolvedResource == null) {
                return null;
            }
            try {
                return resolvedResource.getURL().toString();
            } catch (IOException e) {
                return resolvedResource.getFilename();
            }
        }

        private Resource resolve(String requestPath, List<? extends Resource> locations) {

            if(requestPath == null) return null;

            if (!requestPath.startsWith("static")) {
                return index;
            }else{
                return new ClassPathResource("/admin/" + requestPath);
            }
        }
    }
}


来源:https://stackoverflow.com/questions/46000685/spring-single-page-for-every-url-route-and-subroute-a-a-index-html-exce

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!