spring - Thymeleaf 无法加载静态资源

标签 spring thymeleaf

我有一个 Spring Web 应用程序,它可以正确加载模板,但不会加载 CSS 和图像等静态资源。我已在 src/main/resources/static 目录中添加了静态资源,添加了 thymeleaf 注释,添加了配置,并根据 StackOverflow 上的类似问题对其进行了检查,但我的 CSS/图像文件均未加载:

控制台错误

Refused to apply style from 'http://localhost:8080/login' because its MIME type ('text/html') is not a supported stylesheet MIME type, and strict MIME checking is enabled.

目录结构

Directory Structure

TemplateConfig.java

package com.valencra.recipes.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.thymeleaf.extras.springsecurity4.dialect.SpringSecurityDialect;
import org.thymeleaf.spring4.SpringTemplateEngine;
import org.thymeleaf.spring4.templateresolver.SpringResourceTemplateResolver;
import org.thymeleaf.spring4.view.ThymeleafViewResolver;

@Configuration
public class TemplateConfig {
  @Bean
  public SpringResourceTemplateResolver templateResolver() {
    final SpringResourceTemplateResolver templateResolver = new SpringResourceTemplateResolver();
    templateResolver.setPrefix("classpath:/templates/");
    templateResolver.setSuffix(".html");
    templateResolver.setTemplateMode("LEGACYHTML5");
    return templateResolver;
  }

  @Bean
  public SpringTemplateEngine templateEngine() {
    final SpringTemplateEngine springTemplateEngine = new SpringTemplateEngine();
    springTemplateEngine.addTemplateResolver(templateResolver());
    springTemplateEngine.addDialect(new SpringSecurityDialect());
    return springTemplateEngine;
  }

  @Bean
  public ThymeleafViewResolver viewResolver() {
    final ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
    viewResolver.setTemplateEngine(templateEngine());
    viewResolver.setOrder(1);
    return viewResolver;
  }
}

layout.html

<!DOCTYPE html>
<html lang="en">

<head th:fragment="head">

    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">

    <title>My Recipes</title>

    <link href='https://fonts.googleapis.com/css?family=Varela+Round' rel='stylesheet' type='text/css'>
    <link rel="stylesheet" th:href="@{/css/unsemantic-grid-responsive.css}">
    <link rel="stylesheet" th:href="@{/css/styles.css}">

</head>

<body>

    <nav th:fragment="nav">
        <a th:href="@{|/profile|}" th:text="${currentUser.name}">
            Chandra S.
        </a>
        &bull;
        <form th:action="@{/logout}" method="post" style="display: inline">
            logout
        </form>
    </nav>

    <div th:fragment="home">
        <div class="grid-100">
            <a th:href="@{|/|}">
                <h1>
                    <img th:src="@{/images/chefbot.svg}" height="60px">
                    <br>
                    My Recipes
                </h1>
            </a>
        </div>
    </div>

    <div th:fragment="favorite">
        <form th:action="@{|/recipes/${recipe.id}/favorite|}" method="post" style="display:inline">
            <button type="submit">
                <img th:src="${recipe.isFavorite(currentUser)} ? @{/images/favorited.svg} : @{/images/favorite.svg}" style="height: 15px;">
            </button>
        </form>
    </div>

</body>

</html>

login.html

<!doctype html>
<html lang="en">

<head th:replace="layout :: head"></head>

<body>

    <nav>
        <a th:href="@{/signup}">
            sign-up
        </a>
    </nav>

  <div class="grid-container">

    <div th:replace="layout :: home"></div>

    <div class="grid-100">
      <div class="recipes">

        <form th:action="@{|/login|}" method="post" th:object="${user}">
          <div class="prefix-20 grid-60 suffix-20">
            <p>
              <input placeholder="Username" th:field="*{username}"> </input>
            </p>
          </div> <div class="clear"></div>
          <div class="prefix-20 grid-60 suffix-20">
            <p>
              <input placeholder="Password" type="password" th:field="*{password}"> </input>
            </p>
          </div> <div class="clear"></div>
          <div class="prefix-20 grid-60 suffix-20">
            <p>
              <button>Login</button>
            </p>
          </div> <div class="clear"></div>
        </form>

      </div> <!-- recipes -->
    </div> <!-- grid-100 -->

  </div> <!-- grid-container -->

</body>

</html>

最佳答案

看起来您的 CSS 已作为 HTML 提供。

由于您将样式表放在 src/main/resources/static 中,Spring 应该根据合理的默认值设置大多数内容,包括设置正确的内容类型 header 。

我假设您正在使用 Spring Security,因为您显示了登录表单。

您的资源可能受到 Spring Security 的保护。因此,您将获得 30x 重定向到登录页面,而不是样式表。这可以解释为什么您的浏览器提示 text/html 内容类型,这对于 css 来说是错误的,但对于登录页面来说是正确的类型。

您是否在项目中的某个位置配置了 HttpSecurity(很可能用 @EnableWebSecurity 进行注释)?

如果是这样,您需要允许匿名访问您的资源:

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.authorizeRequests()
            .antMatchers("/css/**", "/images/**").permitAll()
            // rest of your code 

如果您切换到浏览器控制台中的网络选项卡,您应该能够检查登录页面的重定向。

关于spring - Thymeleaf 无法加载静态资源,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49605173/

相关文章:

html - 如何使用 jumbotron 查看正在运行的应用程序的标题

java - 更新资源时Intellij不更新html文件

java - 在我的Spring MVC应用中实现Spring Actuator,而无需添加Spring Boot

java - 将 ext-js 与 java/spring 一起使用

java - 如何将 AspectJ 加载时编织与 Spring AOP 结合使用?

javascript - Thymeleaf:将输入文本作为 href 中的参数传递

gradle - 一个Gradle Thymeleaf项目根据资源变更重新加载,另一个重新启动

java - Spring应用程序看不到具有属性扩展名的文件(application.properties除外)

spring - Redis BITOP 使用 Spring data Redis

java - 使用 WSDL 和 codehaus jaxb2 的 Spring Soap Web 服务客户端;需要 XmlRootElement 吗?