您的位置:首页 > 编程语言 > Java开发

java代码实现注册发送邮件激活账户

2017-07-26 17:31 786 查看

        该项目使用的是SSM框架,由于是单表查询,业务逻辑比较简单,因此只配上Controller层

1.POM.xml中导入javaxmail需要的依赖
<dependency >
<groupId >com.sun.mail </groupId >
<artifactId >javax.mail </artifactId >
<version >1.5.4 </version >
</dependency >
<dependency>
<groupId>javax.activation</groupId>
<artifactId>activation</artifactId>
<version>1.1.1</version>
</dependency>

2.编辑regist.jsp
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>注册</title>
</head>
<body>
<form action="/email/regist" method="post">
<table>
<tr><td>用户名:</td><td><input type="text" name="username"/></td></tr>
<tr><td>密码:</td><td><input type="password" name="password"/></td></tr>
<tr><td>邮箱:</td><td><input type="text" name="email"/></td></tr>
<tr><td colspan="2"><input type="submit" value="注册"/></td></tr>
</table>
</form>
</body>
</html>


3.编辑User实体类
package pojo;

public class User {

private int id;
private String username;
private String password;
private String email;
private boolean activated;  //账号状态
private String codeUrl;		//激活链接中的随机码

public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public boolean isActivated() {
return activated;
}
public void setActivated(boolean activated) {
this.activated = activated;
}
public String getCodeUrl() {
return codeUrl;
}
public void setCodeUrl(String codeUrl) {
this.codeUrl = codeUrl;
}
}


4.编辑Controller
package controller;

import java.io.IOException;
import java.util.UUID;

import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import pojo.User;
import service.UserService;
import util.EmailUtils;
import util.GenerateLinkUtils;

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

@Autowired
private UserService userService;

@RequestMapping("/toregist")
public String toemail() {
return "regist";
}

@RequestMapping("/regist")
public void regist(User user,HttpSession httpSession,HttpServletResponse response) {

user.setActivated(false);  //刚注册默认是没有激活状态
user.setCodeUrl(UUID.randomUUID().toString());

//注册用户
if(userService.findUserByEmail(user.getEmail()) == null) {

userService.saveUser(user);
} else {
throw new RuntimeException("该邮箱已注册");
}

//查看是否注册成功,为实体类User的id赋值
User findUser = userService.findUserByEmail(user.getEmail());

if(findUser != null) {
user.setId(findUser.getId());
} else {
throw new RuntimeException("注册用户失败");
}

//注册成功后,发送账户激活链接
httpSession.setAttribute("user", user);
EmailUtils.sendAccountActivateEmail(user);
try {
response.setContentType("text/html;charset=utf-8");
response.getWriter().write("激活邮件已经发送,请注意提醒查收");
} catch (IOException e) {
e.printStackTrace();
}
}

@RequestMapping("/activate")
public void activate(String id,String checkCode,HttpServletResponse response) {

int idInt = Integer.parseInt(id);

//根据用户id查找用户
User user = userService.findUserById(idInt);

//验证无误,状态更改为1,即激活
if(GenerateLinkUtils.verifyCheckcode(user,checkCode)) {

//修改状态
int activated = 1;
userService.updateActivated(activated,idInt);
user.setActivated(true);
try {
response.setContentType("text/html;charset=utf-8");
response.getWriter().write("恭喜,激活成功!");
} catch (IOException e) {
e.printStackTrace();
}
}
}
}


5.编辑EmailUtils工具类
package util;

import java.util.Date;
import java.util.Properties;

import javax.mail.Authenticator;
import javax.mail.MessagingException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMessage.RecipientType;

import pojo.User;

