
spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver username: root password: 123456 url: jdbc:mysql://localhost:3306/tdoor_user?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8 profiles: active: dev mail: host: smtp.sina.cn username: *******@sina.cn password: ******* port: 25 default-encoding: UTF-8 protool: stmp properties: mail: smth: auth: true strttls: enable: true required: true server: tomcat: uri-encoding: utf-8 port: 8087 servlet: context-path: / #在application.properties文件中引入日志配置文件 logging: config: classpath: logback-boot.xml
时隔一个多月后终于有空更新文章了,已经把毕业设计做得差不多了。
这篇介绍一下用邮箱完成注册的过程。
知识学习来源:https://blog.csdn.net/zhaihuilin0986/article/details/78530657
在注册的时候发送验证码之后,验证码是存在数据库的,由于技术原因没有存在redis缓存中,只能在验证前端验证码时读取数据库中的验证码。
首先第一步要做一个邮件发送器。我用的是新浪邮箱。登录新浪邮箱后进入设置,把IMAP4服务/SMTP服务打开,然后在服务器端就可以用了。
然后在 pox.xml 中 加入
<!--email依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
在resources文件夹下创建一个application.yml文件,也可以用原来的application.properties文件,配置刚刚发送邮件账号,顺便把数据库也账号密码也配置一下

spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver username: root password: 123456 url: jdbc:mysql://localhost:3306/tdoor_user?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8 profiles: active: dev mail: host: smtp.sina.cn username: *****@sina.cn password: ****** port: 25 default-encoding: UTF-8 protool: stmp properties: mail: smth: auth: true strttls: enable: true required: true server: tomcat: uri-encoding: utf-8 port: 8087 servlet: context-path: / #在application.properties文件中引入日志配置文件 logging: config: classpath: logback-boot.xml
创建发送邮箱的工具类

