logo 范 · 拾光录
网址收集 关于作者 Github Gitee
杂文随笔5
Hexo博客:基础使用Hexo博客:Next主题Hexo博客:Next进阶使用Hexo博客:Next高级配置基于Node的WIKI管理
前端知识16
HTML常用知识CSS常用知识CSS美化checkbox复选框JavaScript常用知识JavaScript格式化时间戳JavaScript窗口宽高处理JavaScript黑夜主题切换实现方案JavaScript数字转大写简易图片查看器TypeScript基础知识Threejs基础三要素Threejs网格辅助和轨道控制器Threejs物体绘制Electron基础使用Nodejs基础知识animate.css页面动画
Vue框架19
Vite的使用及扩展Vue3父子组件Vue3使用Marked解析MarkdownMermaid图表生成库初始化页面加载动画Axios表单提交二维码解决方案NProgress加载进度条Vue3动态菜单实现Vue3使用ECharts图表Vue3处理Excel导入导出keep-alive页面缓存及setup问题Element:文件上传Element:结合Pinia实现动态菜单Element:图片上传组件Element:自定义统一弹窗组件Element:表格自定义指令控制按钮显示(鉴权)可视化大屏使用缩放适配分辨率
UniApp15
UniApp的基础使用封装网络请求工具及文件上传uni-app的开发记录微信小程序分享原生文件上传Pinia取消滚动条(兼容小程序)tabbar消息数量显示scroll-view上滑到底部加载数据状态栏高度动态设配数据共享与传递uview-plus导航栏实现背景融合Wot UIWot UI实现顶部背景图融合uni-app x
Java基础知识10
基础知识面向对象Lambda表达式常用API常用知识积累try-with-resource注解反射多线程经纬度距离计算
SpringBoot31
application配置Maven创建聚合项目全局异常处理锁机制项目启动初始化数据方式邮件功能集成原生定时任务异步集成阿里云OSS阿里OSS预签名上传基于hutool读excelJSR303WebSocketWebSocket版AI接口流式调用Smart-Doc接口文档生成器application配置信息加密雪花算法工具AOP实现请求参数脱敏思路JWT生成Token及工具类SpringBoot默认JSON与对象转换若依框架:安装使用若依框架:优化和调整文件上传若依框架:管理后台页面优化若依框架:后端接口代码优化SpringAISpringBoot实现AI接口流式调用服务启动时创建MySQL连接自建项目工程树形结构处理工具微信支付代码微信手机号登录
SpringMVC14
跨域处理拦截器RESTful风格伪前后端分离Jackson转换器调整Thymeleaf基于拦截器做权限校验AOP打印接口请求响应日志AOP打印接口请求响应耗时文件上传和回显POST请求加解密实现(AES)POST请求加解密实现(RSA+AES)参数动态校验实现方案真实IP和归属地
MyBatis8
MyBatis基本使用与配置Mapper使用相关MaBatis多数据源配置MyBatisPlus数据统计类处理方案MyBatisPlus条件查询正向工程的实现(H2)mybatis-plus-join
SpringCloud15
Netflix:微服务与搭建Netflix:服务的消费与提供Netflix:EurekaNetflix:ActuatorNetflix:RibbonNetflix:FeignNetflix:HystrixNetflix:ZuulAlibaba:简介与搭建Alibaba:Nacos注册中心Alibaba:RibbonAlibaba:OpenFeignAlibaba:Nacos配置中心Alibaba:GetewayAlibaba:Sentinel
MySQL6
MySQL基础知识MySQL多表查询与事务MySQL常用函数及解决方案MySQL视图MySQL索引安装MySQL
Redis7
Redis介绍和安装Redis配置文件Redis持久化Redis集群Redis语法基础Redis相关问题及解决方案SpringBoot集成Redis使用记录
MongoDB10
Linux安装MongoDBMongoDB基础语法MongoTemplate及SpringBoot配置MongoTemplate中Update操作MongoTemplate中聚合查询MongoTemplate日期归档示例项目使用相关知识归纳地理位置存储与距离查询MongoDB副本集与事务获取类名和属性名工具类
其他数据库1
H2数据库
Python编程6
Python基础知识Python语法yolo目标检测OpenCV的使用及树莓派平台condauv
工具集合13
IDEAMavenGradleGitNginx安装Nginx配置VSCodeJMeter压测DockerOllamaRustFSPicGoObs录制
Linux知识11
Linux常用命令Jar启动脚本VirtualBox安装CentOSVirtualBox安装Ubuntu树莓派安装及使用frp内网穿透ArchLinux:基础系统安装ArchLInux:图形化界面安装ArchLinux:常用软件ArchLinux:深度优化ArchLinux:Niri
创意设计2
Blender:入门知识UI设计基础知识
AI相关9
Claude CodeHermes AgentOpenAI基本使用OpenAI工具调用OpenAI记忆管理OpenAI推理执行OpenAI开发框架Langchainllama.cpp

Thymeleaf是一款用于渲染XML/XHTML/HTML5内容的模板引擎,类似JSP,Velocity,FreeMaker等,它也可以轻易的与Spring MVC等Web框架进行集成作为Web应用的模板引擎

文档

官方文档