public class EmailUtils {

private static final String FROM = "xxx@163.com";

public static void sendAccountActivateEmail(User user) {

Session session = getSession();

MimeMessage message = new MimeMessage(session);

try {
message.setSubject("这是一封激活账号的邮件");
message.setSentDate(new Date());
//setFrom 表示用哪个邮箱发送邮件
message.setFrom(new InternetAddress(FROM));
/**
* RecipientType.TO||BCC||CC
*     TO表示主要接收人
*     BCC表示秘密抄送人
*     CC表示抄送人
* InternetAddress  接收者的邮箱地址
*/
message.setRecipient(RecipientType.TO, new InternetAddress(user.getEmail()));
/*message.setContent("<a target='_BLANK' href='"+GenerateLinkUtils.generateActivateLink(user)+"'>"+user.getUsername()+"先生/女士您好,请点击此链接激活账号"+GenerateLinkUtils.generateActivateLink(user)
+"</a>","text/html;charset=utf-8");*/
message.setContent("<a target='_BLANK' href='http://www.baidu.com'>"+user.getUsername()+"先生/女士您好,请点击此链接激活账号"+GenerateLinkUtils.generateActivateLink(user)
+"</a>","text/html;charset=utf-8");
Transport.send(message);

} catch (MessagingException e) {
e.printStackTrace();
}
}

public static Session getSession() {

Properties props = new Properties();
props.setProperty("mail.transport.protocol", "smtp");//指定发送的邮箱的邮箱协议
props.setProperty("mail.smtp.host","smtp.163.com");//指定SMTP服务器
props.setProperty("mail.smtp.port", "25");  //smtp是发信邮件服务器,端口是25
props.setProperty("mail.smtp.auth","true");//指定是否需要SMTP验证

Session session = Session.getInstance(props, new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {

return new PasswordAuthentication(FROM, "此处为客户端授权密码");
}
});
return session;
}
}


6.编辑GenerateLinkUtils工具类
package util;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

import pojo.User;

public class GenerateLinkUtils {

private static final String CHECK_CODE = "checkCode";

public static String generateActivateLink(User user) {

return "http://localhost:8091/email/activate?id="+user.getId()+"&"+CHECK_CODE+"="+generateCheckcode(user);
}

/**
* 生成校验码,用户名+UUID唯一标识符,为安全把他们加密发送
* @param user
* @return
*/
private static String generateCheckcode(User user) {
String userName = user.getUsername();
String randomCode = user.getCodeUrl();
return md5(userName+":"+randomCode);
}

private static String md5(String string) {
MessageDigest md = null;

try {
md = MessageDigest.getInstance("md5");//返回实现指定摘要算法的 MessageDigest 对象。
md.update(string.getBytes());//使用指定的 byte 数组更新摘要。
byte[] md5Bytes = md.digest();//通过执行诸如填充之类的最终操作完成哈希计算。在调用此方法之后,摘要被重置。
return bytes2Hex(md5Bytes);//本信息摘要

} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
System.out.println("md5这里出错了");
}
return null;
}

//二行制转字符串
private static String bytes2Hex(byte[] byteArray) {

StringBuffer strBuf = new StringBuffer();

for (int i = 0; i < byteArray.length; i++) {
if(byteArray[i] >= 0 && byteArray[i] < 16) {
strBuf.append("0");
}
strBuf.append(Integer.toHexString(byteArray[i] & 0xFF));
}
return strBuf.toString();
}

public static boolean verifyCheckcode(User user, String checkCode) {

boolean flag = generateCheckcode(user).equals(checkCode);

return flag;
}

/**
* 补充:
* 为了显示一个byte型的单字节十六进制(两位十六进制表示)的编码,请使用:
* Integer.toHexString((byteVar & 0x000000FF) | 0xFFFFFF00).substring(6);
* byteVar & 0x00000
d50b
0FF的作用是,如果byteVar 是负数,则会清除前面24个零,正的byte整型不受影响。
* (...) | 0xFFFFFF00的作用是,如果byteVar 是正数,则置前24位为一,
* 这样toHexString输出一个小于等于15的byte整型的十六进制时,倒数第二位为零且不会被丢弃,
* 这样可以通过substring方法进行截取最后两位即可。
*/

}


7.出现异常(详细原因之前有说过)
     (1)java.lang.NoClassDefFoundError: com/sun/mail/util/MailLogger
          此异常为导的依赖不对的原因
     (2)javax.mail.AuthenticationFailedException: 550 User has no permission
         此异常是因为邮箱没有开启客户端授权密码
     (3)javax.mail.AuthenticationFailedException: 535 Error: authentication failed
        此异常表示认证为通过,通常原因为密码设置的邮箱登录密码,应当改成客户端授权密码
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: