質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.10%

Spring5 + ThymeleafでCSS反映させたい

受付中

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,160

Saggitarie

score 9

前提・実現したいこと

※imageフォルダを「webapp/image」に移動したら解決しました。

Spring 5 + Spring Security + Thymeleaf + BootstrapでECサイトを作成しています。
ローカルに置いてあるcssファイルを読み込みたいのですが、未だにうまく反映されません。

発生している問題・エラーメッセージ

Failed to load resource: the server responded with a status of 404 () style.css

Chrome上でソースを見てリンクを押すと404エラーが発生します。パスがあっていないことはわかるのですが、Spring上でどのようにpathを指定すればいいのかわかりません。

該当のソースコード

1) Web Security Config

    @Override
    public void configure(WebSecurity web) throws Exception {
        // セキュリティ設定を無視するリクエスト設定
        // 静的リソースに対するアクセスはセキュリティ設定を無視する

        web.ignoring().antMatchers("/resources/**", "/resource/**", "/css/**", "/js/**", "/images/**", "/vendor/**", "/fonts/**");
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.eraseCredentials(true)
                .userDetailsService(userDetailsService)
                .passwordEncoder(passwordEncoder());
        //add our users for in memory authentication

    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/").permitAll()
                .anyRequest().authenticated()
                .and()
                .formLogin()
                .loginPage("/index")
                .permitAll()
                .usernameParameter("userName")
                .passwordParameter("password")
                .loginProcessingUrl("/authenticate")
                .defaultSuccessUrl("/result")
                .failureUrl("/login/failure")
        ;
    }

2) Web MVC Config

    @Bean
    public SpringResourceTemplateResolver templateResolver() {
        SpringResourceTemplateResolver templateResolver = new SpringResourceTemplateResolver();
        //ビューを保存するフォルダ名を指定する
        templateResolver.setPrefix("WEB-INF/templates/");
        //ビューの拡張子を指定する
        templateResolver.setSuffix(".html");
        //テンプレートモードをHTMLに指定する
        //templateResolver.setTemplateMode(TemplateMode.HTML);
        templateResolver.setTemplateMode("HTML5");
        //テンプレート読み込み時の文字コードを指定する
        templateResolver.setCharacterEncoding(StandardCharsets.UTF_8.name());
        return templateResolver;
    }

    @Bean
    public SpringTemplateEngine templateEngine() {
        SpringTemplateEngine engine = new SpringTemplateEngine();
        //engine.addDialect(new SpringSecurityDialect());
        engine.setTemplateResolver(templateResolver());
        return engine;
    }

    @Bean
    public ThymeleafViewResolver thymeleafViewResolver() {
        ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
        viewResolver.setTemplateEngine(templateEngine());
        //ビューを書き出す際の文字コードを指定する
        viewResolver.setCharacterEncoding("UTF-8");
        viewResolver.setOrder(1);
        return viewResolver;
    }

    /**
     * CSSなどの静的コンテンツを利用するための設定を記述する。
     */
    public void addResourceHandlers(ResourceHandlerRegistry registry) {

          // Register resource handler for CSS and JS
            registry.addResourceHandler("resource/**").addResourceLocations("classpath:/static")
                    .setCacheControl(CacheControl.maxAge(2, TimeUnit.HOURS).cachePublic());

          // Register resource handler for images
            registry.addResourceHandler("/images/**").addResourceLocations("/WEB-INF/images/")
                    .setCacheControl(CacheControl.maxAge(2, TimeUnit.HOURS).cachePublic());
        }

3) ビュー(Thymeleafで読み込み)

<!doctype html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="utf-8"/>
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"/>
    <meta name="description" content=""/>
    <meta name="author" content="Mark Otto, Jacob Thornton, and Bootstrap contributors"/>
    <meta name="generator" content="Jekyll v3.8.5"/>

    <title>Navbar Template · Bootstrap</title>

    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"
          integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">

    <!--<link rel="stylesheet" th:src="@{/css/style.css}" type="text/css"/>-->

    <link href="/css/style.css" th:href="@{/css/style.css}" rel="stylesheet">
