SpringBoot實(shí)現(xiàn)網(wǎng)站注冊宾舅,郵件激活碼激活功能

項(xiàng)目源碼:https://gitee.com/smfx1314/springbootemail

上一篇文章已經(jīng)講到如何springboot如何實(shí)現(xiàn)郵件的發(fā)送统阿,趁熱打鐵彩倚,這篇文章實(shí)現(xiàn)如下功能。
很多網(wǎng)站注冊功能都會給您注冊的郵箱發(fā)送一封郵件扶平,里面是一串連接帆离,點(diǎn)擊鏈接激活功能,今天咱們就實(shí)現(xiàn)這個功能结澄。

原理:
在您注冊的時候哥谷,User類中設(shè)置一個郵件碼code,同時用戶狀態(tài)未激活麻献。郵件碼可以通過UUID實(shí)現(xiàn)们妥,這樣在注冊的時候發(fā)送一封郵件,把這個郵件碼以html的格式發(fā)送到指定郵箱勉吻,然后通過點(diǎn)擊鏈接监婶,把郵件碼在提交到后臺進(jìn)行對比,如果郵件中的郵件碼跟發(fā)送時設(shè)置的一樣齿桃,就把用戶狀態(tài)改為激活惑惶,然后登陸即可。

開始編碼

第一步搭搭建開發(fā)環(huán)境源譬,只需要通過springboot整合mybatis實(shí)現(xiàn)用戶注冊登錄功能即可集惋,然后在注冊的時候調(diào)用郵件接口發(fā)送郵件就可以了

項(xiàng)目結(jié)構(gòu)

項(xiàng)目結(jié)構(gòu)

引入相關(guān)依賴,這里使用的是阿里巴巴druid數(shù)據(jù)庫連接池

pom.xml

<properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!--MyBatis-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.3.2</version>
        </dependency>

        <!--SpringBoot測試支持-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <!--MySQL-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>

        <!--SpringBoot熱部署-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <optional>true</optional> <!-- 這個需要為 true 熱部署才有效 -->
        </dependency>

        <!--Druid數(shù)據(jù)庫連接池-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.10</version>
        </dependency>
        <!--郵件-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-mail</artifactId>
        </dependency>

        <!--thymeleaf-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
    </dependencies>

上面引入了熱部署依賴踩娘,不引人頁是可以的刮刑。另外還有thymeleaf模板引擎,springboot默認(rèn)支持此引擎

引入相關(guān)依賴之后养渴,節(jié)下來根據(jù)項(xiàng)目結(jié)構(gòu)創(chuàng)建對應(yīng)的包雷绢,請參考上文中的結(jié)構(gòu)圖。在目錄結(jié)構(gòu)完善之后理卑,下面開始配置相關(guān)屬性

application.properties配置

##熱部署
spring.devtools.remote.restart.enabled=true
spring.devtools.restart.additional-paths=src/main

## 數(shù)據(jù)庫連接配置
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/test2?characterEncoding=utf-8&serverTimezone=GMT%2B8
spring.datasource.username=“你的用戶名”
spring.datasource.password=“你的密碼”

#默認(rèn)編碼配置
spring.http.encoding.charset=UTF-8
spring.http.encoding.force=true
spring.http.encoding.enabled=true
server.tomcat.uri-encoding=UTF-8

