目录
一、使用 Redis
1.添加依赖
2.编写用户存取类
3.配置 RedisTemplate
4.启动和配置 redis 服务
5.单元测试
二、整合 mybatis
1.加入依赖
2.配置数据库连接信息和 mybatis 的 mapper.xml 位置
3.在启动类上添加 mybatis 接口扫描路径
三、Thymeleaf
1.添加依赖
2.配置 thymeleaf
3.编写 thymeleaf 模板文件
4.thymeleaf常用标签
5.Thymeleaf 主要语法
编辑
三、Freemarker
1.添加依赖
2.配置 freemarker
3.编写 freemarker 模板文件
四、JSP
1.添加相关依赖
2.创建war包项目,并在 application.properties 文件中增加如下配置
3.创建webapp目录和/WEB-INF/jsp/index.jsp
五、websocket
1.加入依赖
2.配置类
3.撰写服务
关系型数据库在性能上总是存在一些这样那样的缺陷,所以大家有时候在使用传统关系型数据库时,会与具有高效存取功能的缓存系统结合使用,以提高系统的访问性能。在很多流行的缓存系统中,Redis 是一个不错的选择。Redis 是一种可以持久存储的缓存系统,是一个高性能的 key-value 数据库,它使用键-值对的方式来存储数据。
要使用 Redis,需要在工程中加入 spring-boot-starter-data-redis
org.springframework.boot
spring-boot-starter-data-redis
Redis 提供了 string、hash、list、set 和 zset 几种数据类型可供存取,在下面实例中,我们将使用 string 即字符串的类型来演示数据的存取操作。对于 Redis,Spring Boot 没有提供像 JPA 那样相应的资源库接口,所以只能仿照上节中 Repository 的定义编写一个实体 User 的服务类,代码如下所示。这个服务类可以存取对象 User 以及由 User 组成的列表 List,同时还提供了一个删除的方法。所有这些方法都是使用 RedisTemplate 来实现的。
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import java.util.Set;
import java.util.concurrent.TimeUnit;
public class UserRedis {
@Autowired
RedisTemplate redisTemplate;
String projectName="springboot-redis";
/**
* 清空项目全部缓存
*/
public void deleteAll() {
String keys = projectName + "_*";
Set deleteKeys = redisTemplate.keys(keys);
for (Object deleteKey : deleteKeys) {
redisTemplate.delete(deleteKey);
}
}
/**
* 设置值
* @param key 键
* @param user 值
*/
public void put(String key, User user) {
String keys = projectName + "_" + key;
redisTemplate.opsForValue().set(keys, user);
}
/**
* 获取值
* @param key 键
* @return 值
*/
public User get(String key) {
String keys = projectName + "_" + key;
Object o = redisTemplate.opsForValue().get(keys);
return (User) o;
}
/**
* 删除键
* @param key 键
*/
public void delete(String key) {
String keys = projectName + "_" + key;
redisTemplate.delete(keys);
}
/**
* 设置键的过期时间
* @param key 键
* @param time 时间
* @param timeUnit 单位
*/
public void expire(String key, long time, TimeUnit timeUnit) {
String keys = projectName + "_" + key;
redisTemplate.expire(keys, time, timeUnit);
}
}
Redis 没有表结构的概念,所以要实现 MySQL 数据库中表的数据(即普通 Java 对象映射的实体数据)在 Redis 中存取,必须做一些转换, 使用 JSON 格式的文本作为 Redis 与 Java 普通对象互相交换数据的存储格式。这里使用 jackson 工具将类对象转换为 JSON 格式的文本进行存储,要取出数据时,再将 JSON 文本数据转化为 Java 对象。
因为 Redis 使用了 key-value 的方式存储数据,所以存入时要生成一个唯一的 key,而要查询或者删除数据时,就可以使用这个唯一的 key 进行相应的操作。 保存在 Redis 数据库中的数据默认是永久存储的,可以指定一个时限来确定数据的生命周期,超过指定时限的数据将被 Redis 自动清除。
另外,为了能正确调用 RedisTemplate,必须对其进行一些初始化工作,即主要对 它存取的字符串进行一个 JSON 格式的序列化初始配置,代码如下所示。
注意:单独使用 jackson 时,需要导入 spring-boot-starter-web 依赖即可。
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate redisTemplate(RedisConnectionFactory factory) {
RedisTemplate template = new RedisTemplate<>();
// 配置连接工厂
template.setConnectionFactory(factory);
Jackson2JsonRedisSerializer
启动 redis 服务后,在工程的配置文件 aplication.yml 中配置连接 Redis 服务器连接等参数,代码如下所示。其 中 host 和 port 分别表示 Redis 数据库服务器的 IP 地址和开放端口,database 是对应的数据库索引。
spring:
redis:
host: localhost
port: 6379
database: 1
测试程序创建一个部门对象并将其命名为“开发部",创建一个角色对 象并把它命名为 admin,创建一个用户对象并把它命名为 user,同时设定这个用户属于"开发部",并把 admin 这个角色分配给这个用户。接着测试程序使用类名等参数生成一个 key,并使用这个 key 清空原来的数据,然后用这个 key 存储现在这个用户的数据, 最后使用这个 key 查询用户,并将查到的信息打印出来。
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;
@SpringBootTest
class SpringbootRedisApplicationTests {
@Autowired
UserRedis userRedis;
@Test
void contextLoads() {
userRedis.deleteAll();
Department department = new Department();
department.setName("开发部");
Role role = new Role();
role.setName(" admin");
User user = new User();
user.setName("user");
user.setCreateTime(new Date());
user.setDepartment(department);
List roles=new ArrayList<>();
roles.add(role);
user.setRoles(roles);
userRedis.put("1",user);
userRedis.expire("1",1, TimeUnit.MINUTES);
User userOut = userRedis.get("1");
System.out.println(userOut);
}
}
虽然 springdata 足够智能和强大,但国内以腾讯阿里为首的 mybatis 大军仍然弃之不顾。为了满足相关人员的开发需求。springboot 对 mybatis 也有较好的支持。同时也简化了 mybatis 相关繁琐的配置。基本配置如下:
org.mybatis.spring.boot
mybatis-spring-boot-starter
1.3.2
mybatis:
mapper-locations: classpath:mappers/*.xml
spring:
datasource:
url: jdbc:mysql:///unifiedquery?characterEncoding=utf-8&useSSL=false
username: root
password: root
driver-class-name: com.mysql.jdbc.Driver
@SpringBootApplication
@MapperScan("cn.hx.dao")
public class QueryApplication {
public static void main(String[] args) {
SpringApplication.run(QueryApplication.class, args);
}
}
若需要显示 sql,只需如下简单配置即可
logging:
level:
cn.hx.dao: debug
cn.hx.dao 是 mybatis 接口的位置。
Thymeleaf [taim li:f] 是目前最流行的后端引擎之一。虽然现在很多开发,都采用了前后端完全分离的模式,即后端只提供数据接口,前端通过 AJAX 请求获取数据,完全不需要用的后端模板引擎。这种方式的优点在于前后端完全分离,并且随着近几年前端工程化工具和 MVC 框架的完善,使得这种模式的维护成本相对来说也更加低一点。但是这种模式不利于 SEO(搜索引擎优化 Search Engine Optimization),并且在性能上也会稍微差一点。
org.springframework.boot
spring-boot-starter-thymeleaf
spring:
thymeleaf:
prefix: classpath:/templates/ #模范文件资源位置
cache: false #是否开启缓存
suffix: .html #文件后缀名
mode: HTML #模板文件类型
prefix:指定模板所在的目录
cache:是否缓存,开发模式下设置为 false,避免改了模板还要重启服务器,线上设置为 true,可以提高性能。
序号
标题
摘要
创建时间
th:标签 |
说明 |
th:insert |
页面片段包含(类似JSP中的include标签) |
th:replace |
页面片段包含(类似JSP中的include标签) |
th:each |
元素遍历(类似JSP中的c:forEach标签) |
th:if |
条件判断,如果为真 |
th:unless |
条件判断,如果为假 |
th:switch |
条件判断,进行选择性匹配 |
th:case |
条件判断,进行选择性匹配 |
th:object |
变量声明 |
th:with |
变量声明 |
th:attr |
通用属性修改 |
th:attrprepend |
通用属性修改,将计算结果追加前缀到现有属性值 |
th:attrappend |
通用属性修改,将计算结果追加后缀到现有属性值 |
th:value |
属性值修改,指定标签属性值 |
th:href |
用于设定链接地址 |
th:src |
用于设定链接地址 |
th:text |
用于指定标签显示的文本内容 |
th:utext |
用于指定标签显示的文本内容,对特殊标签不转义 |
th:fragment |
声明片段 |
th:remove |
移除片段 |
与thymeleaf 作用相同,在 web 开发中可能还会用到Freemarker 后端模板引擎,他的原理和thymeleaf 相同,只是语法上有稍微的区别。
官方文档:Getting Started with template writing - FreeMarker 中文官方参考手册 (foofun.cn)
org.springframework.boot
spring-boot-starter-freemarker
spring:
freemarker:
template-loader-path: classpath:/templates/
suffix: .ftl
content-type: text/html
charset: UTF-8
settings:
number_format: '0.##'
除了 settings 外,其他的配置选项和 thymeleaf 类似。settings 会对 freemarker 的某些行为产生影响,如日期格式化,数字格式化等,感兴趣的可以参考官网提供的说明。
文章列表
Freemarker 模板引擎
序号
标题
摘要
创建时间
<#list list as article>
${article.id}
${article.title}
${article.summary}
${article.createTime?string('yyyy-MM-dd hh:mm:ss')}
#list>
提起 java Web 开发绕不开的一个技术就是 JSP,因为目前市面上仍有很多的公司在使用 JSP,所以本节就来介绍一下 Spring Boot 怎么集成 JSP 开发。springboot 整合 jsp 有如下几步:创建 war 项目结构。
javax.servlet
javax.servlet-api
provided
javax.servlet
jstl
org.apache.tomcat.embed
tomcat-embed-jasper
spring.mvc.view.suffix=.jsp
spring.mvc.view.prefix=/WEB-INF/jsp/
server.servlet.jsp.init-parameters.development=true
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" %>
demo
序号
标题
摘要
创建时间
${article.id}
${article.title}
${article.summary}
${article.createTime}
WebSocket 协议是基于 TCP 的一种新的网络协议。它实现了浏览器与服务器全双工(full-duplex)通信,即允许服务器主动发送信息给客户端。
WebSocket 协议支持客户端与远程服务器之间进行全双工通信。用于此的安全模型是 Web 浏览器常用的基于原始的安全模式。 协议包括一个开放的握手以及随后的 TCP 层上的消息帧。
WebSocket 协议之前,双工通信是通过不停发送 HTTP 请求,从服务器拉取更新来实现,这导致了效率低下,同时增加不必要的服务器压力,WebSocket 解决了这个问题。springboot 整合 websocket 有以下几个步骤:
org.springframework.boot
spring-boot-starter-websocket
注:如果打 war 包部署到 tomcat 内运行时,则不能配置 ServerEndpointExporter bean,打成 jar 包独立运行时必须有该 bean
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
服务类
import org.springframework.stereotype.Component;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
@Component
@ServerEndpoint(value = "/ws/{userId}")
public class ChatServer {
private static Map routeTab = new HashMap<>();
@OnOpen
public void onOpen(@PathParam("userId") String userId, Session session) throws IOException {
routeTab.put(userId, session);
}
@OnClose
public void onClose(@PathParam("userId") String userId) throws IOException {
routeTab.remove(userId);
}
@OnMessage
public void onMessage(String message) throws IOException {
for (String s : routeTab.keySet()) {
Session session = routeTab.get(s);
session.getBasicRemote().sendText(message);
}
}
@OnError
public void onError(Throwable error) {
error.printStackTrace();
}
}
前端按照 websocket 规范编写即可
聊天