5

I've got a Spring boot application.

I'm not using @EnableWebMvc and I've got my resources in the src/main/resources/static folder. When I try to load localhost:8080/ui/ it just downloads a random file (type: octet-stream). If I directly use /ui/index.html it does work.

I'm also using a WebSecurityConfigurerAdapter, but this does not seem to be the cause of problem.

Has anyone encountered this before? I would like it to load the index.html file when I request localhost:8080/ui/

What I see when I load /ui/

How I start my application:

package my.package;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;

//@EnableWebMvc //Breaks js resource loading
@SpringBootApplication
@EnableJpaRepositories
@EnableZuulProxy
public class MyApplication {

    public static void main(String[] args) {
        SpringApplication.run(MyApplication.class, args);
    }
}

My pom.xml file

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

    <groupId>nl.jaarsma</groupId>
    <artifactId>my-application</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>my-application</name>
    <description>Example app</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.9.RELEASE</version>
        <relativePath /> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Dalston.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-zuul</artifactId>
        </dependency>
<!--        <dependency> -->
<!--            <groupId>org.springframework.boot</groupId> -->
<!--            <artifactId>spring-boot-starter-actuator</artifactId> -->
<!--        </dependency> -->

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-rest</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <!-- <scope>runtime</scope> -->
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-collections4</artifactId>
            <version>4.1</version>
        </dependency>

        <dependency>
            <groupId>commons-codec</groupId>
            <artifactId>commons-codec</artifactId>
            <version>1.6</version>
        </dependency>


<!--        <dependency> -->
<!--            <groupId>org.springframework.boot</groupId> -->
<!--            <artifactId>spring-boot-starter-thymeleaf</artifactId> -->
<!--        </dependency> -->

<!--        <dependency> -->
<!--            <groupId>org.springframework.boot</groupId> -->
<!--            <artifactId>spring-boot-starter-test</artifactId> -->
<!--            <scope>test</scope> -->
<!--        </dependency> -->
<!--        <dependency> -->
<!--            <groupId>org.springframework.security</groupId> -->
<!--            <artifactId>spring-security-test</artifactId> -->
<!--            <scope>test</scope> -->
<!--        </dependency> -->

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>


    <profiles>
        <profile>
            <id>include-ui</id>
            <build>
            <plugins>
                <plugin>
                    <groupId>com.github.eirslett</groupId>
                    <artifactId>frontend-maven-plugin</artifactId>

                    <configuration>
                        <workingDirectory>ui</workingDirectory>
                    </configuration>
                    <executions>
                        <execution>
                            <id>install node and npm</id>
                            <goals>
                                <goal>install-node-and-npm</goal>
                            </goals>
                            <configuration>
                                <nodeVersion>v6.11.1</nodeVersion>
                                <npmVersion>3.10.10</npmVersion>
                            </configuration>
                        </execution>

                        <execution>
                            <id>npm install</id>
                            <goals>
                                <goal>npm</goal>
                            </goals>
                            <configuration>
                                <arguments>install</arguments>
                            </configuration>
                        </execution>

                        <execution>
                            <id>npm run build</id>
                            <goals>
                                <goal>npm</goal>
                            </goals>
                            <configuration>
                                <arguments>run build</arguments>
                            </configuration>
                        </execution>

                    </executions>
                </plugin>
            </plugins>

                <resources>
                    <resource>
                        <directory>src/main/resources</directory>
                    </resource>
                    <resource>
                        <filtering>false</filtering>
                        <directory>ui/dist</directory>
                        <includes>
                            <include>**</include>
                        </includes>
                        <targetPath>static/ui</targetPath>
                    </resource>
                </resources>
            </build>
        </profile>
    </profiles>
</project>
12
  • Any specific reason for not using @EnableWebMvc? Commented Jun 1, 2018 at 18:56
  • @Vasan Because it also seemed to break resource loading. Maybe there is a solution using WebMVC that works? Commented Jun 1, 2018 at 18:58
  • Try having an empty class marked with @Controller Commented Jun 1, 2018 at 19:11
  • Unfortunately that does not work. Commented Jun 1, 2018 at 20:25
  • without seeing your source code, how would we know what's the issue? Commented Jun 1, 2018 at 21:14

4 Answers 4

5

Spring Boot will automatically add static web resources located within any of the following directories: Link

/META-INF/resources/
/resources/
/static/
/public/

By default Spring Boot serves static content from resources in the classpath at "/static" (or "/public").

The index.html resource is special because it is used as a "welcome page" if it exists, which means it will be served up as the root resource, i.e. at http://localhost:8080/ in our example. Link

for your case you need to tell spring location of your index.html

public class MyApplication {


    @Bean
    WebMvcConfigurer configurer () {
        return new WebMvcConfigurerAdapter() {
            @Override
            public void addResourceHandlers (ResourceHandlerRegistry registry) {
                registry.addResourceHandler("/ui/").
                          addResourceLocations("classpath:/static/ui/index.html");
            }
        };
    }


    public static void main(String[] args) {
        SpringApplication.run(MyApplication.class, args);
    }
}
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for the answer, unfortunately this gives me a 404 when I try to load /ui/. Weird thing is, if I deploy my UI on the root: / instead of /ui/ it works just fine.
2

Since you are placing your static resources in the '/static/ui' you have to inform Spring Boot of this.

@Configuration
public class WebMvcConfig  extends WebMvcConfigurerAdapter {

@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
    registry.setOrder(-1)
        .addResourceHandler("/index.html")
        .addResourceLocations("classpath:/static/ui/");
    super.addResourceHandlers(registry);
}

If there are other files in /static/ui then you can use wildcards /**. See the Spring Blog for more details: https://spring.io/blog/2013/12/19/serving-static-web-content-with-spring-boot

2 Comments

Personally, if there is a real business reason for not using the defaults, I would have the build process put the files in /static and save yourself the headache.
Thanks for the answer. Unfortunately this also didn't work (404). I also tried changing /index.html to /ui/index.html. I currently have solved this by putting my static resources directly in the resources folder, as you said in your comment.
1

Why not have a controller that maps /ui to index.html?

@Controller
public class HomeController {

    @RequestMapping("/ui")
    public String home(Model model) {
         return "index.html";
    }
}

Also, you may need to check this link to enable it without @EnableWebMVC

Comments

1

following this url https://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html

you can add static file pattern in application.properties without extra code.

spring.mvc.static-path-pattern=/** # Path pattern used for static resources.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.