springboot 前后端分離開發 從零到整(二、郵箱注冊)


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{

    }
}

大概我就記得這么多了,上面那些代碼中有很多導入包的語句是暫時沒有用到,所以會報錯,先刪除掉就好了。

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM