172

How can I map my app root http://localhost:8080/ to a static index.html? If I navigate to http://localhost:8080/index.html its works fine.

My app structure is :

dirs

My config\WebConfig.java looks like this:

@Configuration
@EnableWebMvc
@ComponentScan
public class WebConfig extends WebMvcConfigurerAdapter {

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/**").addResourceLocations("/");
        }
}

I tried to add registry.addResourceHandler("/").addResourceLocations("/index.html"); but it fails.

starball
  • 20,030
  • 7
  • 43
  • 238
Shoham
  • 7,014
  • 8
  • 40
  • 40

10 Answers10

180

It would have worked out of the box if you hadn't used @EnableWebMvc annotation. When you do that you switch off all the things that Spring Boot does for you in WebMvcAutoConfiguration. You could remove that annotation, or you could add back the view controller that you switched off:

@Override
public void addViewControllers(ViewControllerRegistry registry) {
    registry.addViewController("/").setViewName("forward:/index.html");
}
Marek J
  • 1,364
  • 8
  • 18
  • 33
Dave Syer
  • 56,583
  • 10
  • 155
  • 143
  • 1
    Thanks.. I didn't realised that... couldn't find one simple demo in their site that shows that... – Shoham Dec 10 '14 at 08:30
  • 14
    From [the reference docs](http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-spring-mvc-auto-configuration): "If you want to keep Spring Boot MVC features, and you just want to add additional MVC configuration (interceptors, formatters, view controllers etc.) you can add your own @Bean of type `WebMvcConfigurerAdapte`r, but without `@EnableWebMvc`" – Dave Syer Dec 10 '14 at 10:18
  • 1
    This will serve `index.html` at `/` . But is it possible to also make the browser actually change the url from `/` to `/index.html` ? – asmaier May 15 '15 at 09:49
  • 19
    Ok I figured it out. In case you also want to change the url from `/` to `/index.html` use `"redirect:/index.html"` instead of forward. – asmaier May 15 '15 at 10:06
  • 4
    I am not using the @EnableWebMvc annotation, and I do not get redirected to index.html. – Jelle den Burger Aug 12 '16 at 09:24
  • 1
    You might as well try **redirect:/index.html**. *forward* did not work for me. Also, if using spring-boot, you might simply want to `extends WebMvcConfigurerAdapter` from your `@Configuration` class, and override `addViewControllers`. No need to add a `@Bean` explicit. – membersound Jun 14 '17 at 10:11
  • My spring boot app root url http://host:port/contextpath was not taking me to the index.html but showed "full authentication is required". I didn't do these changes but added security.ignored="/" to make it work. My app is secured with spring security oauth2, Am I doing this right by adding root to security.ignored? – Mahesh Mar 01 '18 at 12:07
  • @DaveSyer is there a difference in declare that `addViewControllers` method through `@Configuration` + `WebMvcConfigurer`'s `addViewControllers` implementation (your approach) **vs** `@Configuration` + `@Bean` such as https://stackoverflow.com/a/31235990/3665178 ? (based in your previous comment) - Just curious when the latter would be mandatory – Manuel Jordan Jul 13 '23 at 22:49
  • @DaveSyer the content shared in your comment about the Reference Documentation does not include anymore the _you can add your own @Bean of type_ part. Why was removed that `@Bean` approach? – Manuel Jordan Jul 13 '23 at 22:53
  • It's still there (but the type changed to `WebMvcConfigurer`) – Dave Syer Jul 18 '23 at 10:00
45

An example of Dave Syer's answer and comment:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

@Configuration
public class MyWebMvcConfig {

    @Bean
    public WebMvcConfigurerAdapter forwardToIndex() {
        return new WebMvcConfigurerAdapter() {
            @Override
            public void addViewControllers(ViewControllerRegistry registry) {
                // forward requests to /admin and /user to their index.html
                registry.addViewController("/admin").setViewName(
                        "forward:/admin/index.html");
                registry.addViewController("/user").setViewName(
                        "forward:/user/index.html");
            }
        };
    }

}
Manuel Jordan
  • 15,253
  • 21
  • 95
  • 158
justin
  • 3,357
  • 1
  • 23
  • 28
35

if it is a Spring boot App.

Spring Boot automatically detects index.html in public/static/webapp folder. If you have written any controller @Requestmapping("/") it will override the default feature and it will not show the index.html unless you type localhost:8080/index.html

Krish
  • 724
  • 7
  • 17
21

If you use the latest spring-boot 2.1.6.RELEASE with a simple @RestController annotation then you do not need to do anything, just add your index.html file under the resources/static folder:

project
  ├── src
      ├── main
          └── resources
              └── static
                  └── index.html

Then hit the root URL of your app http://localhost:8080.

The solution above works out of the box with Spring and Tomcat and your HTTP request to the root / is mapped automatically to the index.html file. But if you used @EnableWebMvc annotation then you switch off that Spring Boot does for you. In this case, you have two options:

(1) remove that annotation

(2) or you could add back the view controller that you switched off

@Configuration
public class WebConfiguration implements WebMvcConfigurer {

   @Override
   public void addViewControllers(ViewControllerRegistry registry) {
       registry.addViewController("/").setViewName("forward:/index.html");
   }
   
}

Hope that it will help everyone.

zappee
  • 20,148
  • 14
  • 73
  • 129
18
@Configuration  
@EnableWebMvc  
public class WebAppConfig extends WebMvcConfigurerAdapter {  

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addRedirectViewController("/", "index.html");
    }

}
Rodrigo Ribeiro
  • 249
  • 3
  • 8
13

Update: Jan-2019

First create public folder under resources and create index.html file. Use WebMvcConfigurer instead of WebMvcConfigurerAdapter.

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebAppConfig implements WebMvcConfigurer {

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/").setViewName("forward:/index.html");
    }

}
sampathlk
  • 338
  • 2
  • 17
  • what could be wrong if this does not work? resources/public/index.html exists; java 13; spring 2.2.2; tomcat – JFFIGK Dec 18 '19 at 19:12
7

You can add a RedirectViewController like:

@Configuration
public class WebConfiguration implements WebMvcConfigurer {

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addRedirectViewController("/", "/index.html");
    }
}
ngg
  • 1,493
  • 19
  • 14
6

Inside Spring Boot, I always put the webpages inside a folder like public or webapps or views and place it inside src/main/resources directory as you can see in application.properties also.

Spring_Boot-Project-Explorer-View

and this is my application.properties:

server.port=15800
spring.mvc.view.prefix=/public/
spring.mvc.view.suffix=.html
spring.datasource.url=jdbc:mysql://localhost:3306/hibernatedb
spring.datasource.username=root
spring.datasource.password=password
spring.datasource.driver-class-name=com.mysql.jdbc.Driver

spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5InnoDBDialect
spring.jpa.hibernate.ddl-auto = update
spring.jpa.properties.hibernate.format_sql = true

logging.level.org.hibernate.SQL=DEBUG
logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE

as soon you put the url like servername:15800 and this request received by Spring Boot occupied Servlet dispatcher it will exactly search the index.html and this name will in case sensitive as the spring.mvc.view.suffix which would be html, jsp, htm etc.

Hope it would help manyone.

ArifMustafa
  • 4,617
  • 5
  • 40
  • 48
  • @ArifMustafa In recent Sprint Boot versions, I recommend to put webpages inside templates also. – ArifMustafa Apr 29 '18 at 06:23
  • Do you have references for that? I'm trying to create a react/redux frontend project with a Spring backend and I'm not sure about the best practices involved. – mike Dec 18 '18 at 14:10
5

I had the same problem. Spring boot knows where static html files are located.

  1. Add index.html into resources/static folder
  2. Then delete full controller method for root path like @RequestMapping("/") etc
  3. Run app and check http://localhost:8080 (Should work)
Yuriy K
  • 111
  • 1
  • 5
3
  1. index.html file should come under below location - src/resources/public/index.html OR src/resources/static/index.html if both location defined then which first occur index.html will call from that directory.
  2. The source code looks like -

    package com.bluestone.pms.app.boot; 
    import org.springframework.boot.Banner;
    import org.springframework.boot.Banner;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.boot.builder.SpringApplicationBuilder;
    import org.springframework.boot.web.support.SpringBootServletInitializer;
    import org.springframework.context.annotation.ComponentScan;
    
    
    
    @SpringBootApplication 
    @EnableAutoConfiguration
    @ComponentScan(basePackages = {"com.your.pkg"}) 
    public class BootApplication extends SpringBootServletInitializer {
    
    
    
    /**
     * @param args Arguments
    */
    public static void main(String[] args) {
    SpringApplication application = new SpringApplication(BootApplication.class);
    /* Setting Boot banner off default value is true */
    application.setBannerMode(Banner.Mode.OFF);
    application.run(args);
    }
    
    /**
      * @param builder a builder for the application context
      * @return the application builder
      * @see SpringApplicationBuilder
     */
     @Override
     protected SpringApplicationBuilder configure(SpringApplicationBuilder 
      builder) {
        return super.configure(builder);
       }
    }
    
Pravind Kumar
  • 809
  • 1
  • 11
  • 10