## MyBatis相關(guān)配置
mybatis.type-aliases-package=com.jiangfeixiang.springbootemail.entity
mybatis.mapper-locations=mapper/*.xml

spring.thymeleaf.prefix=classpath:/templates/

##郵箱服務(wù)器地址
##QQ smtp.qq.com
##sina smtp.sina.cn
##aliyun smtp.aliyun.com
##163 smtp.163.com
spring.mail.host=smtp.qq.com
##郵箱用戶名
spring.mail.username=1016767658@qq.com
##郵箱密碼(注意:qq郵箱應(yīng)該使用獨(dú)立密碼翘紊,去qq郵箱設(shè)置里面獲取)
spring.mail.password=ivhkrccrallkbdcf
##編碼格式
spring.mail.default-encoding=UTF-8
##發(fā)送郵件地址
spring.mail.from=1016767658@qq.com

注意:數(shù)據(jù)庫配置全部改寫成您自己的賬號密碼藐唠,數(shù)據(jù)庫等信息帆疟。郵箱配置不明白的可以參考上一篇springboot如何實(shí)現(xiàn)郵件的發(fā)送

以上都完成之后宇立,接下來是完善實(shí)體類踪宠,另外數(shù)據(jù)庫這里就不在提示了,只有一個user類妈嘹,可以自己完善一下

實(shí)體類User

public class User implements Serializable {
    private Integer id;
    private String username;
    private String password;
    private String useremail;
    /**
     * 狀態(tài):0代表未激活柳琢,1代表激活
     */
    private Integer status;
    /**
     * 利用UUID生成一段數(shù)字,發(fā)動到用戶郵箱,當(dāng)用戶點(diǎn)擊鏈接時
     * 在做一個校驗(yàn)如果用戶傳來的code跟我們發(fā)生的code一致柬脸,更改狀態(tài)為“1”來激活用戶
     */
    private String  code;

    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 getPassword() {
        return password;
    }

    public String getUseremail() {
        return useremail;
    }

    public void setUseremail(String useremail) {
        this.useremail = useremail;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public Integer getStatus() {
        return status;
    }

    public void setStatus(Integer status) {
        this.status = status;
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", password='" + password + '\'' +
                ", useremail='" + useremail + '\'' +
                ", status=" + status +
                ", code='" + code + '\'' +
                '}';
    }
}

說明:

  • 用戶狀態(tài)status:0代表未激活他去,1代表激活,注冊的時候倒堕,默認(rèn)是0灾测,只有激活郵箱激活碼可以更改為1
  • 郵箱激活碼code:利用UUID生成一段數(shù)字,發(fā)動到用戶郵箱涩馆,當(dāng)用戶點(diǎn)擊鏈接時行施,在做一個校驗(yàn),如果用戶傳來的code跟我們發(fā)送的code一致魂那,更改狀態(tài)為“1”來激活用戶

實(shí)體類完成之后下面開始完善dao以及對應(yīng)的mapper.xml文件

對應(yīng)UserDao

public interface UserDao {
    /**
     * 用戶注冊蛾号,注冊的時候默認(rèn)狀態(tài)為0:未激活,并且調(diào)用郵件服務(wù)發(fā)送激活碼到郵箱
     * @param user
     */
    void register(User user);

    /**
     * 點(diǎn)擊郵箱中的激活碼進(jìn)行激活涯雅,根據(jù)激活碼查詢用戶鲜结,之后再進(jìn)行修改用戶狀態(tài)為1進(jìn)行激活
     * @param code
     * @return
     */
    User checkCode(String code);

    /**
     * 激活賬戶,修改用戶狀態(tài)為“1”進(jìn)行激活
     * @param user
     */
    void updateUserStatus(User user);

    /**
     * 登錄活逆,根據(jù)用戶狀態(tài)為“1”來查詢
     * @param user
     * @return
     */
    User loginUser(User user);
}

代碼中有詳細(xì)說明精刷,接下來是UserDao對應(yīng)的映射文件UserMapper.xml

UserMapper.xml

