登入网易邮箱找到设置
---->常规设置
------>POP/SMTP/IMAP
中打开两项服务
记住刚刚第一个开启的IMAP/SMTP授权密码
第一步引入依赖:
<!-- 邮箱jar -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
在application.yml中加入
spring:
mail:
host: smtp.163.com 邮件服务器主机名smtp.163.com
password: 授权密码
username: 邮箱@163.com
port: 465
default-encoding: UTF-8
protocol: smtp
properties:
mail.smtp.auth: true
mail.smtp.starttls.enable: true
mail.smtp.starttls.required: true
mail.smtp.socketFactory.port: 465
mail.smtp.socketFactory.class: javax.net.ssl.SSLSocketFactory
mail.smtp.socketFactory.fallback: false
生成四位和六位的随机数字
package com.qhzx.td.untils;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Random;
/**
* 生成四位和六位的随机数字
*/
public class RandomUtils {
private static final Random random = new Random();
private static final DecimalFormat fourdf = new DecimalFormat("0000");
private static final DecimalFormat sixdf = new DecimalFormat("000000");
public static String getFourBitRandom() {
return fourdf.format(random.nextInt(10000));
}
public static String getSixBitRandom() {
return sixdf.format(random.nextInt(1000000));
}
/**
* 给定数组,抽取n个数据
* @param list
* @param n
* @return
*/
public static ArrayList getRandom(List list, int n) {
Random random = new Random();
HashMap<Object, Object> hashMap = new HashMap<Object, Object>();
// 生成随机数字并存入HashMap
for (int i = 0; i < list.size(); i++) {
int number = random.nextInt(100) + 1;
hashMap.put(number, i);
}
// 从HashMap导入数组
Object[] robjs = hashMap.values().toArray();
ArrayList r = new ArrayList();
// 遍历数组并打印数据
for (int i = 0; i < n; i++) {
r.add(list.get((int) robjs[i]));
System.out.print(list.get((int) robjs[i]) + "\t");
}
System.out.print("\n");
return r;
}
/**
* @param digit 位数
* @return 随机生成digit位数的数字
*/
public static long getNum(int digit) {
StringBuilder str = new StringBuilder();
for (int i = 0; i < digit; i++) {
if (i == 0 && digit > 1)
str.append(new Random().nextInt(9) + 1);
else
str.append(new Random().nextInt(10));
}
return Long.valueOf(str.toString());
}
public static void main(String[] args) {
long num = getNum(8);
System.out.println(num);
}
}
CommonConstants
package com.qhzx.td.constant;
/**
* @Description:
* @Author: x
* @Date :
*/
public class CommonConstants {
public static final String STRING_YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd hh:mm:ss";
public static final String STRING_YYYY_MM_DD = "yyyy-MM-dd";
public static final String STRING_ZERO = "0";
public static final String STRING_ONE = "1";
public static final String STRING_TOW = "2";
public static final Long LONG_ZERO = 0L;
public static final Long LONG_ONE = 1L;
public static final Long LONG_TWO = 2L;
public static final String CAPTCHA_CODE_KEY = "captcha_codes:";
/**
* 登录用户 redis key
*/
public static final String LOGIN_TOKEN_KEY = "login_tokens:";
/**
* 防重提交 redis key
*/
public static final String REPEAT_SUBMIT_KEY = "repeat_submit:";
/**
* 限流 redis key
*/
public static final String RATE_LIMIT_KEY = "rate_limit:";
/**
* 验证码有效期(分钟)
*/
public static final Integer CAPTCHA_EXPIRATION = 2;
}
MailService
package com.qhzx.td.services.otc;
public interface MailService {
boolean sendMail(String to, String subject, String text);
}
MailServiceImpl
package com.qhzx.td.services.otc.impl;
import com.qhzx.td.services.otc.MailService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.MailException;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Service;
/**
* @author xufan1
* 邮箱发送实现类
*/
@Service
public class MailServiceImpl implements MailService {
private final JavaMailSender mailSender;
@Value("${spring.mail.username}")
private String from;
public MailServiceImpl(JavaMailSender mailSender) {
this.mailSender = mailSender;
}
@Override
public boolean sendMail(String to, String subject, String text) {
SimpleMailMessage msg = new SimpleMailMessage();
msg.setFrom(from);
msg.setTo(to);
msg.setSubject(subject);
msg.setText(text);
try {
mailSender.send(msg);
} catch (MailException ex) {
ex.printStackTrace();
System.err.println(ex.getMessage());
return false;
}
return true;
}
}
RedisRepository
package com.qhzx.td.template;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.connection.RedisClusterNode;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisServerCommands;
import org.springframework.data.redis.core.*;
import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.stereotype.Component;
import java.nio.charset.Charset;
import java.util.*;
import java.util.concurrent.TimeUnit;
/**
* Redis Repository
* redis 基本操作 可扩展,基本够用了
*/
@Component
@Slf4j
public class RedisRepository {
/**
* 默认编码
*/
private static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");
/**
* key序列化
*/
private static final StringRedisSerializer STRING_SERIALIZER = new StringRedisSerializer();
/**
* value 序列化
*/
private static final JdkSerializationRedisSerializer OBJECT_SERIALIZER = new JdkSerializationRedisSerializer();
/**
* Spring Redis Template
*/
private RedisTemplate<String, String> redisTemplate;
public RedisRepository(RedisTemplate<String, String> redisTemplate) {
this.redisTemplate = redisTemplate;
this.redisTemplate.setKeySerializer(STRING_SERIALIZER);
this.redisTemplate.setValueSerializer(OBJECT_SERIALIZER);
}
/**
* 获取链接工厂
*/
public RedisConnectionFactory getConnectionFactory() {
return this.redisTemplate.getConnectionFactory();
}
/**
* 获取 RedisTemplate对象
*/
public RedisTemplate<String, String> getRedisTemplate() {
return redisTemplate;
}
/**
* 清空DB
*
* @param node redis 节点
*/
public void flushDB(RedisClusterNode node) {
this.redisTemplate.opsForCluster().flushDb(node);
}
/**
* 添加到带有 过期时间的 缓存
*
* @param key redis主键
* @param value 值
* @param time 过期时间
*/
public void setExpire(final byte[] key, final byte[] value, final long time) {
redisTemplate.execute((RedisCallback<Long>) connection -> {
connection.set(key, value);
connection.expire(key, time);
log.debug("[redisTemplate redis]放入 缓存 url:{} ========缓存时间为{}秒", key, time);
return 1L;
});
}
/**
* 添加到带有 过期时间的 缓存
*
* @param key redis主键
* @param value 值
* @param time 过期时间
*/
public void setExpire(final String key, final String value, final long time) {
redisTemplate.execute((RedisCallback<Long>) connection -> {
RedisSerializer<String> serializer = getRedisSerializer();
byte[] keys = serializer.serialize(key);
byte[] values = serializer.serialize(value);
connection.set(keys, values);
connection.expire(keys, time);
log.debug("[redisTemplate redis]放入 缓存 url:{} ========缓存时间为{}秒", key, time);
return 1L;
});
}
/**
* 一次性添加数组到 过期时间的 缓存,不用多次连接,节省开销
*
* @param keys redis主键数组
* @param values 值数组
* @param time 过期时间
*/
public void setExpire(final String[] keys, final String[] values, final long time) {
redisTemplate.execute((RedisCallback<Long>) connection -> {
RedisSerializer<String> serializer = getRedisSerializer();
for (int i = 0; i < keys.length; i++) {
byte[] bKeys = serializer.serialize(keys[i]);
byte[] bValues = serializer.serialize(values[i]);
connection.set(bKeys, bValues);
connection.expire(bKeys, time);
log.debug("[redisTemplate redis]放入 缓存 url:{} ========缓存时间为:{}秒", keys[i], time);
}
return 1L;
});
}
/**
* 获取key过期剩余时间
*
* @param key
* @param timeUnit
* @return
*/
public Long getExpire(final String key, TimeUnit timeUnit) {
return redisTemplate.getExpire(key, timeUnit);
}
/**
* 一次性添加数组到 过期时间的 缓存,不用多次连接,节省开销
*
* @param keys the keys
* @param values the values
*/
public void set(final String[] keys, final String[] values) {
redisTemplate.execute((RedisCallback<Long>) connection -> {
RedisSerializer<String> serializer = getRedisSerializer();
for (int i = 0; i < keys.length; i++) {
byte[] bKeys = serializer.serialize(keys[i]);
byte[] bValues = serializer.serialize(values[i]);
connection.set(bKeys, bValues);
log.debug("[redisTemplate redis]放入 缓存 url:{}", keys[i]);
}
return 1L;
});
}
/**
* 添加到缓存
*
* @param key the key
* @param value the value
*/
public void set(final String key, final String value) {
redisTemplate.execute((RedisCallback<Long>) connection -> {
RedisSerializer<String> serializer = getRedisSerializer();
byte[] keys = serializer.serialize(key);
byte[] values = serializer.serialize(value);
connection.set(keys, values);
log.debug("[redisTemplate redis]放入 缓存 url:{}", key);
return 1L;
});
}
/**
* 查询在这个时间段内即将过期的key
*
* @param key the key
* @param time the time
* @return the list
*/
public List<String> willExpire(final String key, final long time) {
final List<String> keysList = new ArrayList<>();
redisTemplate.execute((RedisCallback<List<String>>) connection -> {
Set<String> keys = redisTemplate.keys(key + "*");
for (String key1 : keys) {
Long ttl = connection.ttl(key1.getBytes(DEFAULT_CHARSET));
if (0 <= ttl && ttl <= 2 * time) {
keysList.add(key1);
}
}
return keysList;
});
return keysList;
}
/**
* 查询在以keyPatten的所有 key
*
* @param keyPatten the key patten
* @return the set
*/
public Set<String> keys(final String keyPatten) {
return redisTemplate.execute((RedisCallback<Set<String>>) connection -> redisTemplate.keys(keyPatten + "*"));
}
/**
* 根据key获取对象
*
* @param key the key
* @return the byte [ ]
*/
public byte[] get(final byte[] key) {
byte[] result = redisTemplate.execute((RedisCallback<byte[]>) connection -> connection.get(key));
log.debug("[redisTemplate redis]取出 缓存 url:{} ", key);
return result;
}
/**
* 根据key获取对象
*
* @param key the key
* @return the string
*/
public String get(final String key) {
String resultStr = redisTemplate.execute((RedisCallback<String>) connection -> {
RedisSerializer<String> serializer = getRedisSerializer();
byte[] keys = serializer.serialize(key);
byte[] values = connection.get(keys);
return serializer.deserialize(values);
});
log.debug("[redisTemplate redis]取出 缓存 url:{} ", key);
return resultStr;
}
/**
* 根据key获取对象
*
* @param key the key
* @return the string
*/
public String getSelect(final String key, Integer num) {
String resultStr = redisTemplate.execute((RedisCallback<String>) connection -> {
connection.select(num);
RedisSerializer<String> serializer = getRedisSerializer();
byte[] keys = serializer.serialize(key);
byte[] values = connection.get(keys);
return serializer.deserialize(values);
});
log.debug("[redisTemplate redis]取出 缓存 url:{} ", key);
return resultStr;
}
/**
* 根据key获取对象
*
* @param keyPatten the key patten
* @return the keys values
*/
public Map<String, String> getKeysValues(final String keyPatten) {
log.debug("[redisTemplate redis] getValues() patten={} ", keyPatten);
return redisTemplate.execute((RedisCallback<Map<String, String>>) connection -> {
RedisSerializer<String> serializer = getRedisSerializer();
Map<String, String> maps = new HashMap<>(16);
Set<String> keys = redisTemplate.keys(keyPatten + "*");
if (CollectionUtil.isNotEmpty(keys)) {
for (String key : keys) {
byte[] bKeys = serializer.serialize(key);
byte[] bValues = connection.get(bKeys);
String value = serializer.deserialize(bValues);
maps.put(key, value);
}
}
return maps;
});
}
/**
* Ops for hash hash operations.
*
* @return the hash operations
*/
public HashOperations<String, String, String> opsForHash() {
return redisTemplate.opsForHash();
}
/**
* 对HashMap操作
*
* @param key the key
* @param hashKey the hash key
* @param hashValue the hash value
*/
public void putHashValue(String key, String hashKey, String hashValue) {
log.debug("[redisTemplate redis] putHashValue() key={},hashKey={},hashValue={} ", key, hashKey, hashValue);
opsForHash().put(key, hashKey, hashValue);
}
/**
* 获取单个field对应的值
*
* @param key the key
* @param hashKey the hash key
* @return the hash values
*/
public Object getHashValues(String key, String hashKey) {
log.debug("[redisTemplate redis] getHashValues() key={},hashKey={}", key, hashKey);
return opsForHash().get(key, hashKey);
}
/**
* 根据key值删除
*
* @param key the key
* @param hashKeys the hash keys
*/
public void delHashValues(String key, Object... hashKeys) {
log.debug("[redisTemplate redis] delHashValues() key={}", key);
opsForHash().delete(key, hashKeys);
}
/**
* key只匹配map
*
* @param key the key
* @return the hash value
*/
public Map<String, String> getHashValue(String key) {
log.debug("[redisTemplate redis] getHashValue() key={}", key);
return opsForHash().entries(key);
}
/**
* 批量添加
*
* @param key the key
* @param map the map
*/
public void putHashValues(String key, Map<String, String> map) {
opsForHash().putAll(key, map);
}
/**
* 集合数量
*
* @return the long
*/
public long dbSize() {
return redisTemplate.execute(RedisServerCommands::dbSize);
}
/**
* 清空redis存储的数据
*
* @return the string
*/
public String flushDB() {
return redisTemplate.execute((RedisCallback<String>) connection -> {
connection.flushDb();
return "ok";
});
}
/**
* 判断某个主键是否存在
*
* @param key the key
* @return the boolean
*/
public boolean exists(final String key) {
return redisTemplate.execute((RedisCallback<Boolean>) connection -> connection.exists(key.getBytes(DEFAULT_CHARSET)));
}
/**
* 删除key
*
* @param keys the keys
* @return the long
*/
public long del(final String... keys) {
return redisTemplate.execute((RedisCallback<Long>) connection -> {
long result = 0;
for (String key : keys) {
result = connection.del(key.getBytes(DEFAULT_CHARSET));
}
return result;
});
}
/**
* 模糊删除key
*
* @param prex the keys
* @return the long
*/
public void deleteByPrex(String prex) {
Set<String> keys = redisTemplate.keys(prex);
if (CollectionUtils.isNotEmpty(keys)) {
redisTemplate.delete(keys);
}
}
/**
* 获取 RedisSerializer
*
* @return the redis serializer
*/
protected RedisSerializer<String> getRedisSerializer() {
return redisTemplate.getStringSerializer();
}
/**
* 对某个主键对应的值加一,value值必须是全数字的字符串
*
* @param key the key
* @return the long
*/
public long incr(final String key) {
return redisTemplate.execute((RedisCallback<Long>) connection -> {
RedisSerializer<String> redisSerializer = getRedisSerializer();
return connection.incr(redisSerializer.serialize(key));
});
}
public long decr(final String key) {
return redisTemplate.execute((RedisCallback<Long>) connection -> {
RedisSerializer<String> redisSerializer = getRedisSerializer();
return connection.decr(redisSerializer.serialize(key));
});
}
/**
* redis List 引擎
*
* @return the list operations
*/
public ListOperations<String, String> opsForList() {
return redisTemplate.opsForList();
}
/**
* redis zset 引擎
*
* @return the list operations
*/
public ZSetOperations<String, String> opsForzSet() {
return redisTemplate.opsForZSet();
}
/**
* redis List数据结构 : 将一个或多个值 value 插入到列表 key 的表头
*
* @param key the key
* @param value the value
* @return the long
*/
public Long leftPush(String key, String value) {
return opsForList().leftPush(key, value);
}
/**
* redis List数据结构 : 移除并返回列表 key 的头元素
*
* @param key the key
* @return the string
*/
public String leftPop(String key) {
return opsForList().leftPop(key);
}
/**
* redis List数据结构 :将一个或多个值 value 插入到列表 key 的表尾(最右边)。
*
* @param key the key
* @param value the value
* @return the long
*/
public Long in(String key, String value) {
return opsForList().rightPush(key, value);
}
/**
* redis List数据结构 : 移除并返回列表 key 的末尾元素
*
* @param key the key
* @return the string
*/
public String rightPop(String key) {
return opsForList().rightPop(key);
}
/**
* redis List数据结构 : 返回列表 key 的长度 ; 如果 key 不存在,则 key 被解释为一个空列表,返回 0 ; 如果 key 不是列表类型,返回一个错误。
*
* @param key the key
* @return the long
*/
public Long length(String key) {
return opsForList().size(key);
}
/**
* redis List数据结构 : 根据参数 i 的值,移除列表中与参数 value 相等的元素
*
* @param key the key
* @param i the
* @param value the value
*/
public void remove(String key, long i, String value) {
opsForList().remove(key, i, value);
}
/**
* redis List数据结构 : 将列表 key 下标为 index 的元素的值设置为 value
*
* @param key the key
* @param index the index
* @param value the value
*/
public void set(String key, long index, String value) {
opsForList().set(key, index, value);
}
/**
* redis List数据结构 : 返回列表 key 中指定区间内的元素,区间以偏移量 start 和 end 指定。
*
* @param key the key
* @param start the start
* @param end the end
* @return the list
*/
public List<String> getList(String key, int start, int end) {
return opsForList().range(key, start, end);
}
/**
* redis List数据结构 : 批量存储
*
* @param key the key
* @param list the list
* @return the long
*/
public Long leftPushAll(String key, List<String> list) {
return opsForList().leftPushAll(key, list);
}
/**
* redis List数据结构 : 批量存储
*
* @param key the key
* @param list the list
* @return the long
*/
public Long pushAll(String key, List<String> list) {
return opsForList().rightPushAll(key, list);
}
/**
* redis List数据结构 : 将值 value 插入到列表 key 当中,位于值 index 之前或之后,默认之后。
*
* @param key the key
* @param index the index
* @param value the value
*/
public void insert(String key, long index, String value) {
opsForList().set(key, index, value);
}
/**
* redis zset数据结构 : 将值 value 插入到列表 key 当中,分数为score。
*
* @param key the key
* @param score the score
* @param value the value
*/
public Boolean zsetAdd(String key, String value, double score) {
return opsForzSet().add(key, value, score);
}
/**
* redis zset数据结构 : 从小到大
*
* @param key
* @param min
* @param max
* @return
*/
public Set<String> zsetRangByScore(String key, double min, double max) {
return opsForzSet().rangeByScore(key, min, max);
}
/**
* redis zset数据结构 : start,end,从小到大
*
* @param key the key
* @param start the start
* @param end the end
*/
public Set<String> zsetRang(String key, long start, long end) {
return opsForzSet().range(key, start, end);
}
public Set<ZSetOperations.TypedTuple<String>> zsetRangWithScore(String key, long start, long end) {
return opsForzSet().rangeWithScores(key, start, end);
}
public Double zsetIncrScore(String key, String value, double score) {
return opsForzSet().incrementScore(key, value, score);
}
/**
* redis zset数据结构 : 从大到小
*
* @param key
* @param min
* @param max
* @return
*/
public Set<String> zsetRevRangByScore(String key, double min, double max) {
return opsForzSet().reverseRangeByScore(key, min, max);
}
/**
* redis zset数据结构 : start,end,从大到小
*
* @param key
* @param start
* @param end
* @return
*/
public Set<String> zsetRevRang(String key, long start, long end) {
return opsForzSet().reverseRange(key, start, end);
}
/**
* redis zset数据结构 : start,end,从大到小
*
* @param key
* @return
*/
public Long zsetCount(String key) {
return opsForzSet().size(key);
}
/**
* redis zset 根据score删除数据 :
*
* @param key
* @param score
*/
public void zsetRmByScore(String key, long score) {
opsForzSet().removeRangeByScore(key, score, score);
}
public void zsetRemove(String key, String... obj) {
opsForzSet().remove(key, obj);
}
public void zsetRemoveRange(String key, long start, long end) {
opsForzSet().removeRange(key, start, end);
}
/**
* redis zset 模糊查询 :
*
* @param key
* @param param
* @return
*/
public List<String> keyLikeValue(String key, String param) {
BoundZSetOperations bo = redisTemplate.boundZSetOps(key);
ScanOptions.ScanOptionsBuilder sob = new ScanOptions.ScanOptionsBuilder();
sob.match("*" + param + "*");
ScanOptions build = sob.build();
Cursor scan = bo.scan(build);
List<String> list = new ArrayList<String>();
while (scan.hasNext()) {
DefaultTypedTuple next = (DefaultTypedTuple) scan.next();
String value = next.getValue().toString();
list.add(value);
}
return list;
}
}
controller
package com.qhzx.controller;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.qhzx.constant.CommonConstants;
import com.qhzx.service.MailService;
import com.qhzx.template.RedisRepository;
import com.qhzx.util.RandomUtils;
import com.qhzx.util.Result;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
@Api(tags = "邮箱")
@RestController
@CrossOrigin
@RequestMapping("/common")
@Slf4j
public class mailController {
@Resource
private RedisRepository redisRepository;
@Autowired
MailService mailService;
@PostMapping(value = "/sendEmail")
@ResponseBody
@ApiOperation(value = "发送邮箱")
public Result send(String email) {
// 生成验证码
Long code = RandomUtils.getNum(6);
String verifyKey = CommonConstants.CAPTCHA_CODE_KEY + email;
log.info("verifyKey::================>" + verifyKey);
log.info("email::================>" + email);
log.info("code ::================>" + code);
String content = "您好! 您的验证码是: " + code + " 有效期5分钟,如非本人操作請忽略!";
mailService.sendMail(email, "xxxxx", content);
//删除之前的验证码缓存key
redisRepository.deleteByPrex(verifyKey);
//将验证码存入redis
redisRepository.setExpire(verifyKey, code.toString(), 60 * CommonConstants.CAPTCHA_EXPIRATION);
return Result.succeed();
}
// @ApiOperation("判断用户邮箱是否被注册")
// @GetMapping("/registerCheck")
// public Result registerVerification(@RequestParam String email) {
// //判断用户邮箱是否被注册
// QueryWrapper<Users> queryWrapper = new QueryWrapper<>();
// if (!StringUtils.isEmpty(email)) {
// queryWrapper.eq("username", email);
// Integer count = usersService.count(queryWrapper);
// if (count == 1) {
// return Result.succeed(Result.fail("邮箱已注册!"));
// }
// }
// return Result.succeed(Result.succeed());
// }
}