When serving static html/css/js resources from src/main/resources/static, is there a way to have some form of url abstraction?
Precisely, I would like to remove the .html ending from the urls.
To return html static file without extension is the same as return view name from any of templates engines (jsp, theamleaf, freemarker), the thing here you do not need to run any templates processing on view file, you just return it as it is.
Add code below to your Spring configuration:
@Bean
public InternalResourceViewResolver internalResourceViewResolver() {
InternalResourceViewResolver internalResourceViewResolver = new InternalResourceViewResolver();
internalResourceViewResolver.setPrefix("pages/");
internalResourceViewResolver.setSuffix(".html");
return internalResourceViewResolver;
}
Be careful /pages folder should be inside your ResourceLocation
, that means ResourceLocation + "/pages/" + pageName.html in browser should give you desired file (if you already configured servicing of static files it will not be a problem for you to find your ResourceLocation, check method addResourceHandlers in your WebMvcConfigurer)
Now at your WebMvcConfigurer you can add:
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("index");
registry.addViewController("/admin").setViewName("admin");
registry.addViewController("/contact").setViewName("contact");
registry.addViewController("/error").setViewName("index");
}
or just use it, as you would use it in usual view resolver within MVC controller
@GetMapping("/")
public String greeting() {
return "index";
}
A request mapping that ignores all URLs that have a file extension and adds .html to URLs with no file extension.
@Controller
...
@RequestMapping("/{page:^(?!.*[.].*$).*$}")
public String requestOther(@PathVariable("page") String page) {
return "/"+page+".html";
}
...
Change the "/" to a sub directory if needed e.g. "/pages/".
You could write a custom resource resolver to add the .html suffix to requests that don't otherwise resolve. For example:
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.core.io.Resource;
import org.springframework.web.servlet.resource.AbstractResourceResolver;
import org.springframework.web.servlet.resource.ResourceResolverChain;
import java.util.List;
public class HtmlResourceResolver extends AbstractResourceResolver {
private static final String HTML_SUFFIX = ".html";
@Override
protected Resource resolveResourceInternal(HttpServletRequest request, String requestPath,
List<? extends Resource> locations, ResourceResolverChain chain) {
Resource resolved = chain.resolveResource(request, requestPath, locations);
return resolved == null ? chain.resolveResource(request, requestPath + HTML_SUFFIX, locations) : resolved;
}
@Override
protected String resolveUrlPathInternal(String resourceUrlPath, List<? extends Resource> locations,
ResourceResolverChain chain) {
return chain.resolveUrlPath(resourceUrlPath, locations);
}
}
Then you can add the resource resolver to your WebMvcConfigurer as follows:
@Bean
public WebMvcConfigurer webMvcConfigurer() {
return new WebMvcConfigurer() {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/**").addResourceLocations("classpath:/static/").resourceChain(true)
.addResolver(new HtmlResourceResolver());
WebMvcConfigurer.super.addResourceHandlers(registry);
}
};
}
http://localhost/index.htmltohttp://localhost/index?/staticdirectory?