<?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.jiangfeixiang.springbootemail.dao.UserDao" >

  <!--注冊用戶-->
  <insert id="register" parameterType="com.jiangfeixiang.springbootemail.entity.User" >
    insert into user ( username, password,useremail,status,code)
    values (#{username,jdbcType=VARCHAR}, #{password,jdbcType=VARCHAR}, #{useremail,jdbcType=VARCHAR},
      #{status,jdbcType=INTEGER},#{code,jdbcType=INTEGER})
  </insert>

  <!--根據(jù)激活碼code查詢用戶-->
  <select id="checkCode" parameterType="String" resultType="com.jiangfeixiang.springbootemail.entity.User">
    select * from user where code = #{code}
  </select>

  <!--激活賬戶,修改用戶狀態(tài)-->
  <update id="updateUserStatus" parameterType="com.jiangfeixiang.springbootemail.entity.User">
    update user set status=1,code=null where id=#{id}
  </update>

  <!--登錄,根據(jù) status=1 進(jìn)行查詢-->
  <select id="loginUser" resultType="com.jiangfeixiang.springbootemail.entity.User" >
    select * from user where username=#{username} and password=#{password} and status=1
  </select>
</mapper>

dao以及對象映射文件完成之后蔗候,開始編寫Service接口與實(shí)現(xiàn)類

UserService接口

public interface UserService {
    /**
     * 用戶注冊,
     * @param user
     */
    void register(User user);

    /**
     * 根據(jù)激活碼code查詢用戶怒允,之后再進(jìn)行修改狀態(tài)
     * @param code
     * @return
     */
    User checkCode(String code);

    /**
     * 激活賬戶,修改用戶狀態(tài)為“1”
     * @param user
     */
    void updateUserStatus(User user);

    /**
     * 登錄
     * @param user
     * @return
     */
    User loginUser(User user);
}

下面是與之對應(yīng)的實(shí)現(xiàn)類

UserServiceImpl實(shí)現(xiàn)類

@Service
@Transactional
public class UserServiceImpl implements UserService {

    @Autowired
    private UserDao userDao;

    /**
     * 注入郵件接口
     */
    @Autowired
    private MailService mailService;

    /**
     * 用戶注冊锈遥,同時發(fā)送一封激活郵件
     * @param user
     */
    @Override
    public void register(User user) {
        userDao.register(user);
        //獲取激活碼
        String code = user.getCode();
        System.out.println("code:"+code);
        //主題
        String subject = "來自xxx網(wǎng)站的激活郵件";
        //user/checkCode?code=code(激活碼)是我們點(diǎn)擊郵件鏈接之后根據(jù)激活碼查詢用戶纫事,如果存在說明一致,將用戶狀態(tài)修改為“1”激活
        //上面的激活碼發(fā)送到用戶注冊郵箱
        String context = "<a href=\"/user/checkCode?code="+code+"\">激活請點(diǎn)擊:"+code+"</a>";
        //發(fā)送激活郵件
        mailService.sendHtmlMail (user.getUseremail(),subject,context);
    }

    /**
     * 根據(jù)激活碼code進(jìn)行查詢用戶所灸,之后再進(jìn)行修改狀態(tài)
     * @param code
     * @return
     */
    @Override
    public User checkCode(String code) {

        return userDao.checkCode(code);
    }

    /**
     * 激活賬戶丽惶,修改用戶狀態(tài)
     * @param user
     */
    @Override
    public void updateUserStatus(User user) {
        userDao.updateUserStatus(user);
    }

    /**
     * 登錄
     * @param user
     * @return
     */
    @Override
    public User loginUser(User user) {
        User user1 = userDao.loginUser(user);
        if (user1 !=null){
            return user1;
        }
        return null;
    }
}

郵件接口

public interface MailService {

    /**
     * 發(fā)送文本郵件
     * @param to
     * @param subject
     * @param content
     */
    //void sendSimpleMail(String to, String subject, String content);

    /**
     * 發(fā)送HTML郵件,方便用戶點(diǎn)擊附帶的code用來驗(yàn)證激活賬戶
     * @param to
     * @param content
     */
    void sendHtmlMail(String to, String subject, String content);


}

下面是對應(yīng)的實(shí)現(xiàn)類

MailServiceImpl實(shí)現(xiàn)類

@Service
public class MailServiceImpl implements MailService {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());
    @Autowired
    private JavaMailSender mailSender;
    /**
     * 配置文件中我的qq郵箱
     */
    @Value("${spring.mail.from}")
    private String from;

    /**
     * 發(fā)送HTML郵件
     * @param to 收件者
     * @param subject 郵件主題
     * @param content 文本內(nèi)容
     */
    @Override
    public void sendHtmlMail(String to,String subject,String content) {
        MimeMessage message = mailSender.createMimeMessage();
        MimeMessageHelper helper = null;
        try {
            helper = new MimeMessageHelper(message, true);
            helper.setFrom(from);
            helper.setTo(subject);
            helper.setTo(to);
            helper.setText(content, true);
            mailSender.send(message);
            //日志信息
            logger.info("郵件已經(jīng)發(fā)送爬立。");
        } catch (MessagingException e) {
            logger.error("發(fā)送郵件時發(fā)生異常钾唬!", e);
        }
    }
}

