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]
pull/9/head
Dave Syer 11 years ago
parent af798a2741
commit 4c359e1a4d

@ -38,6 +38,7 @@ import org.springframework.core.convert.converter.Converter;
import org.springframework.core.convert.converter.GenericConverter; import org.springframework.core.convert.converter.GenericConverter;
import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource; import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.format.Formatter; import org.springframework.format.Formatter;
import org.springframework.format.FormatterRegistry; import org.springframework.format.FormatterRegistry;
import org.springframework.web.accept.ContentNegotiationManager; 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.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; 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.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.handler.SimpleUrlHandlerMapping; import org.springframework.web.servlet.handler.SimpleUrlHandlerMapping;
import org.springframework.web.servlet.resource.ResourceHttpRequestHandler; import org.springframework.web.servlet.resource.ResourceHttpRequestHandler;
@ -76,6 +78,9 @@ public class WebMvcAutoConfiguration {
@Autowired @Autowired
private ListableBeanFactory beanFactory; private ListableBeanFactory beanFactory;
@Autowired
private ResourceLoader resourceLoader;
@ConditionalOnBean(View.class) @ConditionalOnBean(View.class)
@Bean @Bean
public BeanNameViewResolver beanNameViewResolver() { public BeanNameViewResolver beanNameViewResolver() {
@ -128,6 +133,22 @@ public class WebMvcAutoConfiguration {
"classpath:/static/", "classpath:/public/"); "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 @Configuration
public static class FaviconConfiguration { public static class FaviconConfiguration {

@ -23,6 +23,7 @@
<module>spring-boot-sample-simple</module> <module>spring-boot-sample-simple</module>
<module>spring-boot-sample-tomcat</module> <module>spring-boot-sample-tomcat</module>
<module>spring-boot-sample-traditional</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-web-ui</module>
<module>spring-boot-sample-xml</module> <module>spring-boot-sample-xml</module>
</modules> </modules>
@ -42,6 +43,13 @@
</execution> </execution>
</executions> </executions>
</plugin> </plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.3</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
</plugins> </plugins>
</pluginManagement> </pluginManagement>
</build> </build>

@ -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>

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) + Arrays.asList(COMMON_DOC_ROOTS)
+ " point to a directory and will be ignored."); + " point to a directory and will be ignored.");
} }
else if (this.logger.isDebugEnabled()) {
this.logger.debug("Document root: " + file);
}
return file; return file;
} }
private File getWarFileDocumentRoot() { private File getArchiveFileDocumentRoot(String extension) {
File warFile = getCodeSourceArchive(); File file = getCodeSourceArchive();
if (warFile.exists() && !warFile.isDirectory() if (this.logger.isDebugEnabled()) {
&& warFile.getName().toLowerCase().endsWith(".war")) { this.logger.debug("Code archive: " + file);
return warFile.getAbsoluteFile(); }
if (file.exists() && !file.isDirectory()
&& file.getName().toLowerCase().endsWith(extension)) {
return file.getAbsoluteFile();
} }
return null; return null;
} }
private File getWarFileDocumentRoot() {
return getArchiveFileDocumentRoot(".war");
}
private File getCommonDocumentRoot() { private File getCommonDocumentRoot() {
for (String commonDocRoot : COMMON_DOC_ROOTS) { for (String commonDocRoot : COMMON_DOC_ROOTS) {
File root = new File(commonDocRoot); File root = new File(commonDocRoot);

@ -120,6 +120,7 @@ public class JettyEmbeddedServletContainerFactory extends
ServletContextInitializer[] initializersToUse = mergeInitializers(initializers); ServletContextInitializer[] initializersToUse = mergeInitializers(initializers);
Configuration[] configurations = getWebAppContextConfigurations(context, Configuration[] configurations = getWebAppContextConfigurations(context,
initializersToUse); initializersToUse);
context.setWelcomeFiles(new String[] { "index.html" });
context.setConfigurations(configurations); context.setConfigurations(configurations);
context.getSessionHandler().getSessionManager() context.getSessionHandler().getSessionManager()
.setMaxInactiveInterval(getSessionTimeout()); .setMaxInactiveInterval(getSessionTimeout());

@ -139,6 +139,7 @@ public class TomcatEmbeddedServletContainerFactory extends
File docBase = getValidDocumentRoot(); File docBase = getValidDocumentRoot();
docBase = (docBase != null ? docBase : createTempDir("tomcat-docbase")); docBase = (docBase != null ? docBase : createTempDir("tomcat-docbase"));
Context context = new StandardContext(); Context context = new StandardContext();
context.addWelcomeFile("index.html");
context.setName(getContextPath()); context.setName(getContextPath());
context.setPath(getContextPath()); context.setPath(getContextPath());
context.setDocBase(docBase.getAbsolutePath()); context.setDocBase(docBase.getAbsolutePath());

Loading…
Cancel
Save