》》》插件、部分依赖需的自行查找 :
》》》
前端页面:
DOCTYPE html>
<html lang="zh-CN" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="">
<meta name="keys" content="">
<meta name="author" content="">
<base th:href="@{/}"/>
<link rel="stylesheet" href="bootstrap/css/bootstrap.min.css">
<link rel="stylesheet" href="css/font-awesome.min.css">
<link rel="stylesheet" href="css/login.css">
<script type="text/javascript" src="jquery/jquery-2.1.1.min.js">script>
<script type="text/javascript" src="bootstrap/js/bootstrap.min.js">script>
<script type="text/javascript" src="layer/layer.js">script>
<script type="text/javascript">
$(function () {
$("#sendBtn").click(function () {
// 获取接收短信的邮箱
var email = $.trim($("[name=email]").val());
// 发送请求
$.ajax({
"url":"/auth/member/send/short/message.json",
type:"post",
data : {
"email":email
},
dataType:"json",
success:function (response) {
var result = response.result;
if (result == "SUCCESS"){
layer.msg("发送成功! ")
}
if (result == "FAILED"){
layer.msg("发送失败! 请再试一次");
}
},
error:function (response) {
layer.msg(response.status + " " + response.statusText );
}
});
});
})
script>
head>
<body>
<nav class="navbar navbar-inverse navbar-fixed-top" role="navigation">
<div class="container">
<div class="navbar-header">
<div><a class="navbar-brand" href="index.html" style="font-size:32px;">募资网-创意产品募资平台a>div>
div>
div>
nav>
<div class="container">
<form class="form-signin" role="form">
<h2 class="form-signin-heading"><i class="glyphicon glyphicon-log-in">i> 用户注册h2>
<div class="form-group has-success has-feedback">
<input type="text" class="form-control" id="inputSuccess4" placeholder="请输入登录账号" autofocus>
<span class="glyphicon glyphicon-user form-control-feedback">span>
div>
<div class="form-group has-success has-feedback">
<input type="text" class="form-control" id="inputSuccess4" placeholder="请输入登录密码" style="margin-top:10px;">
<span class="glyphicon glyphicon-lock form-control-feedback">span>
div>
<div class="form-group has-success has-feedback">
<input type="text" name="email" class="form-control" id="inputSuccess4" placeholder="请输入邮箱地址" style="margin-top:10px;"
value="[email protected]">
<span class="glyphicon glyphicon glyphicon-envelope form-control-feedback">span>
div>
<div class="form-group has-success has-feedback">
<input type="text" name="phoneNum" class="form-control" id="inputSuccess4" placeholder="请输入手机号" style="margin-top:10px;">
<span class="glyphicon glyphicon glyphicon-earphone form-control-feedback">span>
div>
<div class="form-group has-success has-feedback">
<input type="text" class="form-control" id="inputSuccess4" placeholder="请输入邮箱验证码" style="margin-top:10px;">
<span class="glyphicon glyphicon glyphicon-comment form-control-feedback">span>
div>
<button id="sendBtn" type="button" class="btn btn-lg btn-success btn-block"> 获取验证码button>
<a class="btn btn-lg btn-success btn-block" href="login.html" > 注册a>
form>
div>
body>
html>
pom:
<dependency>
<groupId>javax.mailgroupId>
<artifactId>mailartifactId>
<version>1.4.7version>
dependency>
yml:
send:
email:
sendEmailAccount: "***@qq.com" #发件人邮箱
sendEmailPassword: "*******" #发件人密码
sendEmailSMTPServer: "smtp.qq.com" #默认服务
smtpPort: "465" #默认端口号
captcha: "******" #默认验证码
emailPSD: 亲爱的用户: 您正在加入募资途中 您的注册验证码为:${send.email.captcha} ; 请在一分钟内完成操作(一分钟后验证码失效) #短信模板
EmailProperties:
@Component
@ConfigurationProperties(prefix = "send.email")
@NoArgsConstructor
@AllArgsConstructor
@Data
public class EmailProperties {
//发件人地址
private String sendEmailAccount;
//qq邮箱授权码
private String sendEmailPassword;
//邮件服务器
private String sendEmailSMTPServer;
//SMTP端口号
private String smtpPort;
// 短信模板
private String emailPSD;
}
EendEmailUtil:
/**
* 发送邮件
*
* @param sendEmailAccount 发件人邮箱
* @param sendEmailPasswd 发件人邮箱密码
* @param SendEmailSMTPServer 邮件协议
* @param smtpPort 邮件端口号
* @param receiveMailAccount 收件账户
* @param emailPSD 验证信息(模板)
* @return 成功无返回值 失败返回异常信息
*/
public static ResultEntity<String> SendEmail(
String sendEmailAccount,
String sendEmailPasswd,
String SendEmailSMTPServer,
String smtpPort,
String receiveMailAccount,
String emailPSD
) {
// 1. 创建参数配置, 用于连接邮件服务器的参数配置
Properties props = new Properties(); // 参数配置
props.setProperty("mail.transport.protocol", "smtp"); // 使用的协议(JavaMail规范要求)
props.setProperty("mail.smtp.host", SendEmailSMTPServer); // 发件人的邮箱的 SMTP 服务器地址
props.setProperty("mail.smtp.auth", "true"); // 需要请求认证
// PS: 某些邮箱服务器要求 SMTP 连接需要使用 SSL 安全认证 (为了提高安全性, 邮箱支持SSL连接, 也可以自己开启),
// 如果无法连接邮件服务器, 仔细查看控制台打印的 log, 如果有有类似 “连接失败, 要求 SSL 安全连接” 等错误,
// 打开下面 /* ... */ 之间的注释代码, 开启 SSL 安全连接。
// SMTP 服务器的端口 (非 SSL 连接的端口一般默认为 25, 可以不添加, 如果开启了 SSL 连接,
// 需要改为对应邮箱的 SMTP 服务器的端口, 具体可查看对应邮箱服务的帮助,
// QQ邮箱的SMTP(SLL)端口为465或587, 其他邮箱自行去查看)
//final String smtpPort = "465";
props.setProperty("mail.smtp.port", smtpPort);
props.setProperty("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
props.setProperty("mail.smtp.socketFactory.fallback", "false");
props.setProperty("mail.smtp.socketFactory.port", smtpPort);
// 2. 根据配置创建会话对象, 用于和邮件服务器交互
Session session = Session.getDefaultInstance(props);
// session.setDebug(true); // 设置为debug模式, 可以查看详细的发送 log
// 3. 创建一封邮件
try {
// MimeMessage message = createMessage(session, sendEmailAccount, receiveMailAccount, info);
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
// 1. 创建一封邮件
MimeMessage message = new MimeMessage(session);
// 2. From: 发件人(昵称有广告嫌疑,避免被邮件服务器误认为是滥发广告以至返回失败,请修改昵称)
message.setFrom(new InternetAddress(sendEmailAccount, "募资网", "UTF-8"));
// 3. To: 收件人(可以增加多个收件人、抄送、密送)
message.setRecipient(MimeMessage.RecipientType.TO, new InternetAddress(receiveMailAccount, "UTF-8"));
// 4. Subject: 邮件主题(标题有广告嫌疑,避免被邮件服务器误认为是滥发广告以至返回失败,请修改标题)
message.setSubject("募资网系统(请勿回复此邮件)", "UTF-8");
// 生成六位验证码
StringBuffer stringBuffer = new StringBuffer();
for (int i = 0; i < 6; i++) {
int random = (int) (Math.random() * 10);
stringBuffer.append(random);
}
// 验证码
String captcha = stringBuffer.toString();
// 验证信息 替换模板中的默认验证码 (模板+验证码=信息)
String info = emailPSD.replace("******", captcha);
// 5. Content: 邮件正文(可以使用html标签)(内容有广告嫌疑,避免被邮件服务器误认为是滥发广告以至返回失败,请修改发送内容)
message.setContent(info, "text/html;charset=UTF-8");
// 6. 设置发件时间
message.setSentDate(new Date());
// 7. 保存设置
message.saveChanges();
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
// 4. 根据 Session 获取邮件传输对象
Transport transport = session.getTransport();
// 5. 使用 邮箱账号 和 密码 连接邮件服务器, 这里认证的邮箱必须与 message 中的发件人邮箱一致, 否则报错
//
// PS_01: 成败的判断关键在此一句, 如果连接服务器失败, 都会在控制台输出相应失败原因的 log,
// 仔细查看失败原因, 有些邮箱服务器会返回错误码或查看错误类型的链接, 根据给出的错误
// 类型到对应邮件服务器的帮助网站上查看具体失败原因。
//
// PS_02: 连接失败的原因通常为以下几点, 仔细检查代码:
// (1) 邮箱没有开启 SMTP 服务;
// (2) 邮箱密码错误, 例如某些邮箱开启了独立密码;
// (3) 邮箱服务器要求必须要使用 SSL 安全连接;
// (4) 请求过于频繁或其他原因, 被邮件服务器拒绝服务;
// (5) 如果以上几点都确定无误, 到邮件服务器网站查找帮助。
//
// PS_03: 仔细看log, 认真看log, 看懂log, 错误原因都在log已说明。
transport.connect(sendEmailAccount, sendEmailPasswd);
// 6. 发送邮件, 发到所有的收件地址, message.getAllRecipients() 获取到的是在创建邮件对象时添加的所有收件人, 抄送人, 密送人
transport.sendMessage(message, message.getAllRecipients());
// 7. 关闭连接
transport.close();
return ResultEntity.successWithoutData(captcha);
} catch (Exception e) {
e.printStackTrace();
return ResultEntity.failed(e.getMessage());
}
}
ResultEntity:
/**
* 统一整个项目中Ajax请求返回的结果(未来也可以用于分布式架构各个模块调用时返回统一类型)
* @param
*/
public class ResultEntity<T> {
public static final String SUCCESS = "SUCCESS";
public static final String FAILED = "FAILED";
//用来封装当前请求处理的结果是成功还是失败
private String result;
//请求处理失败时返回的错误的消息
private String message;
//返回的数据
private T data;
/**
* 请求处理成功且不需要返回数据时使用的工具方法
*
* @param
* @return
*/
public static <Type> ResultEntity<Type> successWithoutData() {
return new ResultEntity<Type>(SUCCESS, null, null);
}
/**
* 请求处理成功且需要返回数据时使用的工具方法
*
* @param data
* @param
* @return
*/
public static <Type> ResultEntity<Type> successWithoutData(Type data) {
return new ResultEntity<Type>(SUCCESS, null, data);
}
/**
* 请求处理失败后使用的工具方法
* @param message 失败的错误消息
* @param
* @return
*/
public static <Type> ResultEntity<Type> failed(String message) {
return new ResultEntity<>(FAILED, message, null);
}
public String getResult() {
return result;
}
public void setResult(String result) {
this.result = result;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
public ResultEntity(String result, String message, T data) {
this.result = result;
this.message = message;
this.data = data;
}
public ResultEntity() {
}
@Override
public String toString() {
return "ResultEntity{" +
"result='" + result + '\'' +
", message='" + message + '\'' +
", data=" + data +
'}';
}
}
Controller:
@Controller
public class MemberHandler {
@Autowired
private EmailProperties emailProperties;
@Autowired
private RedisRemoteService redisRemoteService;
@RequestMapping("/auth/member/send/short/message.json")
@ResponseBody
public ResultEntity<String> sendMessage(@RequestParam("email") String email) {
// 1.发送验证码到email手机
ResultEntity<String> sendEmailResultEntity = CrowdUtil.SendEmail(
emailProperties.getSendEmailAccount(),
emailProperties.getSendEmailPassword(),
emailProperties.getSendEmailSMTPServer(),
emailProperties.getSmtpPort(),
email,
emailProperties.getEmailPSD()
);
// 2.判断发送结果
if (ResultEntity.SUCCESS.equals(sendEmailResultEntity.getResult())) {
// 3.如果发送成功,则将验证码存入Redis
// ①从上一步操作的结果中获取随机生成的验证码
String code = sendEmailResultEntity.getData();
// ②拼接一个用于Redis中存储数据的key
String key = CrowdConstant.REDIS_CODE_PREFIX + email;
// ③调用远程接口存入Redis
ResultEntity<String> saveCodeResultEntity = redisRemoteService.setRedisKeyValueRemoteWithTimeout(key, code, 15, TimeUnit.MINUTES);
// ④判断结果
if (ResultEntity.SUCCESS.equals(saveCodeResultEntity.getResult())) {
return ResultEntity.successWithoutData();
}else {
return saveCodeResultEntity;
}
}else{
return sendEmailResultEntity;
}
}
}