问题
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