写的比较长,从搭建thyemleaf模板开始写的。会的可以直接跳转高阶页面。
以下经过同事帮助,不断测试,发现如下问题。
1 阅览文章 Spring-Boot整合freemarker引入静态资源css、js等
一、概述
1.springboot 默认静态资源访问的路径为:
/static 或 /public 或 /resources 或 /META-INF/resources
这样的地址都必须定义在src/main/resources目录文件中,达到在项目启动时 自动加载 项目静态地址目录 到classpath下 。
静态访问地址:
使用 ResourceHttpRequestHandler核心处理器加载到WebMvcConfigurerAdapter进行对addResourceHandlers方法进行覆盖.将静态访问目录进行重新定义。
我们也可以实现其中方法,手动指定静态访问路径通过继承WebMvcConfigurerAdapter重写内部方法addResourceHandlers也可以达到我们想要的效果。
二、静态资源配置方案
方案1 默认采用springboot 静态资源路径在src/main/resources创建/static 或 /public 或 /resources 或 /META-INF/resources可以直接访问静态资源,默认会放到classpath目录中
方案2 通过application.properties配置,指定自定义静态文件的目录位置,,多个使用逗号分隔,springboot自动失效
spring.resources.static-locations=classpath:/img/,/css/,/js/
方案3 创建StaticController类继承WebMvcConfigurerAdapter 重写addResourceHandlers 指定静态访问资源目录
- addResourceHandler 表示拦截请求,如果遇到/img请求就会找classpath:/img/中找到对应资源的位置,找到图片,如果没有找到就返回404错误
- addResourceLocations 访问本地资源内容对应的映射路径
方案二例子:
原文链接:
第一步:先在application.properties中写
以下代码意味着静态资源在templates文件夹下
spring.resources.static-locations=classpath:/templates/
第二步:将静态资源文件创建在templates文件夹下
第三步:写样式
{color:red}
第四步:在页面引入样式
<link rel="stylesheet" type="text/css" href="/static/css/outlook.css">
2如果是编程老手,直接抄下面的网站就行
3如果是新手,从头开始写的项目。下面是版本号添加完整步骤,全部直接创建文件黏贴。
按目录把文件黏贴一下,我可一个文件都没漏哦。
由于是初学者,事无巨细。
按照目录建立,把下面代码抄抄,先可以看到结果。
ResourceUrlProviderController.java (这个就说利用spring带的方法)直接建文件
package com.example.demo.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.servlet.resource.ResourceUrlProvider;
/**
* @author zy
* @date 2021/9/16 10:00
* @description 静态资源更新
* @return null
*/
@ControllerAdvice
public class ResourceUrlProviderController {
@Autowired
private ResourceUrlProvider resourceUrlProvider;
@ModelAttribute("urls")
public ResourceUrlProvider urls() {
return this.resourceUrlProvider;
}
}
Student.java 文件
package com.example.demo.domain;
import lombok.Data;
import lombok.ToString;
import java.util.Date;
import java.util.List;
/**
* @author ZY
* @date 2021年09月22日 15:54
*/
@Data
@ToString
public class Student {
private String name;//姓名
private int age;//年龄
private Date birthday;//生日
private Float mondy;//钱包
private List<Student> friends;//朋友列表
private Student bestFriend;//最好的朋友
}
User.java 文件
package com.example.demo.domain;
/**
* @author zy
* @date 2021年09月22日 15:01
*/
import java.util.List;
import java.util.Map;
public class User {
String username;
String password;
List<String> hobbies;
Map<String, String> secrets;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public List<String> getHobbies() {
return hobbies;
}
public void setHobbies(List<String> hobbies) {
this.hobbies = hobbies;
}
public Map<String, String> getSecrets() {
return secrets;
}
public void setSecrets(Map<String, String> secrets) {
this.secrets = secrets;
}
}
最简单yml文件 无论你用什么模板,先不管,先粘上去
spring:
mvc:
static-path-pattern: static/** //配置静态资源的路径
web:
resources:
chain:
strategy:
content: #如果用MD5则是fixed,版本号方式为content
enabled: true
paths: /**
# version: v1.0.1 #如果用MD5关闭,版本号方式开启
freemarker:
request-context-attribute: req
suffix: .ftl #关键配置
content-type: text/html
enabled: true
cache: false
template-loader-path: classpath:/templates/ #文件路径
charset: UTF-8
thymeleaf:
#缓冲的配置
cache: false
check-template: true
check-template-location: true
#开启MVC thymeleaf 视图解析
enabled: true
encoding: utf-8
mode: HTML5
prefix: classpath:/templates/
suffix: .html
main:
allow-bean-definition-overriding: true
server:
port: ${port:9043}
DemoApplication,java文件 启动类
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
IndexController.java文件 (controller,相当于后端的入口)
package com.example.demo.controller;
import com.example.demo.domain.Student;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import com.example.demo.domain.User;
import org.springframework.web.bind.annotation.RequestMapping;
import java.util.*;
/**
* @author zy
* @date 2021年09月16日 10:53
*/
@Controller
public class IndexController {
@RequestMapping("/home1")
public String freemarker(Map<String, Object> map){
//返回模板文件名称
return "ttt";
}
@GetMapping("home2")
public String thymeleaf(Model model) {
User user = new User();
user.setUsername("jack");
user.setPassword("112233");
user.setHobbies(Arrays.asList(new String[]{"singing", "dancing", "football"}));
Map<String, String> maps = new HashMap<>();
maps.put("1", "o");
maps.put("2", "g");
maps.put("3", "a");
maps.put("4", "j");
user.setSecrets(maps);
model.addAttribute("user", user);
return "index";
}
@GetMapping("home3")
public String xx() {
return "test1";
}
}
thyemleaf模板的html --index.html
<!doctype html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<!--字符串输出-->
<p th:text="'hello SpringBoot'">hello thymeleaf</p>
<!--数学运算-->
<p th:text="9 + 10"></p>
<p th:text="10 * 10"></p>
<p th:text="1 - 10"></p>
<p th:text="8 / 3"></p>
<p th:text="3 % 2"></p>
<!--操作域对象-->
<p th:text="${user}"></p>
<p th:text="${user.username}"></p>
<!--遍历数组-->
<table th:each="item, sta:${user.hobbies}">
<tr>
<td th:text="${item}"></td>
<td th:text="${sta.index}"></td>
<td th:text="${sta.odd}"></td>
<td th:text="${sta.size}"></td>
</tr>
</table>
<!--遍历map-->
<div th:each="item:${user.secrets}" th:text="${item.key}"></div>
<!--遍历数组-->
<div th:each="item:${user.hobbies}" th:text="${item}"></div>
<!--设置属性-->
<input type="text" th:attr="value=${user.username}">
<input type="text" th:attr="value=${user.username}, title=${user.username}">
<!--表单数据绑定-->
<form action="" th:object="${user}">
<input type="text" th:value="*{username}">
<input type="password" th:value="*{password}">
<select>
<option th:each="item:${user.secrets}" th:text="${item.value}" th:selected="'a' eq ${item.value}"></option>
</select>
</form>
<!--解析html文本内容-->
<p th:utext="'<span>html</span>'"></p>
<!--流程控制-->
<p th:if="${user.username} != ${user.password}">yes</p>
<div th:switch="${user.username}">
<p th:case="rose">name is rose</p>
<p th:case="jack">name is jack</p>
</div>
<!--外部引入-->
<link rel="stylesheet" th:href="@{${urls.getForLookupPath('/static/css/outlook.css')}}">
<script th:src="@{${urls.getForLookupPath('/static/css/cz.js')}}"></script>
<a th:href="@{/home}">home</a>
</body>
</html>
freemarker模板的html --ttt.ftl
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Freemarker</title>
</head>
<script type="text/javascript" src="${urls.getForLookupPath('/static/css/cz.js')}"></script>
<#--<link href="${urls.getForLookupPath('/static/css/outlook.css')}" type="text/css" rel="stylesheet" >-->
<body>
<p>hello</p>
</body>
</html>
cz.js文件 外部引用文件
console.log("我是11111111");
outlook.css文件 外部引用文件
body {
color: red;
}
pom.xml文件
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.4</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<repackage.classifier/>
<spring-native.version>0.10.3</spring-native.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.experimental</groupId>
<artifactId>spring-native</artifactId>
<version>${spring-native.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.5.4</version>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
<classifier>${repackage.classifier}</classifier>
<image>
<builder>paketobuildpacks/builder:tiny</builder>
<env>
<BP_NATIVE_IMAGE>true</BP_NATIVE_IMAGE>
</env>
</image>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.experimental</groupId>
<artifactId>spring-aot-maven-plugin</artifactId>
<version>${spring-native.version}</version>
<executions>
<execution>
<id>test-generate</id>
<goals>
<goal>test-generate</goal>
</goals>
</execution>
<execution>
<id>generate</id>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spring-releases</id>
<name>Spring Releases</name>
<url>https://repo.spring.io/release</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>spring-releases</id>
<name>Spring Releases</name>
<url>https://repo.spring.io/release</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
<profiles>
<profile>
<id>native</id>
<properties>
<repackage.classifier>exec</repackage.classifier>
<native-buildtools.version>0.9.3</native-buildtools.version>
</properties>
</profile>
</profiles>
</project>
4下面是遇到的问题。
模板依赖不相容。会报500错误,或者页面出现好多freemarker代码。这两个有时候需要注释掉一个。
版本号resourse.是content。md5改成fixed。不改就得不到相应结果
不同版本的spring是不需要写web的。如果完全是按照我的文件目录走的话,就是要加web的。
如果是thyemleaf模板,html文件前面写需要加这一句话,不然就会报错。
<html lang="en" xmlns:th="http://www.thymeleaf.org">