目录
  1. SpringBoot整合Thymeleaf构建WEB应用
  2. 一、增加Spring boot的maven 依赖
  3. 二、编写控制层代码
    1. 配置SpringBoot,创建文件application.yml
    2. 实体类
    3. 模型类
    4. 数据库映射接口
    5. 数据库映射实体类
    6. 控制器
  4. 三、编写布局页面
  5. 四、编写列表页面
  6. 五、编写增加页面
    1. 对象提交页
    2. 字段提交页
  7. 六、Thymeleaf的使用与语法
    1. Thymeleaf的默认参数配置
    2. Thymeleaf语法
      1. 基本表达式
        1. 变量的表达式:${...}
        2. 选择变量表达式:*{...}
        3. 信息表达式:#{...}
        4. 链接URL表达式:@{...}
        5. 工具对象表达式:#maps
      2. 常用属性
SpringBoot整合Thymeleaf构建WEB应用

SpringBoot整合Thymeleaf构建WEB应用

云南汉王科技Java8 SpringBoot框架开发培训

Thymeleaf 是一种模板语言。那模板语言或模板引擎是什么?常见的模板语言都包含以下几个概念:数据(Data)、模板(Template)、模板引擎(Template Engine)和结果文档(Result Documents)。

Spring boot 支持多种模板语言(Thymeleaf 、Freemarker、Mustache、Groovy Templates)Thymeleaf 跟大部分的模板语言类似,上手容易,使用简单。

一、增加Spring boot的maven 依赖

在原有基础的pom结构中追加Thymeleaf的依赖

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

二、编写控制层代码

配置SpringBoot,创建文件application.yml

server:
port: 8080
session-timeout: 60*60 #用户会话session过期时间
tomcat:
url-encoding: utf8
compression: true
spring:
thymeleaf:
cache: false
datasource:
driver-class-name: org.postgresql.Driver
url: jdbc:postgresql://120.79.90.37:5432/learning
username: learning
password: ********
db-name: learning
db-schema: swagger2

mybatis-plus:
mapper-locations: classpath:/com/hanwang/restful/mapper/xml/*Mapper.xml
#实体扫描,多个package用逗号或者分号分隔
typeAliasesPackage: com.hanwang.restful.entity
typeEnumsPackage: com.baomidou.springboot.db.entity.enums
global-config:
#刷新mapper 调试神器
db-config:
#主键类型 0:"数据库ID自增", 1:"用户输入ID",2:"全局唯一ID (数字类型唯一ID)", 3:"全局唯一ID UUID";
id-type: uuid
#字段策略 0:"忽略判断",1:"非 NULL 判断"),2:"非空判断"
field-strategy: not_empty
#驼峰下划线转换
column-underline: true
#数据库大写下划线转换
#capital-mode: true
#逻辑删除配置
logic-delete-value: Y
logic-not-delete-value: N
db-type: pgsql
refresh: true
sql-injector: com.baomidou.mybatisplus.extension.injector.LogicSqlInjector
#自定义填充策略接口实现
#meta-object-Handler: com.baomidou.springboot.xxx
#自定义SQL注入器
#sql-injector: com.baomidou.springboot.xxx
configuration:
map-underscore-to-camel-case: true
cache-enabled: false
generator:
module-name: restful01
author: gadfly
file-override: true

实体类

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import com.baomidou.mybatisplus.annotation.TableId;

import java.time.LocalDateTime;
import com.baomidou.mybatisplus.annotation.TableField;
import java.io.Serializable;

import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import pub.gadfly.sdk.Handler.ByteArrayToByteaPG;

/**
* <p>
* 用户信息表 实体类
* </p>
*
* @author gadfly
* @since 2019-12-20
*/
@Data
@EqualsAndHashCode(callSuper = true)
@Accessors(chain = true)
@TableName(value = "user", schema = "swagger2")
public class User extends Model<User> {

private static final long serialVersionUID=1L;

@TableId(value = "id", type = IdType.AUTO)
private Integer id;

@TableField("realname")
private String realname;

@TableField("mobile")
private String mobile;

@TableField("email")
private String email;

@TableField("public_key")
private String publicKey;

@TableField("private_key")
private String privateKey;

@TableField("insert_time")
private LocalDateTime insertTime;

@TableField("modify_time")
private LocalDateTime modifyTime;

@TableField(value = "head_pic", typeHandler = ByteArrayToByteaPG.class)
private byte[] headPic;


public static final String ID ="id";
public static final String REALNAME ="realname";
public static final String MOBILE ="mobile";
public static final String EMAIL ="email";
public static final String PUBLIC_KEY ="public_key";
public static final String PRIVATE_KEY ="private_key";
public static final String INSERT_TIME ="insert_time";
public static final String MODIFY_TIME ="modify_time";
public static final String HEAD_PIC ="head_pic";

@Override
protected Serializable pkVal(){
return this.id;
}
}

