1 thymeleaf模板解析
(一)模板引擎概述
thymeleaf是一款用于渲染XML/XHTML/HTML5内容的模板引擎。类似JSP, Velocity,FreeMaker等,它也可以轻易的与Spring MVC等Web框架进行集成作为Web应用的模板引擎。与其它模板引擎相比,Thymeleaf最大的特点是能够
直接在浏览器中打开并正确显示模板页面,而不需要启动整个Web应用
Spring Boot推荐使用Thymeleaf、Freemarker等现代的模板引擎技术;一但导入相
关依赖,会自动配置ThymeleafAutoConfiguration、FreeMarkerAutoConfiguration。
模板引擎工作原理图:
(二) SpringBoot使用thymeleaf 入门案例
1 构建maven工程引入技术依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
<version>2.4.3</version>
</dependency>
2 在application.yml当中添加配置
spring:
#开始thymeleaf设置
thymeleaf:
#禁用模板缓存
cache: false
3 编写Controller文件
package com.offcn.demo.controller;
@Controller
public class FirstThymeleafController {
/**
* 访问http://localhost:8080/first
* 将数据message填充到templates/index.html
* @param model
* @return
*/
@GetMapping("/first")
public String indexPage(Model model) {
String message = "Hello, Thymeleaf!";
model.addAttribute("message", message);
return "index";
}
}
4 编写模板文件
在resources/templates 下新建 index.html
<!doctype html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>首页</title>
</head>
<body>
<h1 th:text="${message}"></h1>
</body>
</html>
通过 类似EL 表达式将 Model 中的数据填充到 h1 标签中
5 运行访问地址 http://localhost:8080/first
(三) Thymeleaf 语法简介
(四)使用thymeleaf模板进行数据交互
1 Spring boot 集成Thymeleaf打印对象属性
1.1 新建一个实体bean User
package com.offcn.demo.bean;
public class User {
private Integer id;
private String name;
private int age;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
1.2 新建Controller
package com.offcn.demo.controller;
import java.util.HashMap;
import java.util.Map;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import com.offcn.demo.bean.User;
@Controller
public class SecondThymeleafController {
/**
* 访问localhost:8080 页面
* 将数据message填充到templates/index2.html
* @param model
* @return
*/
@GetMapping("/second")
public String indexPage(Model model) {
String message = "Hello, Thymeleaf!";
User u = new User();
u.setId(1);
u.setName("优就业");
u.setAge(18);
Map<String,Object> map=new HashMap<>();
map.put("src1","1.jpg");
map.put("src2","2.jpg");
model.addAttribute("message", message);
model.addAttribute("user", u);
model.addAttribute("src", map);
return "index2";
}
}
1.3 在resource/templates 下,新增模板文件index2.html
<!doctype html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>首页</title>
</head>
<body>
<h1 th:text="${message}"></h1>
<img th:src="${src.src1}"/>
</br>
<img th:src="${src.src2}"/>
</br>
<span th:text="${user.id}"></span>
<span th:text="${user.name}"></span>
<span th:text="${user.age}"></span>
</body>
</html>
1.4 访问地址 http://localhost:8080/second
2 Spring boot 集成Thymeleaf循环遍历集合
2.1 新建一个Controller
package com.offcn.demo.controller;
@Controller
public class ThreeThymeleafController {
/**
* 访问localhost:8080/java003 页面
* 将数据message填充到templates/index3.html
* @param model
* @return
*/
@GetMapping("/three")
public String indexPage(Model model) {
List<User> list=new ArrayList<User>();
User u1 = new User();
u1.setId(1);
u1.setName("优就业");
u1.setAge(18);
list.add(u1);
User u2 = new User();
u2.setId(2);
u2.setName("中公教育");
u2.setAge(28);
list.add(u2);
User u3 = new User();
u3.setId(3);
u3.setName("IT先锋");
u3.setAge(88);
list.add(u3);
User u4 = new User();
u4.setId(4);
u4.setName("JAVA第一");
u4.setAge(888);
list.add(u4);
model.addAttribute("userList", list);
return "index3";
}
}
2.2 在resource/templates 下,新增模板文件index3.html
<!doctype html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>首页</title>
</head>
<body>
<table width="200" style="text-align: center;">
<tr>
<th>编号</th>
<th>姓名</th>
<th>年龄</th>
<th>index</th>
</tr>
<tr th:each="user,iterStat : ${userList}">
<td th:text="${user.id}"></td>
<td th:text="${user.name}"></td>
<td th:text="${user.age}"></td>
<td th:text="${iterStat.index}">index</td>
</tr>
</table>
</body>
</html>
iterStat 称作状态变量,属性有:
index:当前迭代对象的 index(从 0 开始计算)
count:当前迭代对象的 index(从 1 开始计算)
size:被迭代对象的大小
current:当前迭代变量
even/odd:布尔值,当前循环是否是偶数/奇数(从 0 开始计算)
first:布尔值,当前循环是否是第一个
last:布尔值,当前循环是否是最后一个
2.3 访问地址
3 Spring boot 集成Thymeleaf赋值、字符串拼接
3.1 新建一个Controller
package com.offcn.demo.controller;
@Controller
public class FourThymeleafController {
/**
* 访问localhost:8080/java003 页面
* 将数据message填充到templates/index4.html
* @param model
* @return
*/
@GetMapping("/four")
public String indexPage(Model model) {
model.addAttribute("userName", "优就业");
model.addAttribute("href", "http://www.ujiuye.com");
return "index4";
}
}
3.2 在resource/templates 下,新增模板文件index4.html
<!doctype html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>首页</title>
</head>
<body>
<!-- 给标签赋值 th:text -->
<h1 th:text="${userName}"></h1>
<!-- 给属性赋值 th:value、th:属性名称 -->
<input type="text" name="names" th:value="${userName}"/>
</br>
<em th:size="${userName}"></em>
<!-- 字符串拼接 -->
<span th:text="'欢迎来:'+${userName}+'学习!'"></span>
</br>
<!-- 字符串拼接,方式2 -->
<span th:text="|欢迎来:${userName}学习!|"></span>
</body>
</html>
3.3 访问地址: http://localhost:8080/four
4 Spring boot 集成Thymeleaf条件判断、选择语句
4.1 新建一个Controller
package com.offcn.demo.controller;
@Controller
public class FiveThymeleafController {
/**
* 访问localhost:8080/ 页面
* 将数据message填充到templates/index4.html
* @param model
* @return
*/
@GetMapping("/five")
public String indexPage(Model model) {
model.addAttribute("flag", "yes");
model.addAttribute("menu", "admin");
model.addAttribute("manager", "manager");
return "index5";
}
}
4.2 在resource/templates 下,新增模板文件index5.html
<!doctype html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>首页</title>
</head>
<body>
<!-- th:if 条件成立就显示 -->
<h1 th:if="${flag=='yes'}" >中公教育</h1>
<!-- th:unless 条件不成立就显示 -->
<h1 th:unless="${flag=='no'}" >优就业</h1>
<!-- switch选择语句 -->
<div th:switch="${menu}">
<p th:case="'admin'">User is an administrator</p>
<p th:case="${manager}">User is a manager</p>
</div>
</body>
</html>
4.3 访问地址: http://localhost:8080/five
5 Spring boot 集成Thymeleaf 静态资源加载
我们知道一个网页中加载的静态文件通常有一个十分尴尬的问题,比如对于bootstrap.css,就是如果我们能让IDE识别这个文件,那么我们得用相对路径来引入这个文件。这样我们的IDE才能加载到这个文件,并且给予我们相应的提示。但是如果我们想要在发布后服务器能够加载这个文件,我们就必须用相对于resources或者static的位置来引入静态文件。显然,一般情况下我们不能兼顾这两个问题,只能要么在编写的时候用相对自己的路径,然后在发布的时候用相对于项目资源文件夹的路径,要么就只能放弃IDE的提示,非常尴尬。
而在Thymeleaf中,我们可很好的处理这一点。在引入资源的时候,我们可以写类似下面的代码:
<link rel="stylesheet" type="text/css" media="all" href="../../css/gtvg.css" th:href="@{/css/gtvg.css}" />
当我们在没有后台渲染的情况下,浏览器会认得href,但是不认得th:href,这样它就会选择以相对与本文件的相对路径去加载静态文件。而且我们的IDE也能识别这样的加载方式,从而给我们提示。
当我们在有后台渲染的情况下,后台会把这个标签渲染为这样:
<link rel="stylesheet" type="text/css" media="all" href="/css/gtvg.css" />
原来的href标签会被替换成相对于项目的路径,因此服务器就能找到正确的资源,从而正确渲染。
非常的智能而且方便。
这里需要注意到所有的路径我们是用”@{}”来引用,而不是”${}”,因为后者是用来引用变量名的,而前者是引用路径的,因此我们在这里用的是前者。可是如果我们是把路径写在变量里,那么就要用后者来引用了
6 Spring boot 集成Thymeleaf 片段fragment定义使用
thymeleaf也提供了类似import的东西,可以将很多代码块抽象成模块,然后在需要的时候引用,非常方便。
fragment介绍
fragment类似于JSP的tag,在html中文件中,可以将多个地方出现的元素块用fragment包起来使用。
fragment使用
定义fragment,所有的fragment可以写在一个文件里面,也可以单独存在,例如:
6.1 在resource/templates 下,新增模板文件footer.html
<body>
<h1 th:fragment="copy">
© 1999-2022 Offcn.All Rights Reserved
</h1>
</body>
注意: 在Springboot中,默认读取thymeleaf文件的路径是:src/main/resource/templates
6.2 编写Controller
package com.offcn.demo.controller;
@Controller
public class SixThymeleafController {
/**
* 访问localhost:8080/java003 页面
* 将数据message填充到templates/index6.html
* @param model
* @return
*/
@GetMapping("/six")
public String indexPage(Model model) {
return "index6";
}
}
6.3 在resource/templates 下,新增视图文件index6.html
<!doctype html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>首页</title>
</head>
<body>
<!-- 把片段的内容插入到当前位置 -->
<div style="color: #82ff6c" th:insert="~{footer :: copy}"></div>
</br>
<!-- 使用片段的内容替换当前标签 -->
<div style="color: #82ff6c" th:replace="~{footer :: copy}"></div>
</br>
<!-- 保留自己的主标签,不要片段的主标签 -->
<div style="color: #82ff6c" th:include="~{footer :: copy}"></div>
</body>
</html>
fragment的引用
th:insert:保留自己的主标签,保留th:fragment的主标签。
th:replace:不要自己的主标签,保留th:fragment的主标签。
th:include:保留自己的主标签,不要th:fragment的主标签。(官方3.0后不推荐)
6.4 访问地址http://localhost:8080/six 运行
7 Spring boot 集成Thymeleaf 表达式内置对象使用
7.1 常见内置工具对象如下:
#dates 与java.util.Date对象的方法对应,格式化、日期组件抽取等等
#numbers 格式化数字对象的工具方法
#strings 与java.lang.String对应的工具方法
7.2 编写Controller
package com.offcn.demo.controller;
@Controller
public class SevenThymeleafController {
/**
* 访问localhost:8080/java003 页面
* 将数据message填充到templates/index7.html
* @param model
* @return
*/
@GetMapping("/seven")
public String indexPage(Model model) {
//日期时间
Date date = new Date();
model.addAttribute("date", date);
//小数的金额
double price=128.5678D;
model.addAttribute("price", price);
//定义大文本数据
String str="Thymeleaf是Web和独立环境的现代服务器端Java模板引擎,能够处理HTML,XML,JavaScript,CSS甚至纯文本。\r\n" +
"Thymeleaf的主要目标是提供一种优雅和高度可维护的创建模板的方式。为了实现这一点,它建立在自然模板的概念上,将其逻辑注入到模板文件中,不会影响模板被用作设计原型。这改善了设计的沟通,弥补了设计和开发团队之间的差距。\r\n" +
"Thymeleaf也从一开始就设计了Web标准 - 特别是HTML5 - 允许您创建完全验证的模板,如果这是您需要的\r\n" ;
model.addAttribute("strText", str);
//定义字符串
String str2="JAVA-offcn";
model.addAttribute("str2", str2);
return "index7";
}
}
7.3 resource/templates 下,新增模板文件index7.html
<!doctype html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>首页</title>
</head>
<body>
时间:<span th:text="${#dates.format(date,'yyyy-MM-dd HH:mm:ss')}">4564546</span></br>
金额:<span th:text="'¥'+${#numbers.formatDecimal(price, 1, 2)}">180</span> </br>
<!-- # 这里的含义是 如果 atc.text 这个变量多余200个字符,后面显示... -->
<p th:text="${#strings.abbreviate(strText,60)}">内容内容内容</p>
<!-- 判断字符串是否为空 -->
<span th:if="${!#strings.isEmpty(str2)}">字符串str2不为空</span></br>
<!-- 截取字符串,指定长度 -->
<span th:text="${#strings.substring(str2,0,4)}">字符串str2的值</span>
</body>
</html>
7.4 运行访问地址 http://localhost:8080/seven
2 SpringBoot整合Junit
(一)junit5 介绍
Spring Boot 2.2.0 版本开始引入 JUnit 5 作为单元测试默认库
作为最新版本的JUnit框架,JUnit5与之前版本的Junit框架有很大的不同。由三个不同子项目的几个不同模块组成。
JUnit 5 = JUnit Platform + JUnit Jupiter + JUnit Vintage
JUnit Platform: Junit Platform是在JVM上启动测试框架的基础,不仅支持Junit自制的测试引擎,其他测试引擎也都可以接入。
JUnit Jupiter: JUnit Jupiter提供了JUnit5的新的编程模型,是JUnit5新特性的核心。内部 包含了一个测试引擎,用于在Junit Platform上运行。
JUnit Vintage: 由于JUint已经发展多年,为了照顾老的项目,JUnit Vintage提供了兼容JUnit4.x,Junit3.x的测试引擎。
(二)SpringBoot整合Junit
1 构建工程添加依赖
<!--junit5版本,不兼容Junit4 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--如果要继续兼容 junit4,自行引入Vintage-->
<dependency>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-core</artifactId>
</exclusion>
</exclusions>
</dependency>
2 创建测试类
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
class TestThymeleafApplicationTests {
@Test
void contextLoads() {
}
}
3 测试类上添加注解
@SpringBootTest
4 测试类注入测试对象
@SpringBootTest
class TestThymeleafApplicationTests {
@Autowired
private ApplicationContext applicationContext;
@Test
void contextLoads() {
System.out.println(applicationContext);
}
}
3 SpringBoot整合Mybatis
(一)SpringBoot整合Mybatis框架
1 创建maven工程添加依赖
<!--SpringBoot整合Mybatis的启动器-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.4</version>
</dependency>
<!--mysql驱动包-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<!--web模块-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
2 建数据库数据库表
CREATE TABLE `account` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL,
`money` double(10,2) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1005 DEFAULT CHARSET=utf8
3 创建数据模型
/**
* @author offcn
**/
public class Account implements Serializable {
private Integer id;
private String name;
private double money;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getMoney() {
return money;
}
public void setMoney(double money) {
this.money = money;
}
}
4 创建接口和mapper配置文件
@Mapper
public interface AccountMapper {
Account findById(Integer id);
}
<?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.offcn.AccountMapper">
<!-- Account findById(Integer id);-->
<select id="findById" resultType="com.offcn.pojo.Account">
select * from acccont where id=#{id}
</select>
</mapper>
5 配置application.yml(数据源,Myatis配置)
spring:
datasource:
url: jdbc:mysql://localhost:3306/test
username: root
password: root
driver-class-name: com.mysql.jdbc.Driver
# 配置mybatis规则
mybatis:
#config-location: classpath:mybatis/mybatis-config.xml #全局配置文件位置
mapper-locations: classpath:mybatis/mapper/*.xml #sql映射文件位置
type-aliases-package: com.offcn.pojo #配置了实体的别名
configuration:
map-underscore-to-camel-case: true #开启 驼峰式命名法 不写全局,局配置文件的配置都放在configuration对象当中
6 创建业务层接口和实现类
public interface AccountService {
Account findByIdService(Integer id);
}
@Service
public class AccountServiceImpl implements AccountService {
@Autowired
private AccountMapper accountMapper;
@Override
public Account findByIdService(Integer id) {
return accountMapper.findById(id);
}
}
7 创建控制器controller
@Controller
@RequestMapping("account")
public class AccountController {
@Autowired
private AccountService accountService;
@GetMapping("findById")
@ResponseBody
public Account findById(Integer id){
return accountService.findByIdService(id);
}
}
8 启动服务测试结果
访问地址: http://localhost:8080/account/findById?id=1001
测试结果:
4 SpringBoot整合Redis
spring-data-redis针对jedis提供了如下功能:
1.连接池自动管理,提供了一个高度封装的“RedisTemplate”类
2.针对jedis客户端中大量api进行了归类封装,将同一类型操作封装为operation接口
ValueOperations:简单K-V操作
SetOperations:set类型数据操作
ZSetOperations:zset类型数据操作
HashOperations:针对map类型的数据操作
ListOperations:针对list类型的数据操作
(一)创建SpringBoot程序引入启动器
或者是pom.xml文件当中引入启动器依赖
<!--整合redis的启动器-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
(二)application.yml配置连接信息
spring:
redis:
host: 192.168.126.10
port: 6379
password: 123456
1. 绍介一下redisAPI
spring-data-redis针对jedis提供了如下功能:
1.连接池自动管理,提供了一个高度封装的“RedisTemplate”类
2.针对jedis客户端中大量api进行了归类封装,将同一类型操作封装为operation接口
ValueOperations:简单K-V操作
SetOperations:set类型数据操作
ZSetOperations:zset类型数据操作
HashOperations:针对map类型的数据操作
ListOperations:针对list类型的数据操作
(三)使用RedisTemplate操作Redis
1 值类型操作
package com.offcn;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.RedisTemplate;
@SpringBootTest
public class BootRedisDemoApplicationTests {
@Autowired
private RedisTemplate<String,String> redisTemplate;
@Test
void test1() {
ValueOperations<String, String> ops = redisTemplate.opsForValue();
//ops 存
ops.set("username","jack");
// ops取
String username = ops.get("username");
System.out.println(username);
//移除
redisTemplate.delete("username");
}
}
2 Set类型操作
package com.offcn;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.RedisTemplate;
import java.util.Set;
@SpringBootTest
public class BootRedisDemoApplicationTests {
@Autowired
private RedisTemplate<String,String> redisTemplate;
// set集合类型
@Test
void test2() {
SetOperations<String, String> ops = redisTemplate.opsForSet();
//存:
ops.add("set","jack","marray","george");
//取:
Set<String> set = ops.members("set");
System.out.println(set);
//移除:移除单个元素
ops.remove("set","jack");
//删除key
redisTemplate.delete("set");
}
}
3 List集合操作
3.1 右压栈
// 右压栈
@Test
void test3() {
ListOperations<String, String> ops = redisTemplate.opsForList();
//右压栈
ops.rightPush("myList","a");
ops.rightPush("myList","b");
ops.rightPush("myList","c");
//取值:
List<String> myList = ops.range("myList", 0, -1);
System.out.println(myList);
}
3.2 左压栈
// 左压栈
@Test
void test4() {
ListOperations<String, String> ops = redisTemplate.opsForList();
//左压栈
ops.leftPush("myList","A");
ops.leftPush("myList","B");
ops.leftPush("myList","C");
//取值:
List<String> myList = ops.range("myList", 0, -1);// CBAabc
System.out.println(myList);
}
3.3 根据索引查询元素
// 根据索引查询元素
@Test
void test5() {
ListOperations<String, String> ops = redisTemplate.opsForList();
String value = ops.index("myList", 1);
System.out.println(value);
}
3.4 移除某个元素的值
// 移除某个元素的值
@Test
void test6() {
ListOperations<String, String> ops = redisTemplate.opsForList();
ops.remove("myList",1,"A");
List<String> myList = ops.range("myList", 0, -1);//
System.out.println(myList);// CBabc
}
4 Hash类型操作
4.1 存入值
@Test
void test7() {
HashOperations<String, Object, Object> ops = redisTemplate.opsForHash();
// 存入值
ops.put("user","username","mrzhang");
ops.put("user","address","beijing");
ops.put("user","age","18");
}
4.2 提取所有的KEY
// 提取所有的KEY
@Test
void test8() {
HashOperations<String, Object, Object> ops = redisTemplate.opsForHash();
// 提取所有的KEY[field]
Set<Object> user = ops.keys("user");
System.out.println(user);// username address age
}
4.3 提取所有的值
// 提取所有的值
@Test
void test9() {
HashOperations<String, Object, Object> ops = redisTemplate.opsForHash();
// 提取所有的KEY[field]
List<Object> user = ops.values("user");
System.out.println(user);
}
4.4 根据KEY提取值
// 根据KEY提取值
@Test
void test10() {
HashOperations<String, Object, Object> ops = redisTemplate.opsForHash();
// 提取所有的KEY[field]
String o = (String) ops.get("user", "username");
System.out.println(o);
}
4.5根据KEY移除值
// 根据KEY移除值
@Test
void test11() {
HashOperations<String, Object, Object> ops = redisTemplate.opsForHash();
// 提取所有的KEY[field]
ops.delete("user", "username");
}
(四)SpringBoot整合Redis序列化操作
1 Spring提供的序列化器介绍
1.1 Spring默认序列化器
RedisTemplate操作时,默认会采用jdkSerializable序列化机制,使得插入的值在redis客户端看来会有乱码,若想解决这一问题,需要手动指定序列化方式。
public class RedisTemplate<K, V> extends RedisAccessor implements RedisOperations<K, V>, BeanClassLoaderAware {
public void afterPropertiesSet() {
super.afterPropertiesSet();
boolean defaultUsed = false;
if (this.defaultSerializer == null) {
this.defaultSerializer = new JdkSerializationRedisSerializer(this.classLoader != null ? this.classLoader : this.getClass().getClassLoader());
}
...
}
1.2 常见的序列化器
2 序列化案例实现
2.1 创建实体实现序列化接口
/**
* @author offcn
* 实现序列化接口Serializable
**/
public class Account implements Serializable {
private Integer id;
private String name;
private double money;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getMoney() {
return money;
}
public void setMoney(double money) {
this.money = money;
}
@Override
public String toString() {
return "Account{" +
"id=" + id +
", name='" + name + '\'' +
", money=" + money +
'}';
}
}
2.2 在配置类中设置序列化器
/**
* 指定自己的RedisTemplate 模板对象,模板对象设定给了序列化器
* @param redisConnectionFactory
* @return 返回值装在在IOC容器当中
*/
@Bean
public RedisTemplate<String, Account> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<String, Account> template = new RedisTemplate();
template.setConnectionFactory(redisConnectionFactory);
//创建一个序列化器:
Jackson2JsonRedisSerializer serializer = new Jackson2JsonRedisSerializer(Account.class);
//设置默认的序列化器
template.setDefaultSerializer(serializer);
return template;
}
2.3 测试类对象序列化
@SpringBootTest
public class RedisDemo02ApplicationTests {
@Autowired
private RedisTemplate<String,Account> redisTemplate;
/**
* 序列化对象到redis当中
*/
@Test
public void serializableAccount() {
Account account = new Account();
account.setId(1001);
account.setName("张三丰");
account.setId(98765);
redisTemplate.opsForValue().set("account",account);
System.out.println("序列化成功");
}
}
5 SpringBoot整合Dubbo
(一)启动zookeeper注册中心服务
(二)构建maven工程添加依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- zkClient -->
<dependency>
<groupId>com.101tec</groupId>
<artifactId>zkclient</artifactId>
<version>0.9</version>
</dependency>
<!--springboot整合dubbo-->
<dependency>
<groupId>com.alibaba.spring.boot</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>2.0.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
(三)创建服务提供者
1 定义服务接口OrderSerice
/**
* @author offcn
**/
public interface OrderService {
/***
* 查询某个订单对象
*/
public Order loadOrdersService(Integer id);
/***
* 查询所有订单集合
*/
public List<Order> loadOrdersListService();
}
2 定义接口OrderSerice实现类并暴露服务
/**
* @author offcn
* 注意: @Service 注解式dubbo的注解,不是Spring的service注解。
**/
@Component
@Service
public class OrderServiceImpl implements OrderService {
@Override
public Order loadOrdersService(Integer id) {
// TODO Auto-generated method stub
Order o=new Order();
o.setId(id);
o.setRemark("备注....");
o.setTotal(123);
return o;
}
@Override
public List<Order> loadOrdersListService() {
Order o=new Order();
o.setId(1001);
o.setRemark("新疆大盘鸡一份");
o.setTotal(12);
Order o1=new Order();
o1.setId(1002);
o1.setRemark("东北杀猪菜一份");
o1.setTotal(123);
List<Order> results=new ArrayList<Order>();
results.add(o);
results.add(o1);
return results;
}
}
3 配置application.properties整合dubbo
#dubbo的配置
spring.dubbo.application.name=provider-order
spring.dubbo.registry.address=zookeeper://192.168.126.10:2181
spring.dubbo.scan=com.offcn.service.impl
spring.dubbo.protocol.name=dubbo
server.port=8088
4 创建启动类并启动服务
@SpringBootApplication
@EnableDubboConfiguration
public class DemoProvederApplication {
public static void main(String[] args) {
SpringApplication.run(DemoProvederApplication.class, args);
}
}
(四)创建服务器消费者
1 环境准备
创建boot工程, 引入相关依赖
<!-- zkClient -->
<dependency>
<groupId>com.101tec</groupId>
<artifactId>zkclient</artifactId>
<version>0.9</version>
</dependency>
<!--springboot整合dubbo-->
<dependency>
<groupId>com.alibaba.spring.boot</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>2.0.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
2 定义消费端业务接口OrderService & POJO 【copy】
public interface OrderService {
/***
* 查询某个订单对象
*/
public Order loadOrdersService(Integer id);
/***
* 查询所有订单集合
*/
public List<Order> loadOrdersListService();
}
3 定义消费端OrderController
@Controller
public class OrderController {
// @Autowired spring容器当中自动装配
@Reference//dubbo容器当中获得一个远程对象,注入。
private OrderService orderService;
@RequestMapping("findById")
@ResponseBody
public Order findById(Integer id){
Order order = orderService.loadOrdersService(id);
return order;
}
@RequestMapping("findAll")
@ResponseBody
public List<Order> findAll(Integer id){
return orderService.loadOrdersListService();
}
}
4 配置application.yml整合dubbo
spring.dubbo.application.name=consumer
spring.dubbo.registry.address=zookeeper://192.168.126.10:2181
spring.dubbo.scan=com.offcn.controller
spring.dubbo.protocol.name=dubbo
server.context-path=/
server.port=9090
5 创建启动类并启动服务
@SpringBootApplication
@EnableDubboConfiguration
public class DemoProvederApplication {
public static void main(String[] args) {
SpringApplication.run(DemoProvederApplication.class, args);
}
}