首页 文章

运行jar时,带有静态内容的Spring Boot项目会生成404

提问于
浏览
22

Spring最近关于在Spring Boot项目中使用静态Web内容的博客文章(https://spring.io/blog/2013/12/19/serving-static-web-content-with-spring-boot)表明可以使用多个资源目录:

  • / META-INF /资源/

  • / resources /

  • / static /

  • / public /

这要归功于WebMvcAutoConfiguration类,它自动将这些目录添加到类路径中 . 这一切似乎都很好,并且在使用 spring-boot-maven-plugin spring-boot:run 目标时似乎有效,所有静态内容都在工作(例如:/index.html) .

打包Spring Boot项目并允许 spring-boot-maven-plugin 创建增强型JAR然后尝试使用 java -jar my-spring-boot-project.jar 运行项目时,您会发现静态内容现在返回404错误 .

6 回答

  • 0

    我正在撞墙,试图找出如何用gradle做到这一点 . 有小费吗?

    编辑:我通过将其添加到我的build.gradle中来实现它:

    // Copy resources into the jar as static content, where Spring expects it.
    jar.into('static') {
        from('src/main/webapp')
    }
    
  • 6

    Spring Boot将使用 WebMvcAutoConfiguration 来配置静态内容,这个类只会在你没有自定义 WebMvcConfigurationSupport bean时生效,在我的情况下,我确实有一个 .

    @Configuration
    @ConditionalOnWebApplication
    @ConditionalOnClass({ Servlet.class, DispatcherServlet.class,
            WebMvcConfigurerAdapter.class })
    @ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
    @AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10)
    @AutoConfigureAfter({ DispatcherServletAutoConfiguration.class,
            ValidationAutoConfiguration.class })
        public class WebMvcAutoConfiguration {
    
    }
    

    所以我只需要自己配置,这是我的解决方案:

    @Override
    protected void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/static-file/**").addResourceLocations("classpath:/static/");
    }
    
  • 34

    有两件事需要考虑(Spring Boot v1.5.2.RELEASE) -

    1)检查@EnableWebMvc注释的所有Controller类,如果有则删除它

    2)检查使用了注释的Controller类 - @RestController或@Controller .

    不要在一个类中混合使用Rest API和MVC行为 . 对于MVC,使用@Controller和REST API使用@RestController

    Doing above 2 things resolved my issue. Now my spring boot is loading static resources with out any issues.
    @Controller => load index.html => loads static files.
    
    @Controller
    public class WelcomeController {
    
        // inject via application.properties
        @Value("${welcome.message:Hello}")
        private String message = "Hello World";
    
        @RequestMapping("/welcome")
        public String welcome(Map<String, Object> model) {
            model.put("message", this.message);
            return "welcome";
        }
    
        @RequestMapping("/")
        public String home(Map<String, Object> model) {
            model.put("message", this.message);
            return "index";
        }
    
    }
    
    <!DOCTYPE html>
    <html xmlns:th="http://www.thymeleaf.org">
    <head>
    <title>Hello</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    
    
        <link rel="stylesheet/less" th:href="@{/webapp/assets/theme.siberia.less}"/>
    
        <!-- The app's logic -->
        <script type="text/javascript" data-main="/webapp/app" th:src="@{/webapp/libs/require.js}"></script>
        <script type="text/javascript">
            require.config({
                paths: { text:"/webapp/libs/text" }
            });
        </script>
    
         <!-- Development only -->
         <script type="text/javascript" th:src="@{/webapp/libs/less.min.js}"></script>
    
    
    </head>
    <body>
    
    </body>
    </html>
    
  • 1

    我在static dir中有一个assets文件夹,并允许在SpringConfig中扩展 WebSecurityConfigurerAdapter .

    http.authorizeRequests().antMatchers("/", "/login", "/assets/**")
                .permitAll()
    
  • 2

    事实证明,虽然Spring Boot很聪明地将各种资源目录添加到类路径中,但是Maven不是,并且由你来决定处理那部分 . 默认情况下,只有 src/main/resources 将包含在您的JAR中 . 如果您在项目的根目录中创建一个名为 /static 的文件夹(如博客文章所暗示的那样),那么在使用 spring-boot:run Maven目标时它将正常工作,但在创建JAR后则无法正常工作 .

    最简单的解决方案是在 /src/main/resources 中创建 /static 文件夹,然后Maven将其包含在JAR中 . 您可以选择向Maven项目添加其他资源位置:

    <resources>
        <resource>
            <directory>src/main/resources</directory>
        </resource>
        <resource>
            <directory>static</directory>
            <targetPath>static</targetPath>
        </resource>
    </resources>
    

    我希望这对某些人有用,当你退后一步看看Maven是如何工作的时候会很明显,但它可能会让一些人使用Spring Boot,因为它的设计非常免配置 .

  • 3

    我花了几页来了解如何在Spring启动环境中提供静态内容 . 大多数建议都是将静态文件放在/ static / resources / src / main / webapp等中 . 考虑分享下面的方法 .

    • 允许spring boot自动配置Dispatcher Servlet - 确保DispatcherServletAutoConfiguration不在自动配置的排除中 .

    @EnableAutoConfiguration(exclude = {//DispatcherServletAutoConfiguration.class,})

    • 注入外部目录以进行静态内容路由

    @Value(“$ {static-content.locations:file:C:/ myprj / static /”)private String [] staticContentLocations;

    3.使用WebMvcConfigurerAdapter取消WebMvcAutoConfiguration建议不使用默认资源位置但使用我们指示的内容 . 如下所示

    @Bean
        public WebMvcConfigurerAdapter webMvcConfigurerAdapter()
        {
            return new WebMvcConfigurerAdapter()
            {
                @Override
                public void addResourceHandlers(ResourceHandlerRegistry registry)
                {
                    if (!registry.hasMappingForPattern("/**"))
                    {
                        // if this is executed spring won't add default resource
                        // locations - add them to the staticContentLocations if
                        // you want to keep them
                        // default locations:
                        // WebMvcAutoConfiguration.RESOURCE_LOCATIONS
                        registry.addResourceHandler("/**").addResourceLocations(
                                staticContentLocations);
                    }
                }
            };
        }
    

    如果C:/ myprj / static有index.html,则http://localhost:portno/index.html应该有效 . 希望有所帮助 .

相关问题