主程序入口上不要忘記添加@MapperScan

@SpringBootApplication
@MapperScan("com.jiangfeixiang.springbootemail.dao")
public class SpringbootemailApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringbootemailApplication.class, args);
    }

}

DruidDbConfig數(shù)據(jù)源配置

@Configuration
public class DruidDbConfig {
    private Logger logger = LoggerFactory.getLogger(DruidDbConfig.class);

    @ConfigurationProperties(prefix = "spring.datasource")
    @Bean
   public DruidDataSource druidConfig(){

       return new DruidDataSource();
   }
}

UUIDUtils 隨機(jī)生成激活碼

public class UUIDUtils {
    public static String getUUID(){
        return UUID.randomUUID().toString().replace("-","");
    }
}

UserController控制類

@Controller
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserService userService;

    /**
     * 注冊
     * @param user
     * @return
     */
    @RequestMapping(value = "/registerUser")
    public String register(User user){
        user.setStatus(0);
        String code = UUIDUtils.getUUID()+ UUIDUtils.getUUID();
        user.setCode(code);
        userService.register(user);
        return "success";
    }

    /**
     *校驗(yàn)郵箱中的code激活賬戶
     * 首先根據(jù)激活碼code查詢用戶,之后再把狀態(tài)修改為"1"
     */
    @RequestMapping(value = "/checkCode")
    public String checkCode(String code){
        User user = userService.checkCode(code);
        System.out.println(user);
        //如果用戶不等于null侠驯,把用戶狀態(tài)修改status=1
       if (user !=null){
           user.setStatus(1);
           //把code驗(yàn)證碼清空抡秆,已經(jīng)不需要了
           user.setCode("");
           System.out.println(user);
           userService.updateUserStatus(user);
       }
        return "login";
    }

    /**
     * 跳轉(zhuǎn)到登錄頁面
     * @return login
     */
    @RequestMapping(value = "/loginPage")
    public String login(){
        return "login";
    }

    /**
     * 登錄
     */
    @RequestMapping(value = "/loginUser")
    public String login(User user, Model model){
        User u = userService.loginUser(user);
        if (u !=null){
            return "welcome";
        }
        return "login";
    }
}

首頁控制類

@Controller
public class IndexController {
    /**
     * 首頁,localhost:8080直接返回index頁面
     */
    @RequestMapping(value = "/")
    public String index(){

        return "index";
    }
}

templates下html頁面

index.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>注冊</title>
</head>
<body>
    <form action="/user/registerUser" method="post">
        用戶名:<input type="text" id="username" name="username"/><br>
        密碼:<input type="password" id="password" name="password"/><br>
        郵箱:<input type="email" id="email" name="useremail"><br>
        <input type="submit" value="注冊">
    </form>
    <a href="/user/loginPage">登錄</a>
</body>
</html>

login.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>登錄</title>
</head>
<body>
    <form action="/user/loginUser" method="post">
        用戶名:<input type="text" id="username" name="username"/><br>
        密碼:<input type="password" id="password" name="password"/><br>
    <input type="submit" value="登錄">
</form>
</body>
</html>

success.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>注冊成功</title>
</head>
<body>
    前往郵箱激活賬戶
