Skip to content

Add support for customizing WebJars resource handler path pattern #31769

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -189,8 +189,9 @@ public void addResourceHandlers(ResourceHandlerRegistry registry) {
logger.debug("Default resource handling disabled");
return;
}
if (!registry.hasMappingForPattern("/webjars/**")) {
ResourceHandlerRegistration registration = registry.addResourceHandler("/webjars/**")
String webjarsPathPattern = this.webFluxProperties.getWebjarsPathPattern();
if (!registry.hasMappingForPattern(webjarsPathPattern)) {
ResourceHandlerRegistration registration = registry.addResourceHandler(webjarsPathPattern)
.addResourceLocations("classpath:/META-INF/resources/webjars/");
configureResourceCaching(registration);
customizeResourceHandlerRegistration(registration);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
* {@link ConfigurationProperties properties} for Spring WebFlux.
*
* @author Brian Clozel
* @author Vedran Pavic
* @since 2.0.0
*/
@ConfigurationProperties(prefix = "spring.webflux")
Expand All @@ -40,6 +41,11 @@ public class WebFluxProperties {
*/
private String staticPathPattern = "/**";

/**
* Path pattern used for WebJar assets.
*/
private String webjarsPathPattern = "/webjars/**";

public String getBasePath() {
return this.basePath;
}
Expand Down Expand Up @@ -76,6 +82,14 @@ public void setStaticPathPattern(String staticPathPattern) {
this.staticPathPattern = staticPathPattern;
}

public String getWebjarsPathPattern() {
return this.webjarsPathPattern;
}

public void setWebjarsPathPattern(String webjarsPathPattern) {
this.webjarsPathPattern = webjarsPathPattern;
}

public static class Format {

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,8 @@ public void addResourceHandlers(ResourceHandlerRegistry registry) {
logger.debug("Default resource handling disabled");
return;
}
addResourceHandler(registry, "/webjars/**", "classpath:/META-INF/resources/webjars/");
addResourceHandler(registry, this.mvcProperties.getWebjarsPathPattern(),
"classpath:/META-INF/resources/webjars/");
addResourceHandler(registry, this.mvcProperties.getStaticPathPattern(), (registration) -> {
registration.addResourceLocations(this.resourceProperties.getStaticLocations());
if (this.servletContext != null) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2012-2021 the original author or authors.
* Copyright 2012-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -35,6 +35,7 @@
* @author Stephane Nicoll
* @author Eddú Meléndez
* @author Brian Clozel
* @author Vedran Pavic
* @since 2.0.0
*/
@ConfigurationProperties(prefix = "spring.mvc")
Expand Down Expand Up @@ -91,6 +92,11 @@ public class WebMvcProperties {
*/
private String staticPathPattern = "/**";

/**
* Path pattern used for WebJar assets.
*/
private String webjarsPathPattern = "/webjars/**";

private final Async async = new Async();

private final Servlet servlet = new Servlet();
Expand Down Expand Up @@ -188,6 +194,14 @@ public void setStaticPathPattern(String staticPathPattern) {
this.staticPathPattern = staticPathPattern;
}

public String getWebjarsPathPattern() {
return this.webjarsPathPattern;
}

public void setWebjarsPathPattern(String webjarsPathPattern) {
this.webjarsPathPattern = webjarsPathPattern;
}

public Async getAsync() {
return this.async;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@
* @author Brian Clozel
* @author Andy Wilkinson
* @author Artsiom Yudovin
* @author Vedran Pavic
*/
class WebFluxAutoConfigurationTests {

Expand Down Expand Up @@ -186,6 +187,18 @@ void shouldMapResourcesToCustomPath() {
});
}

@Test
void shouldMapWebjarsToCustomPath() {
this.contextRunner.withPropertyValues("spring.webflux.webjars-path-pattern:/assets/**").run((context) -> {
SimpleUrlHandlerMapping hm = context.getBean("resourceHandlerMapping", SimpleUrlHandlerMapping.class);
assertThat(hm.getUrlMap().get("/assets/**")).isInstanceOf(ResourceWebHandler.class);
ResourceWebHandler webjarsHandler = (ResourceWebHandler) hm.getUrlMap().get("/assets/**");
assertThat(webjarsHandler.getLocations()).hasSize(1);
assertThat(webjarsHandler.getLocations().get(0))
.isEqualTo(new ClassPathResource("/META-INF/resources/webjars/"));
});
}

@Test
void shouldNotMapResourcesWhenDisabled() {
this.contextRunner.withPropertyValues("spring.web.resources.add-mappings:false")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@
* @author Kristine Jetzke
* @author Artsiom Yudovin
* @author Scott Frederick
* @author Vedran Pavic
*/
class WebMvcAutoConfigurationTests {

Expand Down Expand Up @@ -195,6 +196,17 @@ void customResourceHandlerMapping() {
});
}

@Test
void customWebjarsHandlerMapping() {
this.contextRunner.withPropertyValues("spring.mvc.webjars-path-pattern:/assets/**").run((context) -> {
Map<String, List<Resource>> locations = getResourceMappingLocations(context);
assertThat(locations.get("/assets/**")).hasSize(1);
assertThat(locations.get("/assets/**").get(0))
.isEqualTo(new ClassPathResource("/META-INF/resources/webjars/"));
assertThat(getResourceResolvers(context, "/assets/**")).hasSize(1);
});
}

@Test
void resourceHandlerMappingOverrideWebjars() {
this.contextRunner.withUserConfiguration(WebJars.class).run((context) -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,8 @@ If you do so, the default welcome page detection switches to your custom locatio
So, if there is an `index.html` in any of your locations on startup, it is the home page of the application.

In addition to the "`standard`" static resource locations listed earlier, a special case is made for https://www.webjars.org/[Webjars content].
Any resources with a path in `+/webjars/**+` are served from jar files if they are packaged in the Webjars format.
By default, any resources with a path in `+/webjars/**+` are served from jar files if they are packaged in the Webjars format.
The path can be customized with the configprop:spring.webflux.webjars-path-pattern[] property.

TIP: Spring WebFlux applications do not strictly depend on the servlet API, so they cannot be deployed as war files and do not use the `src/main/webapp` directory.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,8 @@ You can also customize the static resource locations by using the configprop:spr
The root servlet context path, `"/"`, is automatically added as a location as well.

In addition to the "`standard`" static resource locations mentioned earlier, a special case is made for https://www.webjars.org/[Webjars content].
Any resources with a path in `+/webjars/**+` are served from jar files if they are packaged in the Webjars format.
By default, any resources with a path in `+/webjars/**+` are served from jar files if they are packaged in the Webjars format.
The path can be customized with the configprop:spring.mvc.webjars-path-pattern[] property.

TIP: Do not use the `src/main/webapp` directory if your application is packaged as a jar.
Although this directory is a common standard, it works *only* with war packaging, and it is silently ignored by most build tools if you generate a jar.
Expand Down