package com.liao.tdoor.util; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.mail.javamail.JavaMailSender; import org.springframework.mail.javamail.MimeMessageHelper; import org.springframework.stereotype.Component; import javax.mail.internet.InternetAddress; import javax.mail.internet.MimeMessage; /** * @author 廖某某 * 邮件发送工具类 * */ @Component public class SendEmailUtils { @Autowired private JavaMailSender javaMailSender; //注入JavaMailSender @Value("${spring.mail.username}") private String username; //发送邮件者 /** * 发送邮件 * @param title 标题 * @param titleWithName 是否在标题后添加名称 * @param content 邮件内容 * @param contentWithName 是否在内容后添加名称 * @param email 接收者的邮箱 */ private void sendNormalEmail(String title,boolean titleWithName,String content,boolean contentWithName,String email){ String dName="T-door官方"; MimeMessage mimeMessage=null; try{ mimeMessage=javaMailSender.createMimeMessage(); //创建要发送的消息 MimeMessageHelper helper=new MimeMessageHelper(mimeMessage,true); helper.setFrom(new InternetAddress(username,dName,"UTF-8")); //设置发送者是谁 helper.setTo(email); //接收者邮箱 title=titleWithName?title+"-"+dName:title; //标题内容 helper.setSubject(title); //发送邮件的标题 if(contentWithName){ content +="<p style='text-align:right'>"+dName+"</p>"; content +="<p style='text-align:right'>"+RandomTools.curDate("yyyy-MM-dd HH:mm:ss")+"</p>"; } helper.setText(content,true); //发送的内容 是否为HTML }catch (Exception e){ e.printStackTrace(); } javaMailSender.send(mimeMessage); } /** * 发送注册验证码 * @param email 接收者的邮箱 * @param code 验证码 */ public void sendRegisterCode(final String email,String code){ final StringBuffer sb=new StringBuffer(); //实例化一个StringBuffer sb.append("<h2>"+"亲爱的"+email+"您好!</h2>").append("<p style='text-align: center; font-size: 24px; font-weight: bold'>您的注册验证码为:"+code+"</p>"); new Thread(new Runnable() { @Override public void run() { sendNormalEmail("验证码",true,sb.toString(),true,email); } }).start(); } }
创建随机数6位生成

package com.liao.tdoor.util; import java.text.SimpleDateFormat; import java.util.Date; /** * 随机6位数生成 * @author 廖某某 */ public class RandomTools { /** 随机6位数 **/ public static String randomCode(){ Integer res=(int)((Math.random())*1000000); return res+""; } /*时间捕捉*/ public static String curDate(String pattern){ SimpleDateFormat sdf=new SimpleDateFormat(pattern); return sdf.format(new Date()); } public static String curDate(){ return curDate("yyyy-MM-dd HH:mm:ss"); } }
创建用户实体类

package com.liao.tdoor.model; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.Table; import java.io.Serializable; /** * 用户类 * @author 廖某某 */ @Entity @Table(name = "user") public class User implements Serializable { @Id @Column(name = "id") private String id; @Column(name = "email") //邮箱 private String email; @Column(name = "password") //密码 private String password; @Column(name = "tcoin") //t币 private int tcoin; @Column(name = "nickname") //昵称 private String nickname; @Column(name = "sex") //性别 private int sex; @Column(name = "address") //地址 private String address; @Column(name = "profiles") //简介 private String profiles; @Column(name = "headUrl") //头像 private String headUrl; public User(String email,String password,String nickname){ this.email=email; this.password=password; this.nickname=nickname; } public User(String nickname,String user_id){ this.nickname=nickname; this.id=user_id; } public User(){ } public void setHeadUrl(String headUrl) { this.headUrl = headUrl; } public String getHeadUrl() { return headUrl; } public String getId() { return id; } public String getEmail() { return email; } public String getPassword() { return password; } public int getTcoin() { return tcoin; } public String getNickname() { return nickname; } public int getSex() { return sex; } public String getAddress() { return address; } public String getProfiles() { return profiles; } public void setId(String id) { this.id = id; } public void setEmail(String email) { this.email = email; } public void setPassword(String password) { this.password = password; } public void setTcoin(int tcoin) { this.tcoin = tcoin; } public void setNickname(String nickname) { this.nickname = nickname; } public void setSex(int sex) { this.sex = sex; } public void setAddress(String address) { this.address = address; } public void setProfiles(String profiles) { this.profiles = profiles; } @Override public String toString() { return "User{" + "id='" + id + '\'' + ", email='" + email + '\'' + ", password='" + password + '\'' + ", tcoin=" + tcoin + ", nickname='" + nickname + '\'' + ", sex=" + sex + ", address='" + address + '\'' + ", profiles='" + profiles + '\'' + ", headUrl='" + headUrl + '\'' + '}'; } }
创建验证码实体类

package com.liao.tdoor.model; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.Table; import java.util.Date; /** * 验证码类 * @author 廖某某 */ @Entity @Table(name = "verification_code") public class VerificationCode { @Id @Column(name = "register_id") private String register_id; @Column(name = "email") private String email; @Column(name = "code") private String code; @Column(name = "time") private Date time; public String getRegister_id() { return register_id; } public String getEmail() { return email; } public String getCode() { return code; } public Date getTime() { return time; } public void setRegister_id(String register_id) { this.register_id = register_id; } public void setEmail(String email) { this.email = email; } public void setCode(String code) { this.code = code; } public void setTime(Date time) { this.time = time; } @Override public String toString() { return "VerificationCode{" + "register_id='" + register_id + '\'' + ", email='" + email + '\'' + ", code='" + code + '\'' + ", time=" + time + '}'; } }
数据返回序列化,创建返回数据类

package com.liao.tdoor.responseMsg; /** * 定义一个枚举类来维护我们的状态码 */ public enum RespCode { SUCCESS(0,"操作成功"), CANCEL(2,"取消订阅成功"), REGISTER_SUCCESS(100,"验证通过"), REGISTER_FAILED(101,"验证码不正确"), REGISTER_SEND(102,"验证码发送成功"), REGISTER_NOTS(103,"该邮箱已被注册"), CODE_EXPIRED(102,"验证码过期"), LOGIN_SUCCESS(200,"登录成功"), LOGIN_FAILED(201,"账号密码错误"), PASSWORD_FAILED(202,"密码错误"), NOT_ENOUGH(111,"你的余额不足"), LINK_FAILED(404,"找不到你的链接"), BOUGHT(3,"已经操作过了"), WARN(-1,"登录信息失效,请重新登录"); private int code; private String msg; RespCode(int code,String msg){ this.code=code; this.msg=msg; } public int getCode(){ return code; } public String getMsg(){ return msg; } }
package com.liao.tdoor.responseMsg; public class RespEntity { private int code; private String msg; private Object data; private String token; private int sign; public RespEntity(RespCode respCode){ this.code=respCode.getCode(); this.msg=respCode.getMsg(); } public RespEntity(){ } public RespEntity(RespCode respCode,String token){ this(respCode); this.token=token; } public RespEntity(int sign,Object userData){ this.sign=sign; this.data=userData; } public void setCode(int code) { this.code = code; } public void setMsg(String msg) { this.msg = msg; } public void setData(Object data) { this.data = data; } public void setToken(String token) { this.token = token; } public int getCode() { return code; } public String getMsg() { return msg; } public Object getData() { return data; } public String getToken() { return token; } public int getSign() { return sign; } public void setSign(int sign) { this.sign = sign; } @Override public String toString() { return "RespEntity{" + "code=" + code + ", msg='" + msg + '\'' + ", data=" + data + ", token='" + token + '\'' + ", sign=" + sign + '}'; } }
编写dao层

package com.liao.tdoor.dao; import com.liao.tdoor.model.VerificationCode; import org.apache.ibatis.annotations.*; import org.springframework.stereotype.Repository; import java.util.Date; @Repository public interface CodeDao { /** * 校验验证码 * @param email * @return */ @Select("select * from verification_code where email=#{email}") public VerificationCode checkCode(String email); /** * 保存验证码和用户注册邮箱到数据库 * @param email * @param code * @param time */ @Insert("insert into verification_code(register_id,email,code,time) values (#{register_id},#{email},#{code},#{time})") @SelectKey(keyProperty = "register_id", resultType = String.class, before = true, statement = "select replace(uuid(), '-', '') as id from dual") public void saveCode(String email, String code, Date time); /** * 注册完成后删除记录 * @param email */ @Delete("delete from verification_code where email=#{email}") public void deleteCode(String email); /** * 更改数据库中的验证码 * @param email * @param code */ @Update("update verification_code set code=#{code} where email=#{email}") public void changeCode(String email,String code); }
编写service层

package com.liao.tdoor.service; import com.liao.tdoor.dao.CodeDao; import com.liao.tdoor.dao.PostingDao; import com.liao.tdoor.dao.UserDao; import com.liao.tdoor.model.Posting; import com.liao.tdoor.model.User; import com.liao.tdoor.model.UserSign; import com.liao.tdoor.model.VerificationCode; import com.liao.tdoor.responseMsg.PersonalEntity; import com.liao.tdoor.responseMsg.RespCode; import com.liao.tdoor.responseMsg.RespEntity; import com.liao.tdoor.util.DateUtils; import com.liao.tdoor.util.RandomTools; import com.liao.tdoor.util.SendEmailUtils; import com.liao.tdoor.util.tokenUtil; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Repository; import org.springframework.stereotype.Service; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.List; /** * 用户服务层 * @author 廖某某 * @date 2019/02/17 */ @Service public class UserService { @Autowired UserDao userDao; @Autowired CodeDao codeDao; @Autowired SendEmailUtils sendEmailUtils; @Autowired PostingDao pDao; private RespEntity respEntity=new RespEntity(); private User user=new User(); private VerificationCode verificationCode=new VerificationCode(); private PersonalEntity infoEntity=new PersonalEntity(); /** * 发送验证码 * @param email * @return */ public RespEntity sendCode(String email){ try{ String code= RandomTools.randomCode();//产生随机的验证码 User user=new User(); user=userDao.isExistUser(email); if(user==null){ System.out.println("邮箱:"+email+"--验证码为:"+code); //修改数据库中的验证码 verificationCode=codeDao.checkCode(email); if(verificationCode!=null){ codeDao.changeCode(email,code); } //发送邮件开始 发送验证码 sendEmailUtils.sendRegisterCode(email,code); //保存验证码信息到数据库 codeDao.saveCode(email,code,new Date()); respEntity=new RespEntity(RespCode.REGISTER_SEND); }else { respEntity= new RespEntity(RespCode.REGISTER_NOTS); } }catch (Exception e){ e.printStackTrace(); } return respEntity; } /** * 注册信息提交 * @param email * @param nickName * @param password * @param registerCode * @return */ public RespEntity RegisterInfo(String email,String nickName,String password,String registerCode){ verificationCode=codeDao.checkCode(email); if(verificationCode!=null){ if(registerCode.equals(verificationCode.getCode())){ //时间校验--暂略 User user=new User(email,password,nickName); userDao.addUser(user); //删除验证码信息 codeDao.deleteCode(email); respEntity=new RespEntity(RespCode.REGISTER_SUCCESS); }else { respEntity=new RespEntity(RespCode.CODE_EXPIRED); } }else { respEntity=new RespEntity(RespCode.REGISTER_FAILED); } return respEntity; } }
编写controller层
package com.liao.tdoor.controller; import com.liao.tdoor.annotation.CurrentUser; import com.liao.tdoor.annotation.PassToken; import com.liao.tdoor.annotation.UserLoginToken; import com.liao.tdoor.model.User; import com.liao.tdoor.responseMsg.PersonalEntity; import com.liao.tdoor.responseMsg.RespEntity; import com.liao.tdoor.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.util.Map; /** * @author 廖某某 * 用户控制层 */ @RestController public class userController { @Autowired UserService userService; private RespEntity respEntity=new RespEntity(); private PersonalEntity pEntity=new PersonalEntity(); @RequestMapping("register") public RespEntity register(@RequestBody Map<String,Object> map){ String e_mail=(String)map.get("email"); String nickName=(String)map.get("nickName"); String password=(String)map.get("password"); String registerCode=(String)map.get("code"); respEntity=userService.RegisterInfo(e_mail,nickName,password,registerCode); return respEntity; } @RequestMapping("sendCode") public RespEntity sendPollCode(@RequestBody Map<String,Object> map){ String email=(String)map.get("email"); RespEntity respEntity=userService.sendCode(email); return respEntity; } }
由于前后端分离的下的项目会出现跨域问题,前端页面发起的请求会请求失败,新建一个拦截器类,拦截每次请求设置response的header。
package com.liao.tdoor.interceptor; import com.liao.tdoor.annotation.PassToken; import com.liao.tdoor.annotation.UserLoginToken; import com.liao.tdoor.dao.UserDao; import com.liao.tdoor.model.User; import com.liao.tdoor.responseMsg.CurrentUserConstants; import com.liao.tdoor.util.tokenUtil; import io.jsonwebtoken.Claims; import io.jsonwebtoken.ExpiredJwtException; import io.jsonwebtoken.Jwt; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.method.HandlerMethod; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.lang.reflect.Method; /** * 拦截器,拦截token * @author 廖某某 * @date 2019/02/18 */ public class AuthenticationInterceptor implements HandlerInterceptor { @Override public void preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object object){ //设置允许哪些域名应用进行ajax访问 httpServletResponse.setHeader("Access-Control-Allow-Origin", "*"); httpServletResponse.setHeader("Access-Control-Allow-Methods", "GET,PUT,POST,DELETE"); httpServletResponse.setHeader("Access-Control-Allow-Headers", " Origin, X-Requested-With, content-Type, Accept, Authorization"); httpServletResponse.setHeader("Access-Control-Max-Age","3600"); } // 请求处理之后进行调用,但是在视图被渲染之前(Controller方法调用之后) @Override public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception { } // 在整个请求结束之后被调用,也就是在DispatcherServlet 渲染了对应的视图之后执行(主要是用于进行资源清理工作) @Override public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e)throws Exception{ } }
大概我就记得这么多了,上面那些代码中有很多导入包的语句是暂时没有用到,所以会报错,先删除掉就好了。