Reputation: 121
I'm trying to build an SPA backend (static content server, api) with some additional features/controls that require a flexible URL rewrite/routing/handling. These requirements are proving difficult to achieve together, despite trying the approach in some similar answers I've read through on here.
What I need to do:
So far, I have the following...
For the REST APIs:
@RestController
@RequestMapping(value="/api/**")
public class StateAPIController {
@RequestMapping(value = {"/api/method1"}, method = RequestMethod.POST)
@ResponseBody
public String method1() {
return "method1...";
}
@RequestMapping(value = {"/api/method2"}, method = RequestMethod.POST)
@ResponseBody
public String method2() {
return "method2...";
}
}
(This works fine)
For rendering static files from a specific filesystem location and mapping "/" to "/index.htm":
@Configuration
@EnableWebMvc
public class AssetServerConfig implements WebMvcConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry
.addResourceHandler("/")
.addResourceLocations("file:/some/path/index.htm");
registry
.addResourceHandler("/assets/**")
.addResourceLocations("file:/some/path/assets/");
}
@Bean
public ViewResolver viewResolver() {
UrlBasedViewResolver viewResolver = new UrlBasedViewResolver();
viewResolver.setViewClass(InternalResourceView.class);
return viewResolver;
}
}
(This works, but not sure if the best way to solve this)
To redirect/forward any other requests (outside of those reserved paths) to "/" (and therefore "/index.htm"):
@ControllerAdvice
@RequestMapping(value="/**")
public class AssetServerController {
@RequestMapping(value = {"/**/{path:[^\\.]*}", "/{path:^(?!/assets/).*}", "/{path:^(?!/api/).*}"}, method = RequestMethod.GET)
public String index() {
return "forward:/";
}
}
(This only partially works... and the main issue I need help with)
So, here, I need to exclude a list of paths (/assets/ & /api/), but this is proving difficult to get right with the regex/AntPathMatcher filter in the RequestMapping, and has both false matches (showing index.htm when it shouldn't) and misses (showing 404s when it should show index.htm).
Due to the above, I also cannot correctly serve 404s when a resource is missing under one of the reserved paths (e.g. assets).
a) what is the best way to approach this? Have I got this completely wrong? Is there a better way?
b) how do I make the regex work, as it doesn't seem to follow normal regex rules, and examples I've seen so far don't achieve my goal...
Upvotes: 2
Views: 2588
Reputation: 121
Answered here: Spring RequestMapping Regex to exclude string
Based on answer here: Spring @RequestMapping "Not Contains" Regex
Pattern that worked for excluding /assets/:
value = {"/{path:(?!.*assets).+}/**"}
Upvotes: 1