模型类

import lombok.Data;
import pub.gadfly.sdk.Utils.StreamUtil;

@Data
public class UserPO{
private Integer id;
private String realname;
private String email;
private String mobile;
private String headPic;

public void setHeadPic(byte[] headPic){
try {
this.headPic = StreamUtil.bytes2Base64Pic(headPic);
} catch (Exception e) {
e.printStackTrace();
}
}
}

数据库映射接口

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.hanwang.web.entity.User;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;

/**
* <p>
* 用户信息表 Mapper 接口
* </p>
*
* @author gadfly
* @since 2019-12-20
*/
@Mapper
@Repository
public interface UserMapper extends BaseMapper<User> {

}

数据库映射实体类

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.hanwang.restful01.mapper.UserMapper">

<!-- 开启二级缓存 -->
<cache type="org.mybatis.caches.ehcache.LoggingEhcache"/>

<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="com.hanwang.web.entity.User">
<id column="id" property="id"/>
<result column="realname" property="realname"/>
<result column="mobile" property="mobile"/>
<result column="email" property="email"/>
<result column="public_key" property="publicKey"/>
<result column="private_key" property="privateKey"/>
<result column="insert_time" property="insertTime"/>
<result column="modify_time" property="modifyTime"/>
<result column="head_pic" property="headPic"/>
</resultMap>

<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
id, realname, mobile, email, public_key, private_key, insert_time, modify_time, head_pic
</sql>

</mapper>

