web-dev-qa-db-ja.com

jarを実行すると、静的コンテンツを含むSpring Bootプロジェクトが404を生成する

Springによる静的Webの使用に関する最近のブログ投稿( https://spring.io/blog/2013/12/19/serving-static-web-content-with-spring-boot ) Spring Bootプロジェクトのコンテンツは、いくつかのリソースディレクトリを使用できることを示しています。

  • / META-INF/resources /
  • / resources /
  • /静的/
  • /公衆/

これは、これらのディレクトリをクラスパスに自動的に追加するWebMvcAutoConfigurationクラスのおかげです。これはすべてうまくいくようで、spring-boot-maven-pluginspring-boot:runゴール、すべての静的コンテンツが機能しています(例:/index.html)。

Spring Bootプロジェクトをパッケージ化し、spring-boot-maven-pluginを許可して拡張JARを作成し、Java -jar my-spring-boot-project.jarを使用してプロジェクトを実行しようとすると静的コンテンツが404エラーを返すようになりました。

25
Robert Hunt

Spring Bootがさまざまなリソースディレクトリをクラスパスに追加するのは賢明ですが、Mavenはそうではなく、その部分を処理するのはユーザー次第です。デフォルトでは、src/main/resourcesのみがJARに含まれます。プロジェクトのルートに/staticという名前のフォルダーを作成すると(ブログの投稿で暗示されているように)、spring-boot:run Mavenの目標。ただし、JARを作成したら。

最も簡単な解決策は、/static内に/src/main/resourcesフォルダーを作成し、MavenがそれをJARに含めることです。別の方法として、Mavenプロジェクトにリソースの場所を追加できます。

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

これが誰かに役立つことを願っています。Mavenがどのように機能するかを振り返ってみると、それは明らかなことですが、Spring Bootを使用すると、ほとんど設定が不要になるように設計されているので、数人が困惑するかもしれません。

39
Robert Hunt

私はグラドルでこれを行う方法を見つけようとして、壁に頭を叩いています。任意のヒント?

編集:私はこれをbuild.gradleに追加することで動作するようになりました:

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

Springブート環境で静的コンテンツを提供する方法を理解するために、私は数ページを回っていました。ほとんどすべてのアドバイスは、静的ファイルを/ static/resources/src/main/webappなどに配置することに関するものでした。以下のアプローチを共有することを考えました。

  1. スプリングブートを許可してDispatcher Servletを自動構成する-DispatcherServletAutoConfigurationがAutoConfigurationの除外に含まれていないことを確認します。

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

  2. 静的コンテンツルーティング用に外部ディレクトリを挿入する

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

3.WebMvcConfigurerAdapterを使用してWebMvcAutoConfigurationをオーバーライドし、デフォルトのリソースの場所を使用せず、指示されたものを使用するようにSpringにアドバイスします。

@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 が機能するはずです。お役に立てば幸いです。

3
Sriram

Spring BootはWebMvcAutoConfigurationを使用して静的コンテンツを設定します。このクラスは、カスタムWebMvcConfigurationSupport Beanがない場合にのみ効果を発揮します。私の場合は、1つあります。

@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/");
}
2
acoder2013

考慮すべき2つのことがあります(Spring Boot v1.5.2.RELEASE)-

1)@EnableWebMvcアノテーションのすべてのコントローラークラスを確認し、存在する場合は削除します

2)アノテーションが使用されているコントローラークラス(@RestControllerまたは@Controller)を確認します。

1つのクラスに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>
2
gjp

静的ディレクトリにアセットフォルダーがあり、SpringConfigでWebSecurityConfigurerAdapterを拡張しました。

http.authorizeRequests().antMatchers("/", "/login", "/assets/**")
            .permitAll()
0
Venkat