黑馬旅遊網編寫練習(2)–郵箱激活功能
當用戶進行註冊時,一般會需要使用郵箱進行激活;所以在這裏也模擬一下注冊後郵箱的激活功能。
首先導入發送郵箱的jar包mail.jar;或者配置maven地址爲:
<!--javaMail-->
<dependency>
<groupId>javax.mail</groupId>
<artifactId>javax.mail-api</artifactId>
<version>1.5.6</version>
</dependency>
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>javax.mail</artifactId>
<version>1.5.3</version>
</dependency>
然後編寫Java發送郵箱的代碼,如下:
/**
* 發郵件工具類
*/
public final class MailUtils {
private static final String USER = "[email protected]"; // 發件人稱號,同郵箱地址
private static final String PASSWORD = "xxxxxxxxxxxx"; // 如果是qq郵箱可以使戶端授權碼,或者登錄密碼
/**
*
* @param to 收件人郵箱
* @param text 郵件正文
* @param title 標題
*/
/* 發送驗證信息的郵件 */
public static boolean sendMail(String to, String text, String title){
try {
final Properties props = new Properties();
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.host", "smtp.qq.com");
// 發件人的賬號
props.put("mail.user", USER);
//發件人的密碼
props.put("mail.password", PASSWORD);
// 構建授權信息,用於進行SMTP進行身份驗證
Authenticator authenticator = new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
// 用戶名、密碼
String userName = props.getProperty("mail.user");
String password = props.getProperty("mail.password");
return new PasswordAuthentication(userName, password);
}
};
// 使用環境屬性和授權信息,創建郵件會話
Session mailSession = Session.getInstance(props, authenticator);
// 創建郵件消息
MimeMessage message = new MimeMessage(mailSession);
// 設置發件人
String username = props.getProperty("mail.user");
InternetAddress form = new InternetAddress(username);
message.setFrom(form);
// 設置收件人
InternetAddress toAddress = new InternetAddress(to);
message.setRecipient(Message.RecipientType.TO, toAddress);
// 設置郵件標題
message.setSubject(title);
// 設置郵件的內容體
message.setContent(text, "text/html;charset=UTF-8");
// 發送郵件
Transport.send(message);
return true;
}catch (Exception e){
e.printStackTrace();
}
return false;
}
public static void main(String[] args) throws Exception { // 做測試用
try {
MailUtils.sendMail("[email protected]","你好,這是一封測試郵件,無需回覆。","測試郵件");
} catch (Exception e) {
//e.printStackTrace(); //發送失敗
System.out.println("郵件發送失敗");
}
System.out.println("發送成功");
}
}
注意:使用上述工具進行發送時,需要首先開啓相應的pop3服務,然後使用授權碼作爲發送郵件人的密碼使用,以防止泄露密碼
在這裏我使用的是qq郵箱給163郵箱發送郵件;所以我需要開啓QQ郵箱的pop3服務;然後我收到一個授權碼,替換上述PASSWORD = "xxxxxxxxxxxx"中的xxxxxxxxxxxx即可。
郵件發送功能測試完成後,接下來開始編寫用戶註冊後的郵箱激活功能
在開始編寫之前,還需要對之前的service層的regist方法進行修改,在此處爲用戶添加激活狀態爲N,並添加激活碼(唯一標識)。然後還需要修改dao層的regist方法,將這兩個新加的變量也寫到數據庫中。
service層的regist方法修改如下:
/**
* 註冊用戶,註冊成功返回true
* @param user
* @return
*/
@Override
public Boolean regist(User user) {
// 先設置用戶的激活狀態爲N,並添加激活碼,唯一標識
user.setStatus("N");
user.setCode(UuidUtil.getUuid());
System.out.println("Code:"+user.getCode());
// 調用dao層查詢數據庫
User u = dao.regist(user);
if(u != null){
// 註冊成功
// 給註冊用戶發送郵件提醒激活,當用戶點擊激活時,會訪問activeUserServlet,並提交該用戶的激活碼
String msg = "<div>歡迎註冊黑馬旅遊網,請點擊此處進行<a href='http://localhost/travel/activeUserServlet?code="+u.getCode()+"'>激活</a><br/><br/>本郵件由系統自動發出,請勿回覆。<br/>感謝您的使用。</div>";
MailUtils.sendMail(u.getEmail(),msg,"激活郵件");
return true;
}else {
//註冊失敗
return false;
}
}
dao層的regist方法修改如下:
/**
* 註冊用戶,返回user
* @param user
* @return
*/
@Override
public User regist(User user) {
// 編寫sql
String sql = "insert into tab_user(username,password,name,birthday,sex,telephone,email,status,code) values(?,?,?,?,?,?,?,?,?)";
// 執行sql
try {
template.update(sql,user.getUsername(),user.getPassword(),user.getName(),user.getBirthday(),
user.getSex(),user.getTelephone(),user.getEmail(),user.getStatus(),user.getCode());
} catch (DataAccessException e) {
//e.printStackTrace(); 註冊失敗
System.out.println("dao----Registered Faild!");
return null;
}
return user;
}
接下來開始編寫郵箱激活的activeUserServlet,我們已經設置了用戶點擊激活時,會訪問此資源,並且提交該用戶的唯一標識。所以我們需要通過該唯一標識,查找到該用戶,然後設置該用戶的激活狀態爲Y。激活後會跳轉到一個單獨的界面,上面會給出激活成功與否的提示,若激活成功,則給出一個登錄的超鏈接,點擊登錄後跳轉到登陸界面login.html
activeUserServlet的主要代碼如下:
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//接收用戶的激活碼
String code = request.getParameter("code");
System.out.println("code:"+code);
if(code == null || code.length() <= 0){
// 激活碼不存在
return;
}
//調用service層方法,完成郵箱的激活
UserService service = new UserServiceImpl();
Boolean activated = service.active(code);
String msg = null;
if(activated){
// 激活成功
System.out.println("Active succeed!");
msg = "激活成功,請<a href='login.html'>登錄</a>";
}else{
//激活失敗
System.out.println("Active failed!");
msg = "激活失敗,請重新激活";
}
//將消息發送給客戶端
response.setContentType("text/html;charset=utf-8");
response.getWriter().write(msg);
}
需要在service層添加一個active方法,用來激活用戶;主要代碼如下:
/**
* 通過激活碼給用戶進行激活,激活成功返回true
* @param code
* @return
*/
@Override
public Boolean active(String code) {
// 調用dao層通過激活碼查詢用戶方法
User user = dao.findUserByCode(code);
// 判斷用戶是否存在
if(user == null){
// 用戶不存在
System.out.println("service:--the user isn`t exist!");
return false;
}
// 調用dao層修改用戶激活狀態爲Y的方法
dao.updateUserStatus(user);
return true;
}
然後需要在dao層添加兩個方法,一個用來根據激活碼查詢用戶是否存在,稱作findUserByCode方法;另一個用來修改用戶的激活狀態碼爲Y,稱作updateUserStatus方法。兩個方法的主要代碼如下:
/**
* 通過激活碼查詢用戶,,若存在,返回User
* @param code
* @return
*/
@Override
public User findUserByCode(String code) {
// 定義sql
String sql = "select * from tab_user where code = ? ";
try {
// 執行sql
User user = template.queryForObject(sql, new BeanPropertyRowMapper<User>(User.class), code);
return user;
} catch (DataAccessException e) {
//e.printStackTrace(); //查詢出錯
System.out.println("NO user find, where code = " + code);
return null;
}
}
/**
* 修改用戶的激活狀態爲Y
* @param user
*/
@Override
public void updateUserStatus(User user) {
// 定義sql
String sql = "update tab_user set status = 'Y' where uid = ? ";
try {
// 執行sql
template.update(sql,user.getUid());
} catch (DataAccessException e) {
//e.printStackTrace(); //修改用戶激活狀態出錯
System.out.println("Error in updateUserStatus!");
}
}
據此,便可以實現新註冊用戶的郵箱驗證功能了;接下來便開始編寫用戶的登錄功能,只有註冊成功並進行了郵件激活的用戶纔可以登錄。