Skip to content

Commit f7f858b

Browse files
committed
Merge branch '2.1.x'
Closes gh-17759
2 parents c718a79 + 5f33643 commit f7f858b

File tree

4 files changed

+134
-41
lines changed

4 files changed

+134
-41
lines changed

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/WebMvcAutoConfiguration.java

Lines changed: 49 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -160,13 +160,20 @@ public OrderedFormContentFilter formContentFilter() {
160160
return new OrderedFormContentFilter();
161161
}
162162

163+
static String[] getResourceLocations(String[] staticLocations) {
164+
String[] locations = new String[staticLocations.length + SERVLET_LOCATIONS.length];
165+
System.arraycopy(staticLocations, 0, locations, 0, staticLocations.length);
166+
System.arraycopy(SERVLET_LOCATIONS, 0, locations, staticLocations.length, SERVLET_LOCATIONS.length);
167+
return locations;
168+
}
169+
163170
// Defined as a nested config to ensure WebMvcConfigurer is not read when not
164171
// on the classpath
165172
@Configuration(proxyBeanMethods = false)
166173
@Import(EnableWebMvcConfiguration.class)
167174
@EnableConfigurationProperties({ WebMvcProperties.class, ResourceProperties.class })
168175
@Order(0)
169-
public static class WebMvcAutoConfigurationAdapter implements WebMvcConfigurer, ResourceLoaderAware {
176+
public static class WebMvcAutoConfigurationAdapter implements WebMvcConfigurer {
170177

171178
private static final Log logger = LogFactory.getLog(WebMvcConfigurer.class);
172179

@@ -180,8 +187,6 @@ public static class WebMvcAutoConfigurationAdapter implements WebMvcConfigurer,
180187

181188
final ResourceHandlerRegistrationCustomizer resourceHandlerRegistrationCustomizer;
182189

183-
private ResourceLoader resourceLoader;
184-
185190
public WebMvcAutoConfigurationAdapter(ResourceProperties resourceProperties, WebMvcProperties mvcProperties,
186191
ListableBeanFactory beanFactory, ObjectProvider<HttpMessageConverters> messageConvertersProvider,
187192
ObjectProvider<ResourceHandlerRegistrationCustomizer> resourceHandlerRegistrationCustomizerProvider) {
@@ -192,11 +197,6 @@ public WebMvcAutoConfigurationAdapter(ResourceProperties resourceProperties, Web
192197
this.resourceHandlerRegistrationCustomizer = resourceHandlerRegistrationCustomizerProvider.getIfAvailable();
193198
}
194199

195-
@Override
196-
public void setResourceLoader(ResourceLoader resourceLoader) {
197-
this.resourceLoader = resourceLoader;
198-
}
199-
200200
@Override
201201
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
202202
this.messageConvertersProvider
@@ -319,37 +319,6 @@ private Integer getSeconds(Duration cachePeriod) {
319319
return (cachePeriod != null) ? (int) cachePeriod.getSeconds() : null;
320320
}
321321

322-
@Bean
323-
public WelcomePageHandlerMapping welcomePageHandlerMapping(ApplicationContext applicationContext) {
324-
return new WelcomePageHandlerMapping(new TemplateAvailabilityProviders(applicationContext),
325-
applicationContext, getWelcomePage(), this.mvcProperties.getStaticPathPattern());
326-
}
327-
328-
static String[] getResourceLocations(String[] staticLocations) {
329-
String[] locations = new String[staticLocations.length + SERVLET_LOCATIONS.length];
330-
System.arraycopy(staticLocations, 0, locations, 0, staticLocations.length);
331-
System.arraycopy(SERVLET_LOCATIONS, 0, locations, staticLocations.length, SERVLET_LOCATIONS.length);
332-
return locations;
333-
}
334-
335-
private Optional<Resource> getWelcomePage() {
336-
String[] locations = getResourceLocations(this.resourceProperties.getStaticLocations());
337-
return Arrays.stream(locations).map(this::getIndexHtml).filter(this::isReadable).findFirst();
338-
}
339-
340-
private Resource getIndexHtml(String location) {
341-
return this.resourceLoader.getResource(location + "index.html");
342-
}
343-
344-
private boolean isReadable(Resource resource) {
345-
try {
346-
return resource.exists() && (resource.getURL() != null);
347-
}
348-
catch (Exception ex) {
349-
return false;
350-
}
351-
}
352-
353322
private void customizeResourceHandlerRegistration(ResourceHandlerRegistration registration) {
354323
if (this.resourceHandlerRegistrationCustomizer != null) {
355324
this.resourceHandlerRegistrationCustomizer.customize(registration);
@@ -382,16 +351,22 @@ public void addResourceHandlers(ResourceHandlerRegistry registry) {
382351
* Configuration equivalent to {@code @EnableWebMvc}.
383352
*/
384353
@Configuration(proxyBeanMethods = false)
385-
public static class EnableWebMvcConfiguration extends DelegatingWebMvcConfiguration {
354+
public static class EnableWebMvcConfiguration extends DelegatingWebMvcConfiguration implements ResourceLoaderAware {
355+
356+
private final ResourceProperties resourceProperties;
386357

387358
private final WebMvcProperties mvcProperties;
388359

389360
private final ListableBeanFactory beanFactory;
390361

391362
private final WebMvcRegistrations mvcRegistrations;
392363

393-
public EnableWebMvcConfiguration(ObjectProvider<WebMvcProperties> mvcPropertiesProvider,
364+
private ResourceLoader resourceLoader;
365+
366+
public EnableWebMvcConfiguration(ResourceProperties resourceProperties,
367+
ObjectProvider<WebMvcProperties> mvcPropertiesProvider,
394368
ObjectProvider<WebMvcRegistrations> mvcRegistrationsProvider, ListableBeanFactory beanFactory) {
369+
this.resourceProperties = resourceProperties;
395370
this.mvcProperties = mvcPropertiesProvider.getIfAvailable();
396371
this.mvcRegistrations = mvcRegistrationsProvider.getIfUnique();
397372
this.beanFactory = beanFactory;
@@ -428,6 +403,34 @@ public RequestMappingHandlerMapping requestMappingHandlerMapping(
428403
mvcResourceUrlProvider);
429404
}
430405

406+
@Bean
407+
public WelcomePageHandlerMapping welcomePageHandlerMapping(ApplicationContext applicationContext,
408+
FormattingConversionService mvcConversionService, ResourceUrlProvider mvcResourceUrlProvider) {
409+
WelcomePageHandlerMapping welcomePageHandlerMapping = new WelcomePageHandlerMapping(
410+
new TemplateAvailabilityProviders(applicationContext), applicationContext, getWelcomePage(),
411+
this.mvcProperties.getStaticPathPattern());
412+
welcomePageHandlerMapping.setInterceptors(getInterceptors(mvcConversionService, mvcResourceUrlProvider));
413+
return welcomePageHandlerMapping;
414+
}
415+
416+
private Optional<Resource> getWelcomePage() {
417+
String[] locations = getResourceLocations(this.resourceProperties.getStaticLocations());
418+
return Arrays.stream(locations).map(this::getIndexHtml).filter(this::isReadable).findFirst();
419+
}
420+
421+
private Resource getIndexHtml(String location) {
422+
return this.resourceLoader.getResource(location + "index.html");
423+
}
424+
425+
private boolean isReadable(Resource resource) {
426+
try {
427+
return resource.exists() && (resource.getURL() != null);
428+
}
429+
catch (Exception ex) {
430+
return false;
431+
}
432+
}
433+
431434
@Bean
432435
@Override
433436
public FormattingConversionService mvcConversionService() {
@@ -499,6 +502,11 @@ public ContentNegotiationManager mvcContentNegotiationManager() {
499502
return manager;
500503
}
501504

505+
@Override
506+
public void setResourceLoader(ResourceLoader resourceLoader) {
507+
this.resourceLoader = resourceLoader;
508+
}
509+
502510
}
503511

504512
@Configuration(proxyBeanMethods = false)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
/*
2+
* Copyright 2012-2019 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.boot.autoconfigure.web.servlet;
18+
19+
import java.net.URI;
20+
21+
import org.junit.jupiter.api.Test;
22+
23+
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
24+
import org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration;
25+
import org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration;
26+
import org.springframework.boot.builder.SpringApplicationBuilder;
27+
import org.springframework.boot.test.context.SpringBootTest;
28+
import org.springframework.boot.test.web.client.TestRestTemplate;
29+
import org.springframework.boot.web.server.LocalServerPort;
30+
import org.springframework.context.annotation.Configuration;
31+
import org.springframework.context.annotation.Import;
32+
import org.springframework.http.MediaType;
33+
import org.springframework.http.RequestEntity;
34+
import org.springframework.http.ResponseEntity;
35+
36+
import static org.assertj.core.api.Assertions.assertThat;
37+
38+
/**
39+
* Integration tests for the welcome page.
40+
*
41+
* @author Madhura Bhave
42+
*/
43+
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
44+
properties = { "spring.resources.chain.strategy.content.enabled=true",
45+
"spring.thymeleaf.prefix=classpath:/templates/thymeleaf/" })
46+
class WelcomePageIntegrationTests {
47+
48+
@LocalServerPort
49+
private int port;
50+
51+
private TestRestTemplate template = new TestRestTemplate();
52+
53+
@Test
54+
void contentStrategyWithWelcomePage() throws Exception {
55+
RequestEntity<?> entity = RequestEntity.get(new URI("http://localhost:" + this.port + "/"))
56+
.header("Accept", MediaType.ALL.toString()).build();
57+
ResponseEntity<String> content = this.template.exchange(entity, String.class);
58+
assertThat(content.getBody()).contains("/custom-");
59+
}
60+
61+
@Configuration
62+
@Import({ PropertyPlaceholderAutoConfiguration.class, WebMvcAutoConfiguration.class,
63+
HttpMessageConvertersAutoConfiguration.class, ServletWebServerFactoryAutoConfiguration.class,
64+
DispatcherServletAutoConfiguration.class, ThymeleafAutoConfiguration.class })
65+
static class TestConfiguration {
66+
67+
static void main(String[] args) {
68+
new SpringApplicationBuilder(TestConfiguration.class).run(args);
69+
}
70+
71+
}
72+
73+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
2+
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<!doctype html>
2+
<html xmlns:th="https://www.thymeleaf.org">
3+
<head>
4+
<title>Test Thymeleaf</title>
5+
<link th:href="@{/custom.css}" rel="stylesheet" />
6+
</head>
7+
<body>
8+
9+
</body>
10+
</html>

0 commit comments

Comments
 (0)