头部提示

<html lang="zh-CN" xmlns:th="http://www.thymeleaf.org">

数据作用域

import org.springframework.ui.Model;

// 主要是 Model
@GetMapping("/manage")
public String category(HttpServletRequest request, Model model) {
    model.addAttribute("config", CommonCache.config);
    model.addAttribute("loginFlag", Objects.equals(request.getSession().getAttribute("loginFlag"), true));
    model.addAttribute("categoryList", categoryService.listCategory());
    return "manageCategory";
}

JSON的解析

<div th:text="${article['content']}"></div>

style

<div th:style="${newCate} eq ${item['cateName']} ? 'display:block' : ''"></div>

或者可读性更强的字面量替换

<tr th:each="item,itemStat:${list}" class="animated fadeInDown" th:style="|animation-delay: ${itemStat.count * 200 + 200}ms|">
    <td th:text="${item.id}"></td>
    <td th:text="${item.name}"></td>
    <td th:text="${item.sort}"></td>
    <td th:text="${item.type}"></td>
    <td>
        <button>编辑</button>
    </td>
</tr>

class

th:classappend="${page == pageNnm} ? 'active' : ''"

遍历

<tr th:each="cate:${cateList}">
  <td th:text="${cate.sort}"></td>
  <td th:text="${cate.name}"></td>
  <td>0</td>
  <td th:text="${cate.createDate}"></td>
  <td th:text="${cate.updateDate}"></td>
</tr>

遍历中的index

<div th:each="item,itemStat : ${hot}">
  <span th:text="${itemStat.count}">1</span>
  <a th:href="'/article/'+${item.id}" th:text="${item.title}"></a>
</div>

图像

<img th:src="@{${session.config.avatar}}">

时间

<div th:text="${#dates.format(article.createDate, 'yyyy-MM-dd')}"></div>

onclick

<span class="option" th:onclick="edit([[${category.cateId}]])">重命名</span>

注意:IDEA会飘红,不影响程序运行,优化可使用HTML5的data-*属性

<!-- 使用 data-id 和 data-name 存储数据,清晰明了 -->
<button class="btn-rename" 
        th:data-id="${item.id}" 
        th:data-name="${item.name}"
        onclick="renameFun(this)">
    重命名
</button>

function renameFun(button) {
    // 直接从按钮元素上获取绑定的数据
    const id = button.getAttribute('data-id');
    const name = button.getAttribute('data-name');
    
    console.log("ID:", id, "名称:", name);
    // 你的业务逻辑...
}

下拉选中

<select name="recommend" id="recommend">
<option value="0" th:selected="${article.recommend == 0}">不推荐</option>
<option value="1" th:selected="${article.recommend == 1}">推荐</option>
</select>

解析HTML

<span th:utext="${item.intro}"></span>

模板

创建个html文件,如common.html
<!--底部-->
<div th:fragment="footer">
  <span>© 2020</span>
</div>

使用
<!--底部-->
<div th:replace="~{common::footer}"></div>

注意:模板需要放在templates目录下,不然无法找到

重定向和转发

redirect:  重定向,没有数据
forward:  请求转发,带数据,默认

如:return "redirect:/";

自定义错误页面

在templates下创建error文件夹,放入错误页的html

4xx代表4开头的错误,也可以创建具体的每个状态页面,比如404、400,也可以定义带信息

import com.fan.cache.CommonCache;
import org.springframework.boot.web.servlet.error.ErrorController;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 * 错误页面
 */
@Controller
public class ErrorCustomController implements ErrorController {

    @RequestMapping("/error")
    public String error(Model model) {
        model.addAttribute("config", CommonCache.config);
        return "500";
    }

}

script绑定数据

<script th:inline="javascript">
  // 语法 [[${article.content}]]
  $('#content').html(marked([[${article.content}]]))
  // 同样可以使用判断
  $('#content').html(marked([[${article != null ? article.content : ''}]]))
</script>

input数据绑定

<input id="title" type="text" placeholder="标题" th:value="${document.name}">

textarea数据绑定

<textarea id="content" placeholder="内容" th:text="${document.content}"></textarea>

if条件

<ul>
    <li>首页</li>
    <!-- 只有管理员登录时,才显示后面这两个 li,且不会多出多余的 div 标签 -->
    <th:block th:if="${user.isAdmin}">
        <li>用户管理</li>
        <li>系统设置</li>
    </th:block>
    <li>退出登录</li>
</ul>

拦截器未登录重定向到404

可以配合自定义错误页面使用

/**
 * 请求拦截,权限控制
 */
@NonNullApi
@Slf4j
public class ReqInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws IOException {
        Object loginFlag = request.getSession().getAttribute("loginFlag");
        if (Objects.nonNull(loginFlag)) {
            return true;
        }
        // 重定向到404页面
        response.sendError(HttpServletResponse.SC_NOT_FOUND);
        return false;
    }

}
文档
头部提示
数据作用域
JSON的解析
style
class
遍历
遍历中的index
图像
时间
onclick
下拉选中
解析HTML
模板
重定向和转发
自定义错误页面
script绑定数据
input数据绑定
textarea数据绑定
if条件
拦截器未登录重定向到404