控制器

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Controller
@RequestMapping("/user")
public class UserController {
@Autowired
private UserMapper userMapper;

@RequestMapping(value="", method= RequestMethod.GET)
public String index(Model model){
List<UserPO> userList = new ArrayList<>();
userMapper.selectList( null ).forEach( (user) -> {
UserPO userPO = new UserPO();
userPO.setEmail(user.getEmail());
userPO.setRealname(user.getRealname());
userPO.setMobile(user.getMobile());
userPO.setId(user.getId());
if(user.getHeadPic()!=null){
userPO.setHeadPic(user.getHeadPic());
}
userList.add(userPO);
} );
model.addAttribute("userList", userList);
return "user/index";
}

@RequestMapping(value = "/addUser", method = RequestMethod.GET)
public String addUser(){
return "user/addUser";
}

@RequestMapping(value = "/addUser", method = RequestMethod.POST)
public String addUser(
@RequestParam("realname") String realname,
@RequestParam("mobile") String mobile,
@RequestParam("email") String email
){
System.out.println("realname: " + realname + ", mobile: " + mobile + ", email: " + email);
User user = new User();
user.setEmail( email );
user.setRealname( realname );
user.setMobile( mobile );
_register(user);
return "redirect:/user";
}

@RequestMapping(value = "/register", method = RequestMethod.GET)
public String register(Model model){
model.addAttribute("user", new User());
return "user/register";
}

@RequestMapping(value = "/register", method = RequestMethod.POST)
public String register(@ModelAttribute User user, @RequestParam("file") MultipartFile file){
try {
user.setHeadPic(file.getBytes());
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(user.toString());
_register(user);
return "redirect:/user";
}

private void _register(User user){
try {
Map<String, Object> genKeyPair = RSA.genKeyPair();
user.setPrivateKey( RSA.getPrivateKey(genKeyPair) );
user.setPublicKey( RSA.getPublicKey(genKeyPair) );
user.insert();
} catch (Exception e) {
e.printStackTrace();
}
}
}

三、编写布局页面

<!DOCTYPE html>
<html lang="zh-CN" xmlns:th="http://www.thymeleaf.org">
<head>
<meta content="text/html;charset=UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE-edge" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<link href="https://bootswatch.com/3/cyborg/bootstrap.min.css" rel="stylesheet" />
<title>Title</title>
</head>
<body>
<div class="container">
<nav class="navbar navbar-default">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<a class="navbar-brand" href="#">个人博客</a>
</div>
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav">
<li class="active"><a href="#">欢迎页</a></li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">博客 <span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="#">博客列表</a></li>
<li><a href="#">发布博客</a></li>
</ul>
</li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">用户 <span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a th:href="@{/user}">用户列表</a></li>
<li><a th:href="@{/user/addUser}">注册用户(字段提交)</a></li>
<li><a th:href="@{/user/register}">注册用户(对象提交)</a></li>
</ul>
</li>
</ul>
</div>
</nav>
<div class="panel panel-default">
<div class="panel-heading">Panel heading without title</div>
<div class="panel-body" th:include="::content">
Panel content
</div>
</div>
</div>
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js" type="text/javascript"></script>
<script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
<script th:inline="javascript">
var single = [[${singlePerson}]];
console.log(single.name + "/" + single.age)

function getName(name) {
alert(name);
}
</script>
</body>
</html>

四、编写列表页面

<!DOCTYPE html>
<html lang="zh-CN" xmlns:th="http://www.thymeleaf.org" th:replace="layout">
<div th:fragment="content">
<h3>用户列表</h3>
<ul class="list-group" th:each="user: ${userList}">
<li class="list-group-item row">
<div class="col-md-1 thumbnail">
<img th:src="${user.headPic}" alt="" class="img-circle" style="width: 30px">
</div>
<div class="col-md-4">
<span>真实姓名:</span>
<span th:text="${user.realname}"></span>
</div>
<div class="col-md-4">
<span>联系电话:</span>
<span th:text="${user.mobile}"></span>
</div>
<div class="col-md-3">
<span>电子邮件:</span>
<span th:text="${user.email}"></span>
</div>
</li>
</ul>
</div>
</html>

五、编写增加页面

对象提交页

<!DOCTYPE html>
<html lang="zh-CN" xmlns:th="http://www.thymeleaf.org" th:replace="layout">
<div th:fragment="content">
<h3>用户注册</h3>
<form th:action="@{/user/register}" method="post" th:object="${user}" enctype="multipart/form-data">
<div class="form-group">
<label for="exampleInputRealname">真实姓名</label>
<input type="text" th:field="*{realname}" class="form-control" id="exampleInputRealname" placeholder="真实姓名">
</div>
<div class="form-group">
<label for="exampleInputMobile">联系电话</label>
<input type="text" th:field="*{mobile}" class="form-control" id="exampleInputMobile" placeholder="联系电话">
</div>
<div class="form-group">
<label for="exampleInputEmail">电子邮件</label>
<input type="text" th:field="*{email}" class="form-control" id="exampleInputEmail" placeholder="电子邮件">
</div>
<div class="form-group">
<label for="exampleInputHeadPic">上传头像</label>
<input type="file" name="file" class="form-control" id="exampleInputHeadPic">
</div>
<button type="submit" class="btn btn-default">提交</button>
</form>
</div>
</html>

字段提交页

<!DOCTYPE html>
<html lang="zh-CN" xmlns:th="http://www.thymeleaf.org" th:replace="layout">
<div th:fragment="content">
<h3>用户注册</h3>
<form th:action="@{/user/addUser}" method="post">
<div class="form-group">
<label for="exampleInputRealname">真实姓名</label>
<input type="text" name="realname" class="form-control" id="exampleInputRealname" placeholder="真实姓名">
</div>
<div class="form-group">
<label for="exampleInputMobile">联系电话</label>
<input type="text" name="mobile" class="form-control" id="exampleInputMobile" placeholder="联系电话">
</div>
<div class="form-group">
<label for="exampleInputEmail">电子邮件</label>
<input type="text" name="email" class="form-control" id="exampleInputEmail" placeholder="电子邮件">
</div>
<button type="submit" class="btn btn-default">提交</button>
</form>
</div>
</html>

六、Thymeleaf的使用与语法

坑:创建Thymeleaf模板时注意,把html的名称空间,改成:xmlns:th="http://www.thymeleaf.org"

<!DOCTYPE html>
<html lang="zh-CN" xmlns:th="http://www.thymeleaf.org">
......
</html>
打赏
  • 微信
  • 支付寶

评论