点击链接查看项目

SpringBoot邮件发送

邮件发送是一个非常常见的功能,注册时的身份认证、重要通知发送等都会用到邮件发送。Sun公司提供了JavaMail用来实现邮件发送,但是配置烦琐,Spring 中提供了JavaMailSender 用来简化邮件配置,Spring Boot则提供了MailSenderAutoConfiguration 对邮件的发送做了进一步简化。

发送前的准备

使用QQ邮箱发送邮件,首先要申请开通POP3/SMTP服务或者IMAP/SMTP服务。SMTP全称为Simple Mail Transfer Protocol,译作简单邮件传输协议,它定义了邮件客户端软件与SMTP服务器之间,以及SMTP服务器与SMTP服务器之间的通信规则。也就是说,aaa@qq.com 用户先将邮件投递到腾讯的SMTP服务器,这个过程就使用了SMTP协议,然后腾讯的SMTP服务器将邮件投递到网易的SMTP服务器,这个过程依然使用了SMTP协议,SMTP服务器就是用来接收邮件的。而POP3全称为Post Office Protocol3,译作邮局协议,它定义了邮件客户端与POP3服务器之间的通信规则。该协议在什么场景下会用到呢?当邮件到达网易的SMTP服务器之后,111@163.com 用户需要登录服务器查看邮件,这个时候就用上该协议了:邮件服务商会为每一个用户提供专门的邮件存储空间,SMTP服务器收到邮件之后,将邮件保存到相应用户的邮件存储空间中,如果用户要读取邮件,就需要通过邮件服务商的POP3邮件服务器来完成。至于IMAP协议,则是对POP3协议的扩展,功能更强,作用类似。

后端java代码

UserController控制层代码:

package com.example.demo.controller;import com.example.demo.entity.User;
import com.example.demo.rest.CodeMsg;
import com.example.demo.rest.Result;
import com.example.demo.service.UserRegistService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;import javax.validation.Valid;@RestController
@CrossOrigin
public class UserController {@Autowiredprivate UserRegistService userRegistService;@PostMapping("/sendCode")public Object sendCode(@Valid User vo) {try {return userRegistService.sendCode(vo);} catch (Exception e) {e.printStackTrace();}return Result.error(CodeMsg.SERVER_ERROR);}@PostMapping("/regist")public Object startRegist(@RequestParam("username") String username , @RequestParam("code") String code) {try {return userRegistService.regist(username,code);} catch (Exception e) {e.printStackTrace();}return Result.error(CodeMsg.SERVER_ERROR);}@PostMapping("/updateCode")public Object active(@RequestParam("code") String code) {try {return userRegistService.update(code);} catch (Exception e) {e.printStackTrace();}return Result.error(CodeMsg.SERVER_ERROR);}@PostMapping("/active")public Object login(@RequestParam("username") String username, @RequestParam("pwd") String pwd) {try {return userRegistService.login(username, pwd);} catch (Exception e) {e.printStackTrace();}return Result.error(CodeMsg.SERVER_ERROR);}
}

UserDao数据连接层代码:

package com.example.demo.dao;import com.example.demo.entity.ExamScore;
import com.example.demo.entity.User;
import org.apache.ibatis.annotations.Param;import java.util.List;
import java.util.Map;public interface UserDao {void insert(User vo);void update(String code);User findByUserName(String userName);User findByNameAndPwd(Map<String, String> map);void deleteByUserName(String userName);}

UserEntity实体层代码:

package com.example.demo.entity;import java.util.Date;public class User {private Integer id;private String username;private String pwd;private Integer jh;private Integer scores;private String email;private String code;private Date createdate;public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getPwd() {return pwd;}public void setPwd(String pwd) {this.pwd = pwd;}public Integer getScores() {return scores;}public void setScores(Integer scores) {this.scores = scores;}public String getEmail() {return email;}public void setEmail(String email) {this.email = email;}public String getCode() {return code;}public void setCode(String code) {this.code = code;}public Date getCreatedate() {return createdate;}public Integer getJh() {return jh;}public void setJh(Integer jh) {this.jh = jh;}public void setCreatedate(Date createdate) {this.createdate = createdate;}@Overridepublic String toString() {return "User{" +"id=" + id +", username='" + username + '\'' +", pwd='" + pwd + '\'' +", jh=" + jh +", scores=" + scores +", email='" + email + '\'' +", code='" + code + '\'' +", createdate=" + createdate +'}';}
}