<div class="container">
    <div class="row">
        <!-- Carousal -->
        <div class="col-md-8">
            <div class="panel panel-default">
                <div class="panel-body">
                    <!--カルーセルのタグ。いじるのはオススメしない。-->
                    <div id="carousel-example" class="carousel slide" data-ride="carousel">

                        <!--ここで好きな枚数のスライドを作れる。imgタグのscr内に好きな画像を入れよう。-->
                        <div class="carousel-inner">
                                                    <!--後ろにactiveをつけたものが最初に表示されるよ。-->
                            <div class="carousel-item active">
                                <img class="d-block w-100" src="http://lorempixel.com/output/sports-q-c-1600-500-1.jpg"
                                     alt="Picture1">
                                <div class="carousel-caption">
                                    <h4>First Thumbnail</h4>
                                    <p>Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots
                                        in a
                                        piece of classical Latin literature from 45 BC, making it over 2000 years
                                        old. </p>
                                </div>
                            </div>
                            <div class="carousel-item">
                                <img class="d-block w-100" src="http://lorempixel.com/output/sports-q-c-1600-500-3.jpg"
                                     alt="Picture2">
                            </div>
                            <div class="carousel-item">
                                <img class="d-block w-100" src="http://lorempixel.com/output/sports-q-c-1600-500-2.jpg"
                                     alt="Picture3">
                            </div>
                        </div>

                        <!--これはスライドの「進むボタン」と「戻るボタン」。いらないなら無くていい。-->
                        <a class="carousel-control-prev" href="#carousel-example" role="button" data-slide="prev">
                            <span class="carousel-control-prev-icon" aria-hidden="true"></span>
                            <span class="sr-only">Previous</span>
                        </a>
                        <a class="carousel-control-next" href="#carousel-example" role="button" data-slide="next">
                            <span class="carousel-control-next-icon" aria-hidden="true"></span>
                            <span class="sr-only">Next</span>
                        </a>

                        <!--こちらはスライドの枚数や現在地がわかるあれ。いらないならn(ry-->
                                   
                        <ol class="carousel-indicators">
                            <li data-target="#carousel-example" data-slide-to="0" class="active"></li>
                            <li data-target="#carousel-example" data-slide-to="1"></li>
                            <li data-target="#carousel-example" data-slide-to="2"></li>
                        </ol>
                    </div>
                </div>
            </div>
        </div>
        <div class="col-sm-2">
            <div class="logo">
                 <img th:src="@{/images/logo.png}"/>
            </div>
        </div>
    </div>
</div>

試したこと

以下のStackFlow のサイトの方法で解決を試みましたが、完璧に詰んでいます。
初歩的な質問で申し訳ないですが、どこが間違えているのか検討がつきません。

1)https://stackoverflow.com/questions/50792837/thymeleaf-3-spring-5-load-css
2)https://stackoverflow.com/questions/54848419/cant-load-my-css-when-using-spring-security-and-thymeleaf
3)https://stackoverflow.com/questions/54844592/unable-to-add-css-file-in-spring-and-thymeleaf
4)https://stackoverflow.com/questions/29562471/springboot-with-thymeleaf-css-not-found
5) https://stackoverflow.com/questions/26283670/spring-mvc-issue-with-loading-of-resources-images-css

補足情報(FW/ツールのバージョンなど)

フォルダ構成

ちなみに、Spring Bootは使用していません。

使用しているIDE:IntelliJ

ご教授よろしくお願いします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • asahina1979

    2019/07/07 00:10

    公式ドキュメントに普通にかいてあるし、チートシートも普通に検索すれば出てきます。
    それらの何がわかりませんでしたか?

    キャンセル

  • Saggitarie

    2019/07/07 00:16 編集

    addResourceHandlersメソッドで静的ファイルのフォルダを指定しているので、絶対パスを書かなくても読み込めるはずなのですが、、

    キャンセル

回答 1

0

thymeleafでリソースを参照するときのパスの指定に誤りがあります。

th:href="@{src/main/resources/statics/css/style.css}"

ではなく、"@{/statics/css/style.css}" でしょう。設定次第では、staticの表記も省略できます。
src/main/resources は、mavenによって構成されたディレクトリの形式にすぎず、resources の中もJavaのクラスパスを通している状態です。

Thymeleafの https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html#link-urls も一部参考になるかと思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/07/08 06:08

    回答ありがとうございました。上記のthymeleafのパスの指定方法で試しましたが、未だに404のエラーが表示されます。addResourcesでのパスの指定方法に誤りがあるのでしょうか?

    よろしくお願いします。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.10%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる