首页 > 技术文章 > springboot 前后端分离开发 从零到整(二、邮箱注册)

liao123 2019-03-09 23:06 原文

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
View Code

 

时隔一个多月后终于有空更新文章了,已经把毕业设计做得差不多了。

这篇介绍一下用邮箱完成注册的过程。

知识学习来源: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
View Code

创建发送邮箱的工具类

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();
    }
}
View Code

创建随机数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");
    }
}
View Code

创建用户实体类

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 + '\'' +
                '}';
    }
}
View Code

创建验证码实体类

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 +
                '}';
    }
}
View Code

数据返回序列化,创建返回数据类

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;
    }
}
View Code
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);
}
View 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;
    }
}
View Code

编写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{

    }
}

大概我就记得这么多了,上面那些代码中有很多导入包的语句是暂时没有用到,所以会报错,先删除掉就好了。

 

 

 

 

推荐阅读