Two choices are available to users for welcome page
* For a jar deployment add classpath:static/index.html (works via Spring MVC mapping) * For a war the same thing works, but so does adding index.html to src/main/webapp (works via container default servlet) [Fixes #54092261] [bs-252]
This commit is contained in:
@@ -38,6 +38,7 @@ import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.core.convert.converter.GenericConverter;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.ResourceLoader;
|
||||
import org.springframework.format.Formatter;
|
||||
import org.springframework.format.FormatterRegistry;
|
||||
import org.springframework.web.accept.ContentNegotiationManager;
|
||||
@@ -48,6 +49,7 @@ import org.springframework.web.servlet.View;
|
||||
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
|
||||
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
|
||||
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
|
||||
import org.springframework.web.servlet.handler.SimpleUrlHandlerMapping;
|
||||
import org.springframework.web.servlet.resource.ResourceHttpRequestHandler;
|
||||
@@ -76,6 +78,9 @@ public class WebMvcAutoConfiguration {
|
||||
@Autowired
|
||||
private ListableBeanFactory beanFactory;
|
||||
|
||||
@Autowired
|
||||
private ResourceLoader resourceLoader;
|
||||
|
||||
@ConditionalOnBean(View.class)
|
||||
@Bean
|
||||
public BeanNameViewResolver beanNameViewResolver() {
|
||||
@@ -128,6 +133,22 @@ public class WebMvcAutoConfiguration {
|
||||
"classpath:/static/", "classpath:/public/");
|
||||
}
|
||||
|
||||
// Special case for static home page
|
||||
@Override
|
||||
public void addViewControllers(ViewControllerRegistry registry) {
|
||||
if (this.resourceLoader.getResource("classpath:/static/index.html").exists()) {
|
||||
registry.addViewController("/").setViewName("/index.html");
|
||||
}
|
||||
else if (this.resourceLoader.getResource("classpath:/public/index.html")
|
||||
.exists()) {
|
||||
registry.addViewController("/").setViewName("/index.html");
|
||||
}
|
||||
else if (this.resourceLoader.getResource("classpath:/resources/index.html")
|
||||
.exists()) {
|
||||
registry.addViewController("/").setViewName("/index.html");
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
public static class FaviconConfiguration {
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
<module>spring-boot-sample-simple</module>
|
||||
<module>spring-boot-sample-tomcat</module>
|
||||
<module>spring-boot-sample-traditional</module>
|
||||
<module>spring-boot-sample-web-static</module>
|
||||
<module>spring-boot-sample-web-ui</module>
|
||||
<module>spring-boot-sample-xml</module>
|
||||
</modules>
|
||||
@@ -42,6 +43,13 @@
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-war-plugin</artifactId>
|
||||
<version>2.3</version>
|
||||
<configuration>
|
||||
<failOnMissingWebXml>false</failOnMissingWebXml>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
</build>
|
||||
|
||||
36
spring-boot-samples/spring-boot-sample-web-static/pom.xml
Normal file
36
spring-boot-samples/spring-boot-sample-web-static/pom.xml
Normal file
@@ -0,0 +1,36 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-samples</artifactId>
|
||||
<version>0.5.0.BUILD-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>spring-boot-sample-web-static</artifactId>
|
||||
<packaging>war</packaging>
|
||||
<properties>
|
||||
<main.basedir>${basedir}/../..</main.basedir>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>spring-boot-up-web</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>spring-boot-up-tomcat</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 2013 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.sample.ui;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Configuration
|
||||
@EnableAutoConfiguration
|
||||
@ComponentScan
|
||||
public class SampleWebStaticApplication {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
SpringApplication.run(SampleWebStaticApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 2.8 KiB |
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration>
|
||||
|
||||
<include resource="org/springframework/boot/logging/logback/base.xml"/>
|
||||
<logger name="org.springframework" level="DEBUG"/>
|
||||
|
||||
</configuration>
|
||||
11
spring-boot-samples/spring-boot-sample-web-static/src/main/webapp/css/bootstrap.min.css
vendored
Normal file
11
spring-boot-samples/spring-boot-sample-web-static/src/main/webapp/css/bootstrap.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
@@ -0,0 +1,30 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Static</title>
|
||||
<link rel="stylesheet" href="/css/bootstrap.min.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="navbar">
|
||||
<div class="navbar-inner">
|
||||
<a class="brand"
|
||||
href="https://github.com/SpringSource/spring-boot">
|
||||
Spring Boot
|
||||
</a>
|
||||
<ul class="nav">
|
||||
<li>
|
||||
<a href="/">
|
||||
Home
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<h1>Home</h1>
|
||||
<div>
|
||||
Some static content
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,84 @@
|
||||
package org.springframework.boot.sample.ui;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.http.client.ClientHttpResponse;
|
||||
import org.springframework.web.client.DefaultResponseErrorHandler;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* Basic integration tests for demo application.
|
||||
*
|
||||
* @author Dave Syer
|
||||
*/
|
||||
public class SampleWebStaticApplicationTests {
|
||||
|
||||
private static ConfigurableApplicationContext context;
|
||||
|
||||
@BeforeClass
|
||||
public static void start() throws Exception {
|
||||
Future<ConfigurableApplicationContext> future = Executors
|
||||
.newSingleThreadExecutor().submit(
|
||||
new Callable<ConfigurableApplicationContext>() {
|
||||
@Override
|
||||
public ConfigurableApplicationContext call() throws Exception {
|
||||
return (ConfigurableApplicationContext) SpringApplication
|
||||
.run(SampleWebStaticApplication.class);
|
||||
}
|
||||
});
|
||||
context = future.get(30, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void stop() {
|
||||
if (context != null) {
|
||||
context.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHome() throws Exception {
|
||||
ResponseEntity<String> entity = getRestTemplate().getForEntity(
|
||||
"http://localhost:8080", String.class);
|
||||
assertEquals(HttpStatus.OK, entity.getStatusCode());
|
||||
assertTrue("Wrong body (title doesn't match):\n" + entity.getBody(), entity
|
||||
.getBody().contains("<title>Static"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCss() throws Exception {
|
||||
ResponseEntity<String> entity = getRestTemplate().getForEntity(
|
||||
"http://localhost:8080/resources/css/bootstrap.min.css", String.class);
|
||||
assertEquals(HttpStatus.OK, entity.getStatusCode());
|
||||
assertTrue("Wrong body:\n" + entity.getBody(), entity.getBody().contains("body"));
|
||||
assertEquals("Wrong content type:\n" + entity.getHeaders().getContentType(),
|
||||
MediaType.valueOf("text/css"), entity.getHeaders().getContentType());
|
||||
}
|
||||
|
||||
private RestTemplate getRestTemplate() {
|
||||
RestTemplate restTemplate = new RestTemplate();
|
||||
restTemplate.setErrorHandler(new DefaultResponseErrorHandler() {
|
||||
@Override
|
||||
public void handleError(ClientHttpResponse response) throws IOException {
|
||||
}
|
||||
});
|
||||
return restTemplate;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -310,18 +310,28 @@ public abstract class AbstractEmbeddedServletContainerFactory implements
|
||||
+ Arrays.asList(COMMON_DOC_ROOTS)
|
||||
+ " point to a directory and will be ignored.");
|
||||
}
|
||||
else if (this.logger.isDebugEnabled()) {
|
||||
this.logger.debug("Document root: " + file);
|
||||
}
|
||||
return file;
|
||||
}
|
||||
|
||||
private File getWarFileDocumentRoot() {
|
||||
File warFile = getCodeSourceArchive();
|
||||
if (warFile.exists() && !warFile.isDirectory()
|
||||
&& warFile.getName().toLowerCase().endsWith(".war")) {
|
||||
return warFile.getAbsoluteFile();
|
||||
private File getArchiveFileDocumentRoot(String extension) {
|
||||
File file = getCodeSourceArchive();
|
||||
if (this.logger.isDebugEnabled()) {
|
||||
this.logger.debug("Code archive: " + file);
|
||||
}
|
||||
if (file.exists() && !file.isDirectory()
|
||||
&& file.getName().toLowerCase().endsWith(extension)) {
|
||||
return file.getAbsoluteFile();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private File getWarFileDocumentRoot() {
|
||||
return getArchiveFileDocumentRoot(".war");
|
||||
}
|
||||
|
||||
private File getCommonDocumentRoot() {
|
||||
for (String commonDocRoot : COMMON_DOC_ROOTS) {
|
||||
File root = new File(commonDocRoot);
|
||||
|
||||
@@ -120,6 +120,7 @@ public class JettyEmbeddedServletContainerFactory extends
|
||||
ServletContextInitializer[] initializersToUse = mergeInitializers(initializers);
|
||||
Configuration[] configurations = getWebAppContextConfigurations(context,
|
||||
initializersToUse);
|
||||
context.setWelcomeFiles(new String[] { "index.html" });
|
||||
context.setConfigurations(configurations);
|
||||
context.getSessionHandler().getSessionManager()
|
||||
.setMaxInactiveInterval(getSessionTimeout());
|
||||
|
||||
@@ -139,6 +139,7 @@ public class TomcatEmbeddedServletContainerFactory extends
|
||||
File docBase = getValidDocumentRoot();
|
||||
docBase = (docBase != null ? docBase : createTempDir("tomcat-docbase"));
|
||||
Context context = new StandardContext();
|
||||
context.addWelcomeFile("index.html");
|
||||
context.setName(getContextPath());
|
||||
context.setPath(getContextPath());
|
||||
context.setDocBase(docBase.getAbsolutePath());
|
||||
|
||||
Reference in New Issue
Block a user