前言
scaffold: 脚手架的意思,是一款封装了一些通用组件的,让Spring Boot快速开发的工具集。1. Scaffold组件图谱
2. 项目信息
项目地址: https://github.com/xkcoding/scaffold
目录结构:
scaffold
├── scaffold-bom scaffold依赖管理
├── scaffold-common 通用工具类
├── scaffold-launcher 通用启动器
├── scaffold-log 日志包
├── scaffold-swagger swagger配置
├── scaffold-test 通用单元测试
├── scaffold-web 通用web配置
├── scaffold-code 通用验证码组件
├── scaffold-notification 通用通知组件
└── scaffold-codegen 代码生成器
版本更新记录:CHANGELOG
3.安装方式
<dependency>
<groupId>com.xkcoding</groupId>
<artifactId>scaffold-${模块名}</artifactId>
<version>${最新版本}</version>
</dependency>
4. 各个模块功能介绍及使用方法
4.1. scaffold-bom 版本依赖管理
主要功能
用于统一管理 scaffold 的版本,不需要用户控制各个模块的版本依赖
使用方法
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.xkcoding</groupId>
<artifactId>scaffold-bom</artifactId>
<version>${scaffold-bom.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!--不需要定义版本-->
<dependency>
<groupId>com.xkcoding</groupId>
<artifactId>scaffold-${模块名}</artifactId>
</dependency>
</dependencies>
4.2. scaffold-launcher 启动器模块
主要功能
-
环境划分:dev(开发)、test(测试)、prod(正式),默认 dev。
-
启动器配置,代码中可以注入
ScaffoldProperties来读取启动器的一些配置信息,比如env等。scaffold.prop可以在配置文件中自定义配置。然后再在代码中使用ScaffoldProperties读取。 -
插件扩展,更加方便的去注入一些通用配置,降低使用难度。插件扩展基于 java SPI 技术,关于 java SPI 具体使用可以百度。
注意:如果使用了 scaffold-launcher,单元测试需要使用 scaffold-test 组件,使用方法请看文档
使用方法
① 创建spring boot 项目
② 添加依赖
推荐使用
scaffold-bom管理scaffold模块版本,使用方法请看文档
<dependency>
<groupId>com.xkcoding</groupId>
<artifactId>scaffold-launcher</artifactId>
<version>${scaffold-launcher.version}</version>
</dependency>
③ 修改启动类代码
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
// SpringApplication.run(DemoApplication.class, args);
ScaffoldApplication.run("demo", DemoApplication.class, args);
}
}
④ 设置使用环境
-
java命令行:
java -jar app.jar --spring.profiles.active=dev -
JAVA_OPS:
set JAVA_OPTS="-Dspring.profiles.active=test" -
注解方式(代码层面,junit单元测试非常实用):
@ActiveProfiles({"dev","test"}) -
ENV方式:系统环境变量SPRING_PROFILES_ACTIVE(注意:是大写)
-
idea开发场景下设置参考下图
⑤ 自定义配置项
ScaffoldProperties.java
| 配置项 | 默认值 | 说明 |
|---|---|---|
| scaffold.env | dev | 【只读】scaffold 环境变量,方便在代码中获取,设置无效 |
| scaffold.name | 无 | 【只读】当前服务名称 |
| scaffold.is-local | false | 【只读】判断是否为 本地开发环境 |
| scaffold.prop | 无 | 装载自定义配置 scaffold.prop.xxx |
在 application.yml 中配置
scaffold:
prop:
author: xkcoding
blog: https://xkcoding.com
使用配置
@Autowired
private ScaffoldProperties scaffoldProperties;
public void test() {
String author = scaffoldProperties.get("author");
String blog = scaffoldProperties.get("blog");
// .....
}
⑥ 自定义启动插件
实现 LauncherService,重写 launcher 方法,下面是 LauncherService 的代码。
public interface LauncherService {
/**
* 启动时 处理 SpringApplicationBuilder
*
* @param builder SpringApplicationBuilder
* @param appName 服务名
* @param profile 配置名
* @param isLocalDev 是否本地开发
*/
void launcher(SpringApplicationBuilder builder, String appName, String profile, boolean isLocalDev);
}
编写 SPI 文件放置到 resources 目录下,文件路径和文件名 META-INF/services/com.xkcoding.launcher.service.LauncherService。
内容为你编写的插件完整类名,例如:com.xxxx.CustomLauncherServiceImpl。
4.3. scaffold-common 通用工具
主要功能
- 通用API层返回格式封装
- 通用分页查询参数封装
- 常用工具类封装
使用方法
① 添加依赖
推荐使用
scaffold-bom管理scaffold模块版本,使用方法请看文档
<dependency>
<groupId>com.xkcoding</groupId>
<artifactId>scaffold-common</artifactId>
<version>${scaffold-common.version}</version>
</dependency>
② 统一API返回格式
类名:
com.xkcoding.common.api.R
判断返回是否为成功:R.isSuccess(R result);
判断返回是否为不成功:R.isNotSuccess(R result);
获取data:R.getData(R result);
返回成功:R.success();
成功-携带数据:R.success(Object data);
根据状态返回成功或者失败:R.status(boolean status, String msg);
根据状态返回成功或者失败:R.status(boolean status, IResultCode sCode);
返回失败信息:R.fail();
返回失败信息,用于 web:R.fail(String msg);
返回失败信息:R.fail(IResultCode rCode);
返回失败信息:R.fail(IResultCode rCode, String msg);
返回失败信息:R.fail(int code, String msg);
返回失败信息-携带数据:R.fail(IResultCode rCode, T data);
③ 状态码接口
类名:
com.xkcoding.common.api.IResultCode
④ 内置状态码
| 枚举值 | 状态码 | 描述 |
|---|---|---|
| ResultCode.SUCCESS | 200 | 操作成功 |
| ResultCode.FAILURE | -1 | 业务异常 |
| ResultCode.UN_AUTHORIZED | 401 | 请求未授权 |
| ResultCode.NOT_FOUND | 404 | 没找到请求 |
| ResultCode.MSG_NOT_READABLE | 400 | 消息不能读取 |
| ResultCode.METHOD_NOT_SUPPORTED | 405 | 不支持当前请求方法 |
| ResultCode.MEDIA_TYPE_NOT_SUPPORTED | 415 | 不支持当前媒体类型 |
| ResultCode.REQ_REJECT | 403 | 请求被拒绝 |
| ResultCode.INTERNAL_SERVER_ERROR | 500 | 服务器异常 |
| ResultCode.PARAM_MISS | 400 | 缺少必要的请求参数 |
| ResultCode.PARAM_TYPE_ERROR | 400 | 请求参数类型错误 |
| ResultCode.PARAM_BIND_ERROR | 400 | 请求参数绑定错误 |
| ResultCode.PARAM_VALID_ERROR | 400 | 参数校验失败 |
⑤ 常用工具类
已经内置 hutool 工具类,额外新增TreeUtil(树节点操作)、IpUtil(获取IP信息)、UrlUtil(URL编解码)、Ip2AddressUtil(根据IP获取地址信息)、WebUtil(Web 工具类,操作 request/response/cookie)、ServletUtil(Servlet 工具类)等
4.4. scaffold-log 通用日志组件
主要功能
- 对操作日志进行封装
@ApiLog,自定义操作人,以及自定义日志处理 - 基于
Spring Event异步处理日志信息
使用方法
① 添加依赖
推荐使用
scaffold-bom管理scaffold模块版本,使用方法请看文档
<dependency>
<groupId>com.xkcoding</groupId>
<artifactId>scaffold-log</artifactId>
<version>${scaffold-log.version}</version>
</dependency>
② application.yml 中开启操作日志拦截
scaffold:
log:
enabled: true
③ Controller层添加注解@ApiLog
@GetMapping("/")
@ApiLog("测试操作")
public R<User> test(@RequestBody User user) {
return R.data(user);
}
④ 自定义日志操作
创建一个类,继承 DefaultScaffoldLogServiceImpl(也可以实现LogService接口) 重写对应方法,不需要全部重写,只需要重写部分即可
public class CustomLogServiceImpl extends DefaultScaffoldLogServiceImpl {
/**
* 保存操作日志
*
* @param logApi 操作日志实体
* @return 是否保存成功
*/
@Override
public R<Boolean> saveApiLog(LogApi logApi) {
// 自定义操作,比如保存到数据库中
return super.saveApiLog(logApi);
}
/**
* 保存错误日志
*
* @param logError 错误日志实体
* @return 是否保存成功
*/
@Override
public R<Boolean> saveErrorLog(LogError logError) {
// 自定义操作,比如保存到数据库中
return super.saveErrorLog(logError);
}
/**
* 保存自定义日志
*
* @param logCustom 自定义日志实体
* @return 是否保存成功
*/
@Override
public R<Boolean> saveCustomLog(LogCustom logCustom) {
// 自定义操作,比如保存到数据库中
return super.saveCustomLog(logCustom);
}
}
再将自定义的日志操作放到 Spring 容器中
@Configuration
public class LogConfig {
@Bean
public LogService logService(){
return new CustomLogServiceImpl();
}
}
注意:如果当前
scaffold-launcher配置的spring.profiles.active环境是dev、test则日志实体里会拦截到请求中的参数等信息,如果是prod则不会拦截请求参数
⑤ 自定义当前操作人
scaffold-log 中默认当前操作人为 匿名用户 ,用户可以通过实现 SecurityService 接口,重写 getCurrentUserName 实现自己的业务逻辑,之后务必加到 Spring 容器中,操作同上,不再赘述。
4.5. scaffold-swagger 通用swagger配置
主要功能
集成swagger的自动装配,方便集成
使用方法
① 添加依赖
推荐使用
scaffold-bom管理scaffold模块版本,使用方法请看文档
<dependency>
<groupId>com.xkcoding</groupId>
<artifactId>scaffold-swagger</artifactId>
<version>${scaffold-swagger.version}</version>
</dependency>
② 配置swagger基础信息
#swagger配置信息
swagger:
title: Demo 接口文档系统
description: Demo 接口文档系统
version: 1.0.0
license: Powered By xkcoding
# 注意这里必须配置你当前项目的包名
base-package: com.example.demo.controller
contact:
name: Yangkai.Shen
email: 237497819@qq.com
url: https://xkcoding.com
③ 启动项目
访问 http://${host}:${port}/${contextPath}/doc.html,比如:http://localhost:8080/demo/doc.html
注意:如果当前
scaffold-launcher配置的spring.profiles.active环境是dev、test则可以访问接口文档,如果是prod则访问不到。
4.6. scaffold-test 通用单元测试组件
主要功能
由于在 scaffold-launcher 里设置了一些启动参数,所以提供了 scaffold-test 方便在单元测试的时候使用。
使用方法
① 添加依赖
推荐使用
scaffold-bom管理scaffold模块版本,使用方法请看文档
<dependency>
<groupId>com.xkcoding</groupId>
<artifactId>scaffold-test</artifactId>
<version>${scaffold-test.version}</version>
</dependency>
② 单元测试一
采用 @RunWith(ScaffoldSpringRunner.class)。
@SpringBootTest
@ScaffoldTest(profile = "dev",appName = "demo-test")
@RunWith(ScaffoldSpringRunner.class)
public class DemoTests {
@Test
public void test() {
}
}
③单元测试二
继承 ScaffoldBaseTest。
@SpringBootTest
@ScaffoldTest(profile = "dev",appName = "demo-test")
public class DemoTests extends ScaffoldBaseTest {
@Test
public void test() {
}
}
4.7. scaffold-web 通用web配置
主要功能
- Redis序列化配置
- Jackson序列化配置
- 通用全局异常拦截配置,未知异常触发 Event 事件,由
scaffold-log监听处理 dev、test环境下打印请求明细,方便代码调试- 异步线程池通用配置
- Mybatis-Plus 配置,
dev、test环境下启用SQL执行效率插件
使用方法
① 添加依赖
推荐使用
scaffold-bom管理scaffold模块版本,使用方法请看文档
<dependency>
<groupId>com.xkcoding</groupId>
<artifactId>scaffold-web</artifactId>
<version>${scaffold-web.version}</version>
</dependency>
② 异步线程池配置
| 配置项 | 默认值 | 说明 |
|---|---|---|
| scaffold.async.corePoolSize | 2 | 异步核心线程数,默认:2 |
| scaffold.async.maxPoolSize | 50 | 异步最大线程数,默认:50 |
| scaffold.async.queueCapacity | 10000 | 队列容量,默认:10000 |
| scaffold.async.keepAliveSeconds | 300 | 线程存活时间,默认:300 |
③ 监控打印请求
2019-03-13 15:38:11.650 INFO 6846 --- [ XNIO-1 task-2] com.xkcoding.web.logger.RequestLogAspect : RequestLogAspect.java:157 -
================ Request Start ================
===> POST: /demo/ Parameters: {"name":"","id":0,"age":0,"email":""}
===headers=== Origin : http://localhost:8080
===headers=== Cookie : Hm_lvt_bc38887aa5588add05a38704342ad7e8=1549855562; Hm_lvt_521f6d48d3fa40ce529ba993fc1a46b4=1548829297,1551345825; scroll-cookie=1900|/
===headers=== Request-Origion : SwaggerBootstrapUi
===headers=== Accept : */*
===headers=== X-Requested-With : XMLHttpRequest
===headers=== User-Agent : Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.81 Safari/537.36 QQBrowser/4.5.121.400
===headers=== Connection : keep-alive
===headers=== Referer : http://localhost:8080/demo/doc.html
===headers=== Host : localhost:8080
===headers=== Accept-Encoding : gzip, deflate, br
===headers=== Accept-Language : zh-CN,zh;q=0.9
===headers=== Content-Length : 50
===headers=== Content-Type : application/json
===Result=== {"msg":"操作成功","code":200,"data":{"name":"","id":0,"age":0,"email":""},"success":true}
<=== POST: /demo/ (2 ms)
================ Request End ================
4.8. scaffold-code 通用验证码组件
主要功能
- 随机验证码,可配置随机验证码的字符串、长度、宽度、高度
- 简单算术验证码,可配置验证码宽度、高度
使用方法
注意:验证码组件需要配合缓存使用,建议使用Redis
① 添加依赖
推荐使用
scaffold-bom管理scaffold模块版本,使用方法请看文档
<dependency>
<groupId>com.xkcoding</groupId>
<artifactId>scaffold-code</artifactId>
<version>${scaffold-code.version}</version>
</dependency>
② 在 application.yml 中开启验证码,同时设置Redis相关配置
scaffold:
code:
enabled: true
spring:
redis:
host: localhost
# 连接超时时间(记得添加单位,Duration)
timeout: 10000ms
# Redis默认情况下有16个分片,这里配置具体使用的分片
# database: 0
lettuce:
pool:
# 连接池最大连接数(使用负值表示没有限制) 默认 8
max-active: 8
# 连接池最大阻塞等待时间(使用负值表示没有限制) 默认 -1
max-wait: -1ms
# 连接池中的最大空闲连接 默认 8
max-idle: 8
# 连接池中的最小空闲连接 默认 0
min-idle: 0
cache:
# 一般来说是不用配置的,Spring Cache 会根据依赖的包自行装配
type: redis
③ 自定义配置项
| 配置项 | 默认值 | 说明 |
|---|---|---|
| scaffold.code.enabled | false | 是否开启验证码 |
| scaffold.code.cookie-name | scaffold-code | 验证码默认cookie名 |
| scaffold.code.cache-name | SCAFFOLD::CODE | 验证码默认缓存 |
| scaffold.code.pool | ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 | 验证码生成策略,默认:大写字母+数字 |
| scaffold.code.width | 108 | 验证码宽度 |
| scaffold.code.height | 40 | 验证码高度 |
| scaffold.code.length | 4 | 验证码长度 |
④ 示例代码
@RestController
@Slf4j
public class DemoController {
@Autowired
private ScaffoldCode scaffoldCode;
@GetMapping(value = "/code/math.jpg", produces = MediaType.IMAGE_JPEG_VALUE)
public ResponseEntity<Resource> mathCode(HttpServletResponse response) {
return scaffoldCode.generateMathCode(response);
}
@GetMapping("/verify/math/{code}")
public R<Boolean> verifyMathCode(HttpServletResponse response, @PathVariable String code) {
boolean flag = scaffoldCode.validateMath(response, code);
return R.status(flag, "验证码错误");
}
@GetMapping(value = "/code/random.jpg", produces = MediaType.IMAGE_JPEG_VALUE)
public ResponseEntity<Resource> randomCode(HttpServletResponse response) {
return scaffoldCode.generateRandomCode(response);
}
@GetMapping("/verify/random/{code}")
public R<Boolean> verifyCode(HttpServletResponse response, @PathVariable String code) {
boolean flag = scaffoldCode.validateRandom(response, code);
return R.status(flag, "验证码错误");
}
}
4.9. scaffold-notification 通用通知组件
主要功能
-
钉钉机器人通知,支持多种消息类型,包括text类型、link类型、markdown类型、整体跳转ActionCard类型、独立跳转ActionCard类型、FeedCard类型
-
短信通知,集成阿里大鱼短信服务,稳定、快速
-
邮件通知,支持多种类型邮件,包括简单文本邮件、HTML模板邮件、附件、静态资源
使用方法
① 添加依赖
推荐使用
scaffold-bom管理scaffold模块版本,使用方法请看文档
<dependency>
<groupId>com.xkcoding</groupId>
<artifactId>scaffold-notification</artifactId>
<version>${scaffold-notification.version}</version>
</dependency>
② 在 application.yml 中开启不同类型的通知配置,如果使用邮件通知类型,一定需要额外配置邮箱信息
scaffold:
notification:
dingtalk:
enabled: true
# 钉钉机器人 webhook 地址
webhook: https://oapi.dingtalk.com/robot/send?access_token=xxxxxxxx
email:
enabled: true
aliyun:
enabled: true
# 阿里云 AccessKey ID
access-key: ***********
# 阿里云 Access Key Secret
secret-key: ***********
# 参见阿里大鱼短信服务的模板管理,格式为:模版名称:模版CODE,注意模板名称不能为中文
channels:
article_notification: SMS_160576086
spring:
mail:
# 邮箱 smtp 服务器地址
host: smtp.qq.com
# 邮箱 smtp 服务器端口,一般存在ssl和非ssl的区别,比如QQ邮箱ssl端口为465,非ssl端口为587
port: 465
# 你的邮箱地址
username: ********@qq.com
# 你的邮箱密码
password: ********
protocol: smtp
test-connection: true
default-encoding: UTF-8
properties:
mail.smtp.auth: true
# 下面三项根据自己邮箱是否使用ssl端口来设置,使用ssl为true,不使用ssl为false
mail.smtp.starttls.enable: true
mail.smtp.starttls.required: true
mail.smtp.ssl.enable: true
③ 自定义配置项
| 配置项 | 默认值 | 说明 |
|---|---|---|
| scaffold.notification.dingtalk.enabled | false | 是否启用钉钉机器人通知 |
| scaffold.notification.dingtalk.webhook | 无 | 钉钉机器人webhook地址 |
| scaffold.notification.aliyun.enabled | false | 是否启用阿里大鱼短信通知 |
| scaffold.notification.aliyun.access-key | 无 | 阿里云 AccessKey |
| scaffold.notification.aliyun.secret-key | 无 | 阿里云 AccessSecret |
| scaffold.notification.aliyun.channels | 无 | 模板与模板CODE的映射关系,参见阿里大鱼短信服务的模板管理,格式为:模版名称:模版CODE,注意模板名称不能为中文 |
| scaffold.notification.email.enabled | false | 是否启用邮箱通知,如果启用,一定需要额外配置邮箱信息 |
| scaffold.notification.email.prefix | classpath:/email/ | 邮件模板位置 |
| scaffold.notification.email.suffix | .html | 邮件模板后缀 |
④ 示例代码
在 application.yml 中,配置好上述配置后,可参考如下代码,实现钉钉、短信、邮箱三种类型的消息通知
这里钉钉消息,只演示了 text 类型和 link 类型,其余类型,可以举一反三实现,官方文档地址:https://open-doc.dingtalk.com/microapp/serverapi2/qf2nxq
package com.xkcoding.scaffold.demo;
import cn.hutool.core.io.resource.ResourceUtil;
import com.google.common.collect.Maps;
import com.xkcoding.scaffold.notification.constants.EmailType;
import com.xkcoding.scaffold.notification.model.dingtalk.Attention;
import com.xkcoding.scaffold.notification.model.dingtalk.Link;
import com.xkcoding.scaffold.notification.model.dingtalk.LinkDingTalkMessage;
import com.xkcoding.scaffold.notification.model.dingtalk.TextDingTalkMessage;
import com.xkcoding.scaffold.notification.model.email.EmailMessage;
import com.xkcoding.scaffold.notification.model.sms.SmsMessage;
import com.xkcoding.scaffold.notification.service.dingtalk.DingTalkMessageSender;
import com.xkcoding.scaffold.notification.service.email.EmailMessageSender;
import com.xkcoding.scaffold.notification.service.sms.SmsAliyunMessageSender;
import com.xkcoding.scaffold.test.ScaffoldBaseTest;
import com.xkcoding.scaffold.test.ScaffoldTest;
import lombok.extern.slf4j.Slf4j;
import org.assertj.core.util.Lists;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.io.File;
import java.net.URL;
import java.util.List;
import java.util.Map;
/**
* <p>
* 通知测试
* </p>
*
* @package: com.xkcoding.scaffold.demo
* @description: 通知测试
* @author: yangkai.shen
* @date: Created in 2019-03-18 22:59
* @copyright: Copyright (c) 2019
* @version: V1.0
* @modified: yangkai.shen
*/
@SpringBootTest
@ScaffoldTest(profile = "prod", appName = "scaffold-notification-test")
@Slf4j
public class NotificationTest extends ScaffoldBaseTest {
@Autowired
private DingTalkMessageSender dingTalkMessageSender;
@Autowired
private EmailMessageSender emailMessageSender;
@Autowired
private SmsAliyunMessageSender smsAliyunMessageSender;
@Test
public void testTextDingTalk() {
TextDingTalkMessage textDingTalkMessage = new TextDingTalkMessage();
textDingTalkMessage.setText(new TextDingTalkMessage.Text("你好,我是钉钉机器人"));
textDingTalkMessage.setAt(new Attention(Lists.newArrayList( "17326075631"), false));
dingTalkMessageSender.execute(textDingTalkMessage);
}
@Test
public void testLinkDingTalk(){
LinkDingTalkMessage linkDingTalkMessage = new LinkDingTalkMessage();
Link link = new Link();
link.setMessageUrl("https://xkcoding.com");
link.setText("代码日记更新博客了。。。。。");
link.setTitle("博客更新");
linkDingTalkMessage.setLink(link);
dingTalkMessageSender.execute(linkDingTalkMessage);
}
@Test
public void testSimpleEmail() {
EmailMessage emailMessage = new EmailMessage();
emailMessage.setEmailType(EmailType.SIMPLE);
emailMessage.setTos(Lists.newArrayList("237497819@qq.com"));
emailMessage.setFrom("xkcoding");
emailMessage.setSubject("简单邮件标题");
emailMessage.setContent("这是一封简单邮件的内容");
emailMessageSender.execute(emailMessage);
}
@Test
public void testMimeEmail() {
EmailMessage emailMessage = new EmailMessage();
emailMessage.setEmailType(EmailType.MIME);
emailMessage.setTos(Lists.newArrayList("237497819@qq.com"));
emailMessage.setFrom("xkcoding");
emailMessage.setSubject("复杂邮件标题");
// 设置模板,位置:resources/email/template.html
emailMessage.setTemplate("template");
// 设置变量
Map<String, Object> params = Maps.newHashMap();
params.put("project", "Spring Boot Demo");
params.put("author", "Yangkai.Shen");
params.put("url", "https://github.com/xkcoding/spring-boot-demo");
emailMessage.setParams(params);
// 设置附件,文件位置:resources/db/data-h2.sql、resources/db/schema-h2.sql
URL data = ResourceUtil.getResource("db/data-h2.sql");
URL schema = ResourceUtil.getResource("db/schema-h2.sql");
List<EmailMessage.Attachment> attachments = Lists.newArrayList(new EmailMessage.Attachment("data.sql", new File(data
.getPath())), new EmailMessage.Attachment("schema.sql", new File(schema.getPath())));
emailMessage.setAttachments(attachments);
// 设置静态资源,图片位置:resources/static/favicon.png
URL favicon = ResourceUtil.getResource("static/favicon.png");
List<EmailMessage.StaticResource> staticResources = Lists.newArrayList(new EmailMessage.StaticResource("favicon", new File(favicon
.getPath())));
emailMessage.setStaticResources(staticResources);
emailMessageSender.execute(emailMessage);
}
@Test
public void testSmsAliyunMessageSender() {
SmsMessage smsMessage = new SmsMessage();
smsMessage.setMobile("17326075631");
Map<String, String> params = Maps.newHashMap();
// 根据短信模板里的变量设置参数
// 此处我的模板内容为:尊敬的读者,代码日记发布文章《${article}》,欢迎阅读!
params.put("article", "scaffold-doc");
smsMessage.setParams(params);
smsMessage.setSignName("代码日记");
smsMessage.setTemplate("article_notification");
smsMessage.setType("短信通知");
smsAliyunMessageSender.execute(smsMessage);
}
}
邮件模板,位置:resources/email/template.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8" />
<title>SpringBootDemo(入门SpringBoot的首选Demo)</title>
<style>
body {
text-align: center;
margin-left: auto;
margin-right: auto;
}
#welcome {
text-align: center;
}
</style>
</head>
<body>
<div id="welcome">
<div style="text-align: center; padding: 10px">
<img src="cid:favicon" />
</div>
<h3>
欢迎使用 <span th:text="${project}"></span> - Powered By
<span th:text=" ${author}"></span>
</h3>
<span th:text="${url}"></span>
<div style="text-align: center; padding: 10px">
<a
style="text-decoration: none;"
href="#"
th:href="@{${url}}"
target="_bank"
>
<strong>spring-boot-demo,入门Spring Boot的首选Demo!:)</strong>
</a>
</div>
<div style="text-align: center; padding: 4px">
如果对你有帮助,请任意打赏
</div>
<div style="width: 100%;height: 100%;text-align: center;display: flex">
<div style="flex: 1;"></div>
<div style="display: flex;width: 400px;">
<div style="flex: 1;text-align: center;">
<div>
<img
width="180px"
height="180px"
src="http://xkcoding.com/resources/wechat-reward-image.png"
/>
</div>
<div>微信打赏</div>
</div>
<div style="flex: 1;text-align: center;">
<div>
<img
width="180px"
height="180px"
src="http://xkcoding.com/resources/alipay-reward-image.png"
/>
</div>
<div>支付宝打赏</div>
</div>
</div>
<div style="flex: 1;"></div>
</div>
</div>
</body>
</html>
⑤ 效果图
钉钉消息
简单邮件
复杂邮件
短信
⑥ 文档参考
- 钉钉机器人:https://open-doc.dingtalk.com/microapp/serverapi2/qf2nxq
- 阿里大鱼:https://help.aliyun.com/document_detail/101300.html
4.10. scaffold-codegen 代码生成器
主要功能
- 支持生成前端api、Controller、Mapper、Service、Model代码,暂时仅支持mysql数据源
- Controller、Model代码集成swagger注解
- 提供前端下载页面
使用方法
① 添加依赖
推荐使用
scaffold-bom管理scaffold模块版本,使用方法请看文档
<dependency>
<groupId>com.xkcoding</groupId>
<artifactId>scaffold-codegen</artifactId>
<version>${scaffold-codegen.version}</version>
</dependency>
② 自定义配置项
| 配置项 | 默认值 | 说明 |
|---|---|---|
| scaffold.codegen.author | com.xkcoding | 基础包名 |
| scaffold.codegen.base-package-name | codegen | 模块名 |
| scaffold.codegen.module-name | Yangkai.Shen | 作者 |
| scaffold.codegen.table-prefix | tb_ | 表前缀(类名不会包含表前缀) |
③ 在application.yml中添加数据源信息
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/spring-boot-demo
username: root
password: root
④ 启动项目,访问 http://localhost:8080/demo/codegen.html
注意:如果当前
scaffold-launcher配置的spring.profiles.active环境是dev、test则可以访问接口文档,如果是prod则访问不到。
TODO
- scaffold-cache 通用基于redis或者ehcache的缓存配置,设计缓存key,保证全系统key统一
- scaffold-auth 通用认证授权配置