SpringBoot(二) - 核心配置文件 (+ 邮件发送 和 短信发送)
1、application.properties 和 application.yml 配置文件格式区别
1.1 文件格式
application.properties
# 端口号
server.port=8096
application.yml
# 服务端口
server:
port: 8096
1.2 区别
- properties的优先级高于yml,同等配置,高优先级会覆盖低优先级,不同的配置时互补配置(增补,不管哪个配置文件中有,都可以生效);
- properties的核心语法是:通过 . 作为层级分隔符,配置值是用 = ,比如 server.port=9096
yml的核心语法是:通过层级+缩进的方式,同一给等级,缩进是相同的,配置使用key: value方式- server:
port: 8096 #注意值前面必须有空格
- server:
- 小结:yml格式配置,可以简化配置内容,层次清晰,更适合作为核心配置文件;
2、自定义配置
2.1 配置信息 yml 语法
注意:值前面必须有空格;
2.1.1 基本类型数据
user:
userId: kh96
user-Name: gala # 支持松散绑定
user_age: 17
adult: true # 是否成年
salary: 9696.0
userTel: 13501020304
birthday: 2002/10/11 10:10:10
email: kh96@163.com
2.1.2 数组,List,Set
user:
hobbies: # 爱好 list集合
- springboot
- linux
- mysql
- ssm
- jvaweb
- springvloud
#行内写法
#hobbies:[springboot,linux,mysql,ssm,jvaweb,springvloud]
2.1.3 Map
user:
carMap: # 爱车 map 集合
bnm: 宝马325
audi: 奥迪A41
benz: 奔驰C200
#行内写法
#carMap:{bnm: 宝马325;audi: 奥迪A41;benz: 奔驰C200}
2.1.4 实体参数
user:
userRole:
role-id: R96 ${random.uuid} #${}可以去一些内置的自定义参数
role_name: root
2.1.5 值的写法
2.1.5.1 单引号:
会转义特殊字符。
user:
msg: '你好!\n小可爱!'
输出:
你好!\n小可爱!
2.1.5.2 双引号:
不会转义字符里的特殊字符,特殊字符仍然是本身的意思
user:
msg: "你好!\n小可爱!"
输出:
你好!
小可爱!
2.2 获取 配置信息
2.2.1 批量自动读取 @ConfigurationProperties(prefix = "xxx")
使用注解@ConfigurationProperties(prefix = "xxx") ,必须配合@Component 注解获取在核心启动类上使用 @EnableConfigurationProperties(配置属性读取类.class)使用;
特点:支持松散绑定(可以自动识别驼峰,-,_),支持复杂类型绑定(实体,集合-list,set,array,map等),支持数据格式校验;
@Component + @ConfigurationProperties(prefix = "user")
或
@Component
+
@EnableConfigurationProperties(UserProperties.class) //写在主启动类上
2.2.1.1 UserProperties
@Data
@Component //第一个写法,使用普通组件
@ConfigurationProperties(prefix = "user") //不能单独使用,必须配合@EnableConfigurationProperties 或指定为spring容器中的普通组件
public class UserProperties {
//用户编号
private String userId;
//用户名
private String userName;
//用户年龄
private Integer userAge;
//是否成年
private boolean adult;
//工资
private double salary;
//联系方式
private String userTel;
//生日
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8") //springMVC将将数据转成json格式,时间格式规则
private Date birthday;
//用户角色
private UserRole userRole; //实体参数
//爱好
private List<String> hobbies;
//爱车
private Map<String,String> carMap;
//邮箱
@Email //邮箱格式校验
private String email;
}
2.2.1.1.2 运行结果:
2.2.2 单个手动读取 @Value("${xxx.xxx}")
用法:使用注解@Value("${xxx.xxx}");
特点:写法灵活,可以指定默认值等,但是不支持松散绑定,单个读取的配置要求指定的读取属性key必须和自定义配置一直,否者报错;
@Component + @ConfigurationProperties(prefix = "user")
2.2.2.1 UserProperties
@Data
@Component
@PropertySource(value = "classpath:user.properties")
//@EnableConfigurationProperties(UserProperties.class) //第二种方式,核心启动类上,增加指定开启自动配置读取,但是一般不怎么使用,且容易忘记
public class UserProperties {
//用户编号
@Value("${user.userId}")
private String userId;
//用户名
@Value("${user.user-Name}")
private String userName;
//昵称
@Value("#{userValues.userName}") //获取的是容器中已有的实体的值
//@Value("#{'xiaoming'}") //可以赋默认值
private String niceName;
//用户年龄
@Value("${user.user_age}")
// @Value("16") //直接赋值
private Integer userAge;
//是否成年
@Value("#{(${user.user_age}>17)?true:false}") //spel 表达式
private boolean adult;
//工资
@Value("#{${user.salary}*10}") //#{} 和 ${}套用
private double salary;
//联系方式
@Value("${user.userTel}")
private String userTel;
//生日
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8") //springMVC将将数据转成json格式,时间格式规则
@Value("${user.birthday}")
private Date birthday;
//用户角色
//@Value("${user.userRole}") //不可以单个手动获取石参数
private UserRole userRole; //实体参数
//爱好
//@Value("${user.hobbies}") //不可以单个手动获取复杂参数
private List<String> hobbies;
//爱车
//@Value("${user.carMap}")
private Map<String,String> carMap;
//邮箱
@Email //邮箱格式校验
@Value("${user.email:abc@kgc.com}") //添加默认值,配置信息没有就使用默认值
private String email;
}
2.2.2.2运行结果:
2.2.3 ${} 和 #{} 的区别
- ${}:用于读取核心配置文件中的自定义配置,也可以给属性指定默认值 (${xxx.xx:default值});
- #{}:不可以读取核心配置文件中的自定义配置,可以给属性发指定默认值#{default值} (可以使用表达式),还可以读取容器中已用实体的属性值;
- 两种读取自定义配置的方式,是可以混用的,但是实际开发中,尽量使用其中一种,,一般都是少量配置,单个读取,多个读取,使用批量读取;
3、自定义配置文件并获取配置信息
3.1xxx.properties
3.1.1 student.properties
student.studentId=19130010
student.studentName=huayu
student.studentClass=计算机科学与技术(2)
student.graduationSchool=金陵科技学院
student.graduationTime=2023/7/1 12:12:12
student.nativePlace=南京
student.hasGirFriends=true
3.1.2 StudentProperties.java
@Data
@Component
@ConfigurationProperties(prefix = "student")
public class StudentProperties {
// 学号
private String studentId;
// 姓名
private String studentName;
// 班级
private String studentClass;
// 毕业院校
private String graduationSchool;
// 毕业时间
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
private Date graduationTime;
// 籍贯
private String nativePlace;
// 有没有女朋友
private boolean hasGirFriends;
}
3.1.3 StudentValues.java
@Data
@Component //第一个写法,使用普通组件
@PropertySource(value = "classpath:student.properties")//单个从student.properties 中获取参数
public class StudentValues {
// 学号
@Value("${student.studentId}")
private String studentId;
// 姓名
@Value("${student.studentName}")
private String studentName;
// 班级
@Value("${student.studentClass}")
private String studentClass;
// 毕业院校
@Value("${student.graduationSchool}")
private String graduationSchool;
// 毕业时间
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
@Value("${student.graduationTime}")
private Date graduationTime;
// 籍贯
@Value("${student.nativePlace}")
private String nativePlace;
// 有没有女朋友
@Value("${student.hasGirFriends}")
private boolean hasGirFriends;
}
3.2 xxx.yml
3.2.1 student.yml
student:
studentId: 19130010
studentName: huayu
studentClass: 计算机科学与技术(2)
graduationSchool: 金陵科技学院
graduationTime: 2023/7/1 12:12:12
nativePlace: 南京
hasGirFriends: true
3.2.2 StudentProperties.java
@Data
@Component
@ConfigurationProperties(prefix = "student")
@PropertySource(value = "classpath:student.yml",encoding = "utf-8",factory = YamlPropertySourceFactory.class) //从自定义的 student.yml 中获取
public class StudentProperties {
......
}
3.2.3 StudentValues.java
@Data
@Component
@PropertySource(value = "classpath:my.yml", factory = YamlPropertySourceFactory.class) //从自定义的 student.yml 中获取
public class StudentValues {
......
}
3.2.4 YamlPropertySourceFactory.java yml配置映射类
@PropertySource读取不能直接自定义yaml配置文件,需要自定义一个继承 PropertySourceFactory 的 YamlPropertySourceFactory 编写配置映射类
public class YamlPropertySourceFactory implements PropertySourceFactory {
@Override
public PropertySource<?> createPropertySource(String name, EncodedResource encodedResource) {
Resource resource = encodedResource.getResource();
YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean();
factory.setResources(resource);
Properties props = factory.getObject();
return new PropertiesPropertySource(resource.getFilename(), props);
}
}
3.3 测试
3.3.1 testStudentProperties
3.3.2 testStudentValues
4、*@Configuration配置类的用法,可以实现自定义组件加入容器
4.1 实体
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class UserRole {
//角色
private String roleId;
//角色名称
private String roleName;
}
4.2 UserRoleConfig 配置类
@Configuration //凡是被此注解修饰的类,就是一个配置类,在项目启动是,自动加载,功能跟spring的核心配置文件xml文件是同等的
public class UserRoleConfig {
//手动添加自定义对象,放入容器中以前spring框架,通过xml配置文件,添加<bean id="xx" class="xx">...</bran>
@Bean //标注的方法,会自动将当前方法返回的实例对象放入容器中,默认的bean的id值就是方法名
public UserRole userRole1(){
return UserRole.builder()
.roleId("R001")
.roleName("admin")
.build();
}
@Bean
public UserRole userRole2(){
return UserRole.builder()
.roleId("R002")
.roleName("admin")
.build();
}
}
4.3 测试类
@RestController
public class SpringBootConfigController {
@Autowired
@Qualifier("userRole2")
UserRole userRole;
//可以实现自定义实体加入容器
@GetMapping("/testUserRole")
public UserRole testUserRole(){
return userRole;
}
}
运行结果:
5、激活环境
5.1 多套环境配置文件
激活环境 (实际开发中,主要有三个环境:开发环境,测试环境,生产环境(线上环境),还有一个环境,灰度环境,也是线上环境,叫预上限环境);
好处:可以隔离不同环境的不同配置,需要使用哪个环境,就直接切换核心配置文件;
application-devp.properties
application-prod.properties
application-test.properties
5.2 激活环境
active: test # 指定当前的profiles值,环境是什么是通过核心配置文件名中,application-${profiles},profiles写的是什么就是什么环境;
spring:
profiles:
active: test #激活测试环境
6、核心配置文件加载位置
优先级从高到底依次为:
项目根路径下的config目录
项目根路径下
类路径(resource)下的
类路径(resource)下
注意:模块项目的 项目根路径 是 父项目的根路径;
7、邮件发送 和 短信测试发送
7.1 邮件发送
7.1.1 依赖
<!-- spring-boot-starter-mail start -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<!-- spring-boot-starter-mail end -->
7.1.2 邮件配置信息
7.1.3 类里面写配置信息
配置信息直接写在 对象里面;
@GetMapping("/sendEmail")
public String sendEmail(@RequestParam(value = "setToEmail",required = false) String setToEmail){
System.out.println("--------------[mail/mailSend] start------------------");
try {
MimeMessage message=javaMailSender.createMimeMessage();
MimeMessageHelper helper=new MimeMessageHelper(message,true);
helper.setFrom("2663092414@qq.com","2663092414");
helper.setTo(setToEmail);
helper.setSubject("KH-96-王松—核心配置文件读取");
helper.setText("正在使用SpringBoot读取自定义核心配置,发送邮件成功!<br/>"+studentProperties.toString(),true);
javaMailSender.send(message);
} catch (Exception e) {
System.out.println("邮件发送失败"+ e.getMessage());
e.printStackTrace();
}
System.out.println("--------------[mail/mailSend] end------------------");
return studentProperties.toString();
}
//实例化javaMailSender 并写入配置信息
private static JavaMailSenderImpl javaMailSender;
static {
javaMailSender = new JavaMailSenderImpl();
javaMailSender.setHost("smtp.qq.com");//链接服务器
//javaMailSender.setPort(25);//默认使用25端口发送
javaMailSender.setUsername("2663092414@qq.com");//账号
javaMailSender.setPassword("dwxlbkrmdyagebhe");//授权码
javaMailSender.setDefaultEncoding("UTF-8");
Properties properties = new Properties();
//properties.setProperty("mail.debug", "true");//启用调试
//properties.setProperty("mail.smtp.timeout", "1000");//设置链接超时
//设置通过ssl协议使用465端口发送、使用默认端口(25)时下面三行不需要
properties.setProperty("mail.smtp.auth", "true");//开启认证
properties.setProperty("mail.smtp.socketFactory.port", "465");//设置ssl端口
properties.setProperty("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
javaMailSender.setJavaMailProperties(properties);
}
7.1.4 application.yaml中写配置信息
7.1.4.1 application.yaml
spring:
mail:
default-encoding: UTF-8
host: smtp.qq.com
port: 587
username: xxxxxx@qq.com
password: 授权码
7.1.4.2 请求方法
@GetMapping("/sendEmail2")
public String sendEmail2(@RequestParam(value = "setToEmail",required = false) String setToEmail){
SimpleMailMessage mailMessage = new SimpleMailMessage();
mailMessage.setFrom("xxxxxx@qq.com"); //发送邮箱
mailMessage.setTo("xxxxxx@qq.com"); //目标邮箱
mailMessage.setText("你好 hello world");
mailMessage.setSubject("测试 Springboot 邮箱服务");
mailSender.send(mailMessage);
return "====完成发送!====";
}
7.2 短信测试发送
7.2.1 依赖
<!-- SMS star -->
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>dysmsapi20170525</artifactId>
<version>2.0.9</version>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>tea</artifactId>
<version>1.1.14</version>
</dependency>
<!-- SMS end -->
7.2.2 代码
其中:accessKeyId ,accessKeySecret 填写自己的用户 AccessKey,最好用子用户 AccessKey;
public class Sample {
/**
* 使用AK&SK初始化账号Client
*
* @param accessKeyId
* @param accessKeySecret
* @return Client
* @throws Exception
*/
public static com.aliyun.dysmsapi20170525.Client createClient(String accessKeyId, String accessKeySecret) throws Exception {
com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config()
// 您的 AccessKey ID
.setAccessKeyId(accessKeyId)
// 您的 AccessKey Secret
.setAccessKeySecret(accessKeySecret);
// 访问的域名
config.endpoint = "dysmsapi.aliyuncs.com";
return new com.aliyun.dysmsapi20170525.Client(config);
}
public static void main(String[] args_) throws Exception {
java.util.List<String> args = java.util.Arrays.asList(args_);
com.aliyun.dysmsapi20170525.Client client = Sample.createClient("accessKeyId", "accessKeySecret"); //accessKeyId ,accessKeySecret 填写自己的用户信息
com.aliyun.dysmsapi20170525.models.SendSmsRequest sendSmsRequest = new com.aliyun.dysmsapi20170525.models.SendSmsRequest()
.setSignName("阿里云短信测试")
.setTemplateCode("SMS_154950909")
.setPhoneNumbers("发送短信的手机号")
.setTemplateParam("{\"code\":\"131313\"}");
com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
try {
// 复制代码运行请自行打印 API 的返回值
SendSmsResponse sendSmsResponse = client.sendSmsWithOptions(sendSmsRequest, runtime);
} catch (TeaException error) {
// 如有需要,请打印 error
String errerMsg = Common.assertAsString(error.message);
} catch (Exception _error) {
TeaException error = new TeaException(_error.getMessage(), _error);
// 如有需要,请打印 error
String errorMsg = Common.assertAsString(error.message);
}
}
}
SpringBoot(二) - 核心配置文件 (+ 邮件发送 和 短信发送)的更多相关文章
- yii2验证密码->手机号码短信发送>手机短信发送频繁问题
<?php namespace frontend\models; use Yii; use yii\base\Model; class ChangeMobileSendRequestForm e ...
- SpringBoot(二) - 核心配置文件
1.application.properties 和 application.yml 配置文件格式区别 1.1 文件格式 application.properties # 端口号 server.por ...
- SpringBoot 整合 中国移动 MAS HTTP1.0 实现短信发送服务
因为客户需要,本身使用的 阿里云的短信服务改为了中国移动MAS HTTP 1.0 短信通知,因为看到网络上关于此类的博客知识很少,再趟完坑后特地写下这篇博客,提醒后来人. 特别感谢 中国移动MAS ...
- Springboot 整合 中国移动MAS HTTP1.0 实现短信发送服务(二)
原因:身份验证传入的参数包含中文企业名,因为本地编码格式是支持中文的:而客户的服务器中文却乱码,导致传给中国移动MAS服务器的是乱码的信息. 解决:非常简单,将中文信息转为UTF-8.例如(%E5%8 ...
- C# 短信发送 邮件发送
兴趣是最好的老师. --爱因斯坦 一.实现短信发送 1.使用短信mao的方式进行短信发送,前提要购买硬件设备,这里就不考虑展示了: 2.使用中国网建提供的短信平台,但是用几次后要收费: 我们这里主要介 ...
- SNF开发平台WinForm之十二-发送手机短信功能调用-金笛-SNF快速开发平台3.3-Spring.Net.Framework
1.调用前组装参数 2.调用发送信息服务脚本 .调用前组装参数: BaseSendTaskEntity entity = new BaseSendTaskEntity(); entity.Mess ...
- zabbix告警邮件、短信发送错误快速排查方法
zabbix告警邮件.短信发送错误快速排查方法 背景 zabbix告警邮件.短信经常有同事反馈发送错误的情况,这个问题排查的角度很多,那么最快捷的角度是什么呢? 在我看来,最快的角度就是判断这个告警邮 ...
- Android短彩信源码解析-短信发送流程(二)
转载请注明出处:http://blog.csdn.net/droyon/article/details/11699935 2,短彩信发送framework逻辑 短信在SmsSingleRecipien ...
- Android系统应用Mms之Sms短信发送流程(Mms应用部分)二
1. 新建一条短信, 在发送短信之前, 首先创建的是一个会话Conversation, 以后所有与该接收人(一个或多个接收人)的消息交互, 都在该会话Conversation中. ComposeMes ...
- 短信发送接口被恶意访问的网络攻击事件(三)定位恶意IP的日志分析脚本
前言 承接前文<短信发送接口被恶意访问的网络攻击事件(二)肉搏战-阻止恶意请求>,文中有讲到一个定位非法IP的shell脚本,现在就来公布一下吧,并没有什么技术难度,只是当时花了些时间去写 ...
随机推荐
- Go语言编写单元测试用例
Go单元测试示例 example/ |--division.go |--division_test.go 为什么被测试文件和测试文件通常放到同一个文件夹下以及同一个声明包里 通常情况下,我们把被测试的 ...
- 2-6 C/C++ 编写头文件
目录 头文件怎么起作用 避免头文件被重复引用 避免头文件被重复引用的方法:条件编译 1. 给每个头文件添加一个预编译变量(preprocessor variable)作为标记(Label) 2. 使用 ...
- macOS安装使用OpenConnect客户端替代cisco连接公司内网环境
mac_os安装openconnect服务 brew install openconnect 使用OpenConnect客户端拨通VPN,打开终端执行以下命令: sudo openconnect -u ...
- Qml 中的那些坑(七)---ComboBox嵌入Popup时,滚动内容超过其可见区域不会关闭ComboBox弹窗
[写在前面] 最近在写信息提交 ( 表单 ) 的窗口时发现一个奇怪的 BUG: 其代码如下: import QtQuick 2.15 import QtQuick.Controls 2.15 impo ...
- Air780EP之RC522开发板,你了解吗?
本文讲解合宙Air780EP开发板RC522实例. 本文档适用于Air780EP开发板: 关联文档和使用工具: rc522 - rc522 非接触式读写卡驱动 - LuatOS 文档: LuatO ...
- python数据结构的性能分析
2.python数据结构的性能分析 一.引言 - 现在大家对 大O 算法和不同函数之间的差异有了了解.本节的目标是告诉你 Python 列表和字典操作的 大O 性能.然后我们将做一些基于时间的实验来说 ...
- Java 并发编程实战学习笔记——路径查找类型并行任务的终止
1.该类问题的递归串行算法(深度优先遍历) 代码 复制 - 运行 package net.jcip.examples; import java.util.*; /** * SequentialPuzz ...
- 如何正确使用 RMQ
序列分块.设块长为 \(B\).每块预处理出最大值.对于询问 \([l, r]\),答案就是整块最大值和散块最大值拼起来.答案显然是 \(O(n) \sim O(\dfrac{n}{B} + B)\) ...
- ZCMU-1111
与背包和动态规划有关(我认为) 采用dp数组存放吃掉i千克食物要用掉的钱 dp最开始要尽量的大方便过程中判断和最后的输出判断 实时更新dp,保留最小的钱 以前不知道的 printf函数可以这样用 fi ...
- canvas(七)绘制网格和坐标轴
1.绘制网格 传入dom和分割线间隔进行渲染,网格线分为水平方向和垂直方向 <script> //绘制网格 function drwaGrid(dom = document.querySe ...