</body>
</html>

welcome.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>歡迎</title>
</head>
<body>
    登錄成功
</body>
</html>
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末吟策,一起剝皮案震驚了整個濱河市琅轧,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌踊挠,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,548評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異效床,居然都是意外死亡睹酌,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,497評論 3 399
  • 文/潘曉璐 我一進(jìn)店門剩檀,熙熙樓的掌柜王于貴愁眉苦臉地迎上來憋沿,“玉大人,你說我怎么就攤上這事沪猴》模” “怎么了?”我有些...
    開封第一講書人閱讀 167,990評論 0 360
  • 文/不壞的土叔 我叫張陵运嗜,是天一觀的道長壶辜。 經(jīng)常有香客問我,道長担租,這世上最難降的妖魔是什么砸民? 我笑而不...
    開封第一講書人閱讀 59,618評論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮奋救,結(jié)果婚禮上岭参,老公的妹妹穿的比我還像新娘。我一直安慰自己尝艘,他們只是感情好演侯,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,618評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著背亥,像睡著了一般秒际。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上隘梨,一...
    開封第一講書人閱讀 52,246評論 1 308
  • 那天程癌,我揣著相機(jī)與錄音,去河邊找鬼轴猎。 笑死嵌莉,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的捻脖。 我是一名探鬼主播锐峭,決...
    沈念sama閱讀 40,819評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼可婶!你這毒婦竟也來了沿癞?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,725評論 0 276
  • 序言:老撾萬榮一對情侶失蹤矛渴,失蹤者是張志新(化名)和其女友劉穎椎扬,沒想到半個月后惫搏,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,268評論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡蚕涤,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,356評論 3 340
  • 正文 我和宋清朗相戀三年筐赔,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片揖铜。...
    茶點(diǎn)故事閱讀 40,488評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡茴丰,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出天吓,到底是詐尸還是另有隱情贿肩,我是刑警寧澤,帶...
    沈念sama閱讀 36,181評論 5 350
  • 正文 年R本政府宣布龄寞,位于F島的核電站汰规,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏萄焦。R本人自食惡果不足惜控轿,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,862評論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望拂封。 院中可真熱鬧茬射,春花似錦、人聲如沸冒签。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,331評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽萧恕。三九已至刚梭,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間票唆,已是汗流浹背朴读。 一陣腳步聲響...
    開封第一講書人閱讀 33,445評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留走趋,地道東北人衅金。 一個月前我還...
    沈念sama閱讀 48,897評論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像簿煌,于是被迫代替她去往敵國和親氮唯。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,500評論 2 359

推薦閱讀更多精彩內(nèi)容

  • SpringBoot集成郵件服務(wù)竟如此簡單姨伟,還等什么惩琉,快來學(xué)習(xí)漲姿勢吧!夺荒! 學(xué)習(xí)目標(biāo) 快速掌握郵件業(yè)務(wù)類的核心邏輯...
    一只襪子閱讀 27,733評論 13 103
  • 本是一匹北方狼 逼迫自己從了良 從此褪下反犬旁 溫馴好似被家養(yǎng) 獨(dú)奔獨(dú)嘯隱蒼茫 獨(dú)行獨(dú)吟人彷徨 舉杯邀月共一觴 俯...
    花飄水流閱讀 312評論 0 3
  • 淅淅瀝瀝的雨給石板路刷上了層清漆瞒渠,零星的小坑偶會躍起迸濺良蒸,又爭先恐后地鉆進(jìn)鞋與褲腳的罅隙,倏忽間在孝,大粒的水珠咚從樹...
    d97e939bcb7f閱讀 279評論 0 0
  • 冥冥之中有個聲音告訴我去公司內(nèi)部通訊軟件搜一下“小z”诚啃,輸入完名字拼音顯示“該用戶不存在”。似乎在預(yù)料之中私沮,他離職...
    大鳳爺叫2鳳閱讀 250評論 0 1