注册操作信息提示以及注册成功或失败时调用函数:

package com.example.demo.rest;/*** @description 错误信息* @author dcl* @date 2019/12/17**/
public class CodeMsg {private int code;private String msg;public static final CodeMsg SUCCESS = new CodeMsg(0, "操作成功");public static final CodeMsg REGIST_SUCCESS = new CodeMsg(0, "注册成功,点击确定前往登录界面登录");public static final CodeMsg ACTIVE_SUCCESS = new CodeMsg(0, "用户激活成功");public static final CodeMsg REGIST_FALSE = new CodeMsg(-1, "注册失败,验证码错误,请重新输入");public static final CodeMsg USEREXISTS = new CodeMsg(500101,"用户已经存在");public static final CodeMsg USENOTREXISTS = new CodeMsg(500102,"账号或密码错误");public static final CodeMsg SERVER_ERROR = new CodeMsg(500100,"服务端异常");//临期管理模块异常public CodeMsg(int code,String msg){this.code = code;this.msg = msg;}public int getCode() {return code;}public String getMsg() {return msg;}}
package com.example.demo.rest;import com.fasterxml.jackson.databind.annotation.JsonSerialize;public class Result<T>
{private int code;private String msg;@JsonSerialize(include= JsonSerialize.Inclusion.NON_NULL)private T data;/*** 返回成功时调用* @param data* @return*/public static <T> Result<T> success(T data){return new Result<T>(data);}/*** 返回失败时调用* @param data* @return*/public static <T> Result<T> error(CodeMsg cm){return new Result<T>(cm);}private Result(T data){this.code = 0;this.msg = "操作成功";this.data = data;}private Result(CodeMsg cm){if(cm == null){return;}this.code = cm.getCode();this.msg = cm.getMsg();}public int getCode() {return code;}public void setCode(int code) {this.code = code;}public String getMsg() {return msg;}public void setMsg(String msg) {this.msg = msg;}public T getData() {return data;}public void setData(T data) {this.data = data;}
}

service服务接口层:

package com.example.demo.service;import com.example.demo.entity.ExamScore;
import com.example.demo.entity.User;
import org.springframework.stereotype.Service;import java.util.List;@Service
public interface UserRegistService {Object sendCode(User vo);Object regist(String username,String code);Object update(String code);Object login(String username, String pwd);
}

serviceImpl服务接口实现层:

package com.example.demo.service.impl;import com.example.demo.dao.UserDao;
import com.example.demo.entity.User;
import com.example.demo.rest.CodeMsg;
import com.example.demo.rest.Result;
import com.example.demo.service.UserRegistService;
import com.example.demo.util.MailUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;import javax.annotation.Resource;
import java.util.*;@Service
public class UserRegistServiceImpl implements UserRegistService {private Logger logger = LoggerFactory.getLogger(com.example.demo.service.impl.UserRegistServiceImpl.class);@Resourceprivate UserDao userDao;@Overridepublic Object sendCode(User vo) {//生成 验证码 codeString code = UUID.randomUUID().toString().replace("-", "").substring(0,6);vo.setCode(code);vo.setJh(0);vo.setScores(0);vo.setCreatedate(new Date());User findByUserName = userDao.findByUserName(vo.getUsername());if (null != findByUserName) {logger.error("error:注册用户名:[{}],已存在", vo.getUsername());return Result.error(CodeMsg.USEREXISTS);}userDao.insert(vo);try {new MailUtil(vo.getEmail(), code).run();} catch (Exception e) {logger.error("error:发送邮件失败");throw new RuntimeException("发送邮件失败");}try {Thread.sleep(47000);} catch (InterruptedException e) {e.printStackTrace();}User findByUserName1 = userDao.findByUserName(vo.getUsername());if (findByUserName1.getJh() == 0){userDao.deleteByUserName(vo.getUsername());System.out.println("删除成功");return Result.error(CodeMsg.REGIST_FALSE);}else {return Result.error(CodeMsg.REGIST_SUCCESS);}}@Overridepublic Object regist(String username,String code){User findByUserName = userDao.findByUserName(username);System.out.println(code);System.out.println(findByUserName.getCode());if(code.equals(findByUserName.getCode())){System.out.println("12121212");userDao.update(code);return CodeMsg.REGIST_SUCCESS;}else {System.out.println("1111");return CodeMsg.REGIST_FALSE;}}@Overridepublic Object update(String code) {userDao.update(code);return Result.error(CodeMsg.ACTIVE_SUCCESS);}@Overridepublic Object login(String username, String pwd) {Map<String, String> map = new HashMap<>(3);map.put("username", username);map.put("pwd", pwd);User findByNameAndPwd = userDao.findByNameAndPwd(map);if (null == findByNameAndPwd) {return Result.error(CodeMsg.USENOTREXISTS);}return Result.success(null);}
}

邮件基本信息配置:

package com.example.demo.util;import com.sun.mail.util.MailSSLSocketFactory;import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import java.util.Properties;public class MailUtil {private String email;// 收件人邮箱private String code;// 激活码public MailUtil(String email, String code) {this.email = email;this.code = code;}public void run() {// 1.创建连接对象javax.mail.Session// 2.创建邮件对象 javax.mail.Message// 3.发送一封激活邮件String from = "xxx@qq.com";// 发件人电子邮箱String host = "smtp.qq.com"; // 指定发送邮件的主机smtp.qq.com(QQ)|smtp.163.com(网易)Properties properties = System.getProperties();// 获取系统属性properties.setProperty("mail.smtp.host", host);// 设置邮件服务器properties.setProperty("mail.smtp.auth", "true");// 打开认证try {//QQ邮箱需要下面这段代码,163邮箱不需要MailSSLSocketFactory sf = new MailSSLSocketFactory();sf.setTrustAllHosts(true);properties.put("mail.smtp.ssl.enable", "true");properties.put("mail.smtp.ssl.socketFactory", sf);// 1.获取默认session对象Session session = Session.getDefaultInstance(properties, new Authenticator() {public PasswordAuthentication getPasswordAuthentication() {return new PasswordAuthentication("xxx@qq.com", "授权码"); // 发件人邮箱账号、授权码}});// 2.创建邮件对象Message message = new MimeMessage(session);// 2.1设置发件人message.setFrom(new InternetAddress(from));// 2.2设置接收人message.addRecipient(Message.RecipientType.TO, new InternetAddress(email));// 2.3设置邮件主题message.setSubject("账号激活");// 2.4设置邮件内容String content = "<html><head></head><body><h1>这是一份激活文件</h1><h3>激活码,code="+ code + "</href></h3></body></html>";message.setContent(content, "text/html;charset=UTF-8");// 3.发送邮件Transport.send(message);System.out.printf("code=" + code);System.out.println("邮件成功发送!");} catch (Exception e) {e.printStackTrace();}}
}

Mapper数据库操作实现层:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.demo.dao.UserDao"><insert id="insert" parameterType="com.example.demo.entity.User">INSERT INTO t_user(USERNAME,PWD,JH,CREATEDATE,EMAIL,CODE,SCORES)VALUES(#{username,jdbcType=VARCHAR},#{pwd,jdbcType=VARCHAR},#{jh,jdbcType=INTEGER},#{createdate,jdbcType=TIMESTAMP},#{email,jdbcType=VARCHAR},#{code,jdbcType=VARCHAR},#{scores,jdbcType=INTEGER})</insert><update id="update" parameterType="java.lang.String">UPDATE t_user SET jh = 1 WHERE CODE = #{code}</update><update id="updateScores">UPDATE t_user SET SCORES = #{scores} WHERE USERNAME = #{username} AND #{scores} > SCORES</update><select id="findByUserName" parameterType="java.lang.String" resultType="com.example.demo.entity.User">SELECT * FROM t_user WHERE USERNAME = #{username}</select><select id="findByNameAndPwd" parameterType="java.util.Map" resultType="com.example.demo.entity.User">SELECT * FROM t_user WHERE USERNAME = #{username} and PWD = #{pwd}</select><delete id="deleteByUserName" parameterType="java.lang.String">DELETE FROM t_user WHERE USERNAME = #{username}</delete><select id="showAllByScores" resultType="com.example.demo.entity.User">SELECT * FROM t_user ORDER BY SCORES DESC</select><insert id="addExamScore" parameterType="com.example.demo.entity.ExamScore">insert into exam_scores (score1,score2,score3,score4,sumscore,username) values(#{score1}, #{score2},#{score3},#{score4},#{sumscore},#{username})</insert><select id="showAllScoreByUser" resultType="com.example.demo.entity.ExamScore">SELECT * FROM exam_scores where username = #{username}</select>
</mapper>

数据库配置信息:

server:port:
spring:datasource:name: url: jdbc:mysql://xxx.xx.xx.xx:xxx/xx?serverTimezone=GMT%2b8username: password: # 使用druid数据源type: com.alibaba.druid.pool.DruidDataSourcedriver-class-name: com.mysql.cj.jdbc.Driverfilters: statmaxActive: 20initialSize: 1maxWait: 60000minIdle: 1timeBetweenEvictionRunsMillis: 60000minEvictableIdleTimeMillis: 300000validationQuery: select 'x'testWhileIdle: truetestOnBorrow: falsetestOnReturn: falsepoolPreparedStatements: truemaxOpenPreparedStatements: 20
## 该配置节点为独立的节点
mybatis:mapper-locations: classpath:mapper/*Mapper.xml #注意:一定要对应mapper映射xml文件的所在路径type-aliases-package: com.example.demo.entity # 注意:对应实体类的路径

前端Vue代码

登录:

<template><div class="loginMainDiv"><headerr></headerr><div class="top_div"></div><div style="background: rgb(255, 255, 255); margin: -120px auto auto; border: 1px solid rgb(231, 231, 231); border-image: none; width: 400px; height: 224px; text-align: center;"><div style="width: 165px; height: 96px; position: absolute;"><div class="tou"></div><div class="initial_left_hand" id="left_hand"></div><div class="initial_right_hand" id="right_hand"></div></div><p style="padding: 30px 0px 10px; position: relative;"><spanclass="u_logo"></span> <input id="loginName" class="ipt" type="text" v-model="userName" placeholder="请输入用户名" value=""></p><p style="position: relative;"><span class="p_logo"></span><input class="ipt" id="password" type="password" v-model="password" placeholder="请输入密码" value=""></p><div id="errorText" style="height: 20px;margin-top:10px"><p  style="color: red;display: none">用户名密码错误请从新输入</p></div><div style="height: 50px; line-height: 50px; margin-top: 30px; border-top-color: rgb(231, 231, 231); border-top-width: 1px; border-top-style: solid;"><!--        <p style="margin: 0px 35px 20px 45px;"><span style="float: left;"><a style="color: rgb(204, 204, 204);"--><!--                                                                             href="#">忘记密码?</a></span>--><router-link to='/Register'><span style="float: left;margin-left: 10px;font-size: 14px;">没有账号?现在注册</span></router-link><span style="float: right;"><a id="loginBtn" @click="login()">登录</a></span></div></div></div>
</template><script>
import Headerr from 'components/headerr/Headerr.vue'export default {name: 'PjLogin',components:{Headerr},data () {return {userName: "",password:""}},created(){},methods:{login: function(){let fd = new FormData();fd.append("username",this.userName);fd.append("pwd",this.password);let config = {headers: {'Content-Type': 'application/x-www-form-urlencoded'}}this.$axios.post("active", fd,config).then( res => {if(res.data.msg === "操作成功"){this.$store.commit("edit",this.userName);console.log(this.$store.state.userName);this.$router.push({path:'/entry'})}else{alert("用户名或密码错误")}}).catch( res => {alert("网络错误")//alert(res.data.msg)})}}
}
</script><!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>.loginMainDiv{background-image: url(~assets/bj.jpg);width: 100%;height: 2000%;/* background-size: 100% 100%; */background-attachment: fixed;position: fixed;}body{background: #ebebeb;font-family: "Helvetica Neue","Hiragino Sans GB","Microsoft YaHei","\9ED1\4F53",Arial,sans-serif;color: #222;font-size: 12px;}*{padding: 0px;margin: 0px;}.top_div{/* background: #008ead; */width: 100%;height: 240px;}.ipt{border: 1px solid #d3d3d3;padding: 10px 10px;width: 290px;border-radius: 4px;padding-left: 35px;-webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075);box-shadow: inset 0 1px 1px rgba(0,0,0,.075);-webkit-transition: border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s;-o-transition: border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition: border-color ease-in-out .15s,box-shadow ease-in-out .15s}.ipt:focus{border-color: #66afe9;outline: none;-webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6);box-shadow: inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6)}.u_logo{background: url("~assets/images/username.png") no-repeat;padding: 10px 10px;position: absolute;top: 43px;left: 40px;}.p_logo{background: url("~assets/images/password.png") no-repeat;padding: 10px 10px;position: absolute;top: 12px;left: 40px;}a{text-decoration: none;}.tou{background: url("~assets/images/tou.png") no-repeat;width: 97px;height: 92px;position: absolute;top: -87px;left: 140px;}.left_hand{background: url("~assets/images/left_hand.png") no-repeat;width: 32px;height: 37px;position: absolute;top: -38px;left: 150px;}.right_hand{background: url("~assets/images/right_hand.png") no-repeat;width: 32px;height: 37px;position: absolute;top: -38px;right: -64px;}.initial_left_hand{background: url("~assets/images/hand.png") no-repeat;width: 30px;height: 20px;position: absolute;top: -12px;left: 100px;}.initial_right_hand{background: url("~assets/images/hand.png") no-repeat;width: 30px;height: 20px;position: absolute;top: -12px;right: -112px;}.left_handing{background: url("~assets/images/left-handing.png") no-repeat;width: 30px;height: 20px;position: absolute;top: -24px;left: 139px;}.right_handinging{background: url("~assets/images/right_handing.png") no-repeat;width: 30px;height: 20px;position: absolute;top: -21px;left: 210px;}#loginBtn {margin-right: 30px;background: rgb(0, 142, 173);padding: 7px 10px;border-radius: 4px;border: 1px solid rgb(26, 117, 152);border-image: none;color: rgb(255, 255, 255);font-weight: bold;cursor: pointer;}</style>

注册:

<template><div class="registerMainDiv"><headerr></headerr><div class="top_div"></div><divstyle="background: rgb(255, 255, 255);margin: -120px auto auto;border: 1px solid rgb(231, 231, 231);border-image: none;width: 400px;height: 270px;text-align: center;"><div style="width: 165px; height: 96px; position: absolute"><div class="tou"></div><div class="initial_left_hand" id="left_hand"></div><div class="initial_right_hand" id="right_hand"></div></div><p style="padding: 30px 0px 10px; position: relative"><span class="u_logo"></span><inputid="loginName"class="ipt"type="text"v-model="userName"placeholder="请输入用户名"value=""/></p><p style="position: relative"><span class="p_logo"></span><inputclass="ipt"id="password"type="password"v-model="password"placeholder="请输入密码"value=""/></p><p style="position: relative; margin-top: 10px"><span class="p_logo"></span><inputclass="ipt"id="password2"type="password"v-model="password2"placeholder="请输入密码"value=""/></p><p style="position: relative; margin-top: 10px"><span class="p_logo"></span><inputclass="ipt"id="email"type="email"v-model="email"placeholder="请输入邮箱"value=""/></p><span v-show="show" class="sendTestCode"><a id="loginBtn" @click="sendCode()">发送验证码</a></span><span v-show="!show" class="sendTestCode"><a id="loginBtn" style="padding: 6px 36px">{{ count }} s</a></span><div class="testCodeInfo"><p style="position: relative; margin-top: 10px"><span class="p_logo"></span><inputclass="ipt"id="testCode"type="testCode"v-model="testCode"placeholder="请输入验证码"value=""/></p></div><!-- <div id="errorText" style="height: 20px;margin-top:10px"><p  style="color: red;display: none">用户名密码错误请从新输入</p></div> --><divstyle="height: 50px;line-height: 50px;margin-top: 5px;border-top-color: rgb(231, 231, 231);border-top-width: 1px;border-top-style: solid;"><router-link to="/"><span style="float: left; margin-left: 10px; font-size: 14px">已有账号,现在登录</span></router-link><span style="float: right"><a id="loginBtn" @click="registe()">注册</a></span></div></div></div>
</template><script>
import Headerr from "components/headerr/Headerr.vue";export default {name: "Register",data() {return {userName: "",password: "",password2: "",email: "",testCode: "",show: true,count: "",timer: null,};},components: {Headerr,},created() {},methods: {sendCode() {const TIME_COUNT = 60;var reg = new RegExp("^[a-z0-9]+([._\\-]*[a-z0-9])*@([a-z0-9]+[-a-z0-9]*[a-z0-9]+.){1,63}[a-z0-9]+$"); //正则表达式let fd = new FormData();fd.append("username", this.userName);fd.append("pwd", this.password);fd.append("email", this.email);let config = {headers: {"Content-Type": "application/x-www-form-urlencoded",},};var flag = true;//判空if (this.userName == "") {alert("用户名不能为空!");flag = false;return;}//判空if (this.password == "") {alert("密码不能为空!");flag = false;return;}//判空if (this.password2 == "") {alert("确认密码不能为空!");flag = false;return;}//判空if (this.email == "") {alert("邮箱号不能为空!");flag = false;return;}//判断两次密码是否相同if (this.password != this.password2) {alert("两次密码不一致!");flag = false;return;}if (!reg.test(this.email)) {alert("请填写正确的邮箱格式!");flag = false;return;}if (this.password === this.password2 && flag) {//倒数60秒if (!this.timer) {this.count = TIME_COUNT;this.show = false;this.timer = setInterval(() => {if (this.count > 0 && this.count <= TIME_COUNT) {this.count--;} else {this.show = true;clearInterval(this.timer);this.timer = null;}}, 1000);//请求发注册码this.$axios.post("/sendCode", fd).then((res) => {// alert(res);}).catch((res) => {// alert(res.data.msg);});}}},registe() {let fd = new FormData();fd.append("username", this.userName);fd.append("code", this.testCode);this.$axios.post("/regist", fd).then((res) => {this.$confirm(res.data.msg, "提示", {cancelButtonClass: "btn-custom-cancel",}).then((action) => {if (action == "confirm") {//确认的回调if(res.data.msg == "注册成功,点击确定前往登录界面登录"){this.$router.push({ path: "/" });}}}).catch((err) => {if (err == "cancel") {//取消的回调}});}).catch((res) => {alert(res.data.msg);});},},
};
</script><!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
.registerMainDiv {background-image: url(~assets/bj.jpg);width: 100%;height: 2000%;/* background-size: 100% 100%; */background-attachment: fixed;position: fixed;
}
body {background: #ebebeb;font-family: "Helvetica Neue", "Hiragino Sans GB", "Microsoft YaHei","\9ED1\4F53", Arial, sans-serif;color: #222;font-size: 12px;
}
* {padding: 0px;margin: 0px;
}
.top_div {width: 100%;height: 240px;
}
.ipt {border: 1px solid #d3d3d3;padding: 10px 10px;width: 290px;border-radius: 4px;padding-left: 35px;-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);-webkit-transition: border-color ease-in-out 0.15s,-webkit-box-shadow ease-in-out 0.15s;-o-transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s;transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s;
}.ipt:focus {border-color: #66afe9;outline: 0;-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 8px rgba(102, 175, 233, 0.6);box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 8px rgba(102, 175, 233, 0.6);
}
.u_logo {background: url("~assets/images/username.png") no-repeat;padding: 10px 10px;position: absolute;top: 43px;left: 40px;
}
.p_logo {background: url("~assets/images/password.png") no-repeat;padding: 10px 10px;position: absolute;top: 12px;left: 40px;z-index: 9;
}
a {text-decoration: none;
}
.tou {background: url("~assets/images/tou.png") no-repeat;width: 97px;height: 92px;position: absolute;top: -87px;left: 140px;
}
.left_hand {background: url("~assets/images/left_hand.png") no-repeat;width: 32px;height: 37px;position: absolute;top: -38px;left: 150px;
}
.right_hand {background: url("~assets/images/right_hand.png") no-repeat;width: 32px;height: 37px;position: absolute;top: -38px;right: -64px;
}
.initial_left_hand {background: url("~assets/images/hand.png") no-repeat;width: 30px;height: 20px;position: absolute;top: -12px;left: 100px;
}
.initial_right_hand {background: url("~assets/images/hand.png") no-repeat;width: 30px;height: 20px;position: absolute;top: -12px;right: -112px;
}
.left_handing {background: url("~assets/images/left-handing.png") no-repeat;width: 30px;height: 20px;position: absolute;top: -24px;left: 139px;
}
.right_handinging {background: url("~assets/images/right_handing.png") no-repeat;width: 30px;height: 20px;position: absolute;top: -21px;left: 210px;
}
#loginBtn {margin-right: 30px;background: rgb(0, 142, 173);padding: 7px 10px;border-radius: 4px;border: 1px solid rgb(26, 117, 152);border-image: none;color: rgb(255, 255, 255);font-weight: bold;cursor: pointer;
}
.sendTestCode {position: relative;top: -30px;right: -130px;
}
#email {width: 180px;position: relative;left: -55px;
}
.testCodeInfo {position: relative;top: -20px;
}
</style>
<style>
.btn-custom-cancel{background-color: red;
}
</style>

SQL文件

/*Navicat Premium Data TransferSource Server         : mysqlSource Server Type    : MySQLSource Server Version : 50722Source Host           : localhost:3306Source Schema         : testTarget Server Type    : MySQLTarget Server Version : 50722File Encoding         : 65001*/SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;-- ----------------------------
-- Table structure for t_user
-- ----------------------------
DROP TABLE IF EXISTS `t_user`;
CREATE TABLE `t_user`  (`id` int(32) NOT NULL AUTO_INCREMENT,`username` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,`pwd` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,`zt` int(255) NULL DEFAULT NULL,`email` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,`code` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,`createdate` datetime(0) NULL DEFAULT NULL,PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 6 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;SET FOREIGN_KEY_CHECKS = 1;

点击链接查看项目

SpringBoot+Vue实现邮箱登录注册功能相关推荐

  1. SpringBoot+Vue实现邮箱登录注册找回密码(附接口文档)

  2. Vue项目二 登录注册功能的实现

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 一.系统注册功能的实现 1.配置注册页面路由 2.注册页面的搭建 3.api下发送ajax请求的文件创建 二.后台数据 ...

  3. 【BackEnd】SpringBoot整合MybatisPlus实现登录注册功能(适合初学者)

    一.引言 作者将代码上传到了Gitee,小伙伴可以直接Clone项目到本地 项目地址:https://gitee.com/cai-zijing/SpringBoot_MybatisPlus_Login ...

  4. vue+node---使用element框架实现的前后台用户登录注册功能

    为了更进一步清晰地了解前台数据向后台提交的过程,更好地加强巩固前端开发学习,整理了基础的[前后台用户登录注册功能]实现代码.后台通过node.js开发,数据存储在sqlite中,前台vue+eleme ...

  5. springboot使用qq邮箱进行注册登录

    springboot使用qq邮箱进行注册登录 设计依赖 springboot mybatis-plus json数据 MySQL8 lombok 先打开qq邮箱权限记住验证key 先为登录方式,先进行 ...

  6. 注册登录案例用MVC和mysql_用MVC模式实现简单用户登录注册功能

    Model2模式 Jsp+Servlet+JavaBean MVC:开发模式 M:Model 模型层 ----> JavaBean V:View 视图层 ----> Jsp C:Contr ...

  7. java wed登录面 代码_JavaWeb实现用户登录注册功能实例代码(基于Servlet+JSP+JavaBean模式)...

    下面通过通过图文并茂的方式给大家介绍JavaWeb实现用户登录注册功能实例代码,一起看看吧. 一.Servlet+JSP+JavaBean开发模式(MVC)介绍 Servlet+JSP+JavaBea ...

  8. html登陆注册功能实现,实现用户的登录注册功能

    在基于Spring Boot框架上,实现用户的登录注册功能, 首先分析前期所需要的规划. 1 实现登录注册 前端向后端发起post请求 2用户密码安全性 密码是不推荐明文入库的,在后台采取秘钥加加不可 ...

  9. 安卓通过SQLite实现登录注册功能(小白式教程)

    安卓通过SQLlite实现登录注册功能 前面基本操作看图片 第一个xml文件是:round_bg.xml,后面界面布局要用到 <?xml version="1.0" enco ...

最新文章

  1. 沈向洋博士:三十年科研路,我踩过的那些坑
  2. Ironic 裸金属管理服务的底层技术支撑
  3. 根据json对象的某一属性对其进行排序
  4. ASP.NET Core 开源项目 nopCommerce,一款沉淀13年的电商开源佳作!
  5. python转换为c代码_bash 转换为C代码
  6. 深度概览卷积神经网络全景图,没有比这更全的了!
  7. 修改caffe源码--支持多标签--关键点检测
  8. 基于卷积神经网络的大豆病害识别
  9. 寒冬下,掉队的金立、联想、魅族们还能赶上5G班车吗?
  10. 【15】淘宝sdk——入门实战之header.php制作(三)
  11. 电子邮件收发原理和JavaMail开发
  12. CSS度量单位px/pt/em/in/pc/mm/cm
  13. Adobe Dreamweaver CS6(或者CC 2018.2 SP)安装失败解决方案
  14. android电视接跳舞毯,跳舞毯怎么连接电视以及注意事项
  15. android开发笔记之materialish-progress
  16. 前端高效开发必备的js库梳理,日常使用中会持续更新
  17. ERROR security.UserGroupInformation: Priviledge...
  18. with dlz mysql 条件_Bind-DLZ with MySQL
  19. Python基于Oxford-IIIT Pet Dataset实现宠物识别系统
  20. 大爽pygame入门教程 第一节 基础知识

热门文章

  1. java校园二手书交易管理系统springboot+Vue
  2. GIS空间分析 栅格数据分析2 成本距离分析
  3. ccf 201809-4 再卖菜
  4. LVGL笔记11--lv_btn按钮
  5. 《从0到1 开启商业与未来的秘密》阅读心得
  6. 全力配合金融改革,尝试期货投资基金
  7. 融云会话界面自定义功能_Android快速集成融云
  8. C++ 进程间通信(管道)
  9. C语言编程>第二十周 ③ 请补充fun函数,该函数的功能是:把字符串s中的字符按字符的ASCII码升序排列,处理后的字符串仍然保存在原串中,字符串及其长度作为函数参数传入。
  10. qq设置头衔显示服务器异常,qq头衔如何设置