最近在研究邮箱/手机号注册账号。
这一篇就是基于Java语言的SpringBoot框架的邮箱校验。当然最核心的内容与SpringBoot并没有什么太大的关联。
最基本的Mapper就不展示了,专注于核心功能的邮箱校验。
首先,构建一个User对象。
public class User{
/**
* 用户编号
*/
private Integer userId;
/**
* 用户名称
*/
private String userName;
/**
* 用户密码
*/
private String pwd;
/**
* 用户邮箱
*/
private String email;
/**
* 用户状态(实际开发中建议使用Enum,但是这个是简单的测试案例,所以使用int)
*/
private int state;
//getter,setter,construction
}
在Controller包里建一个EmailSignUpController,以便于未来扩展手机号等.
可以想象的到,这个Controller中有两个方法,一个是registerByEmail,也就是通过Email进行注册功能。另一个是Email中进行邮箱校验,起名为:confirmEmail。
package cn.edu.zzuli.controller.user.signup;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
/**
* @ClassName EmailSignUpController
* @Description 用户使用邮箱进行注册
* @Author 过道
* @Date 2018/12/23 15:56
* @Version 1.0
*/
@RestController
@RequestMapping("emailSignUp")
public class EmailSignUpController {
@Autowired
EmailSignUpService signService;
/**
* 邮件注册
*
* @return
*/
@RequestMapping(value = "registerByEmail", method = RequestMethod.POST)
public Msg registerByEmail(@RequestParam(value = "email", required = true) String email,
@RequestParam(value = "pwd", required = true) String pwd,
@RequestParam(value = "userName", required = true) String userName
) {
boolean res = signService.registerByEmail(email, pwd, userName);
if (res) {
return Msg.success();
}
return Msg.fail();
}
/**
* 校验邮箱
*/
@RequestMapping(value = "confirmEmail", method = RequestMethod.GET)
public Msg confirmEmail(@RequestParam(value = "email", required = true) String email,
@RequestParam(value = "code", required = true) String code) {
boolean res = signService.confirmEmail(email, code);
if (res) {
return Msg.success();
}
return Msg.fail();
}
}
Service中自然就是两个核心功能,一个是用户使用邮箱注册,流程如下
:用户注册-->controller---->校验邮箱格式是否合法------>不合法则直接返回----->合法则添加一个状态码为‘未激活’的用户---->给用户发一封邮件,邮件中包含一个验证码,同时将验证码存入Session中------>用户点击邮件中的链接----->跳转至confirmEmail(String Email, String code)方法------->校验code--->激活用户。
import cn.edu.zzuli.bean.User;
import cn.edu.zzuli.mapper.UserMapper;
import cn.edu.zzuli.service.user.EmailSignUpService;
import cn.edu.zzuli.util.EmailUtil;
import cn.edu.zzuli.util.FormatUtil;
import cn.edu.zzuli.util.userDataSetting.UserStateEnum;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.Random;
/**
* @ClassName EmailSignUpServiceImpl
* @Description 邮箱注册手机号的相关操作
* @Author 过道
* @Date 2018/12/23 16:01
* @Version 1.0
*/
@Service
public class EmailSignUpService{
@Autowired
UserMapper userMapper;
/**
* 通过用户的E-mail注册用户
*
* @param email
* @param pwd
* @return
*/
public boolean registerByEmail(String email, String pwd, String userName) {
// 校验邮箱是否合法
if (!FormatUtil.isEmail(email)) {
// 不合法则直接返回false
return false;
}
//先将一个未激活的用户插入到数据库中
User user = User.getNewUserByEmail(email, pwd, userName);
userMapper.addUser(user);
//邮箱合法则发送校验邮件以便于激活用户
judgeMail(email);
return true;
}
public boolean confirmEmail(String email, String code) {
HttpSession session = request.getSession();
String codeInSession = (String) session.getAttribute("code");
if (code.equals(codeInSession)) {
User user = userMapper.getUserByEmail(email);
// 激活这个用户
user.setState(UserStateEnum.NORMAL);
userMapper.updateUser(user);
return true;
}
return false;
}
@Autowired
HttpServletRequest request;
/**
* 发送给他一个校验码。
*
* @param email
*/
private void judgeMail(String email) {
HttpSession session = request.getSession();
//生成随机验证码
Random random = new Random();
StringBuilder code = new StringBuilder();
for (int i = 0; i < 6; i++) {
code.append(random.nextInt(10));
}
String massage = "您的邮箱是"+ email+",您的验证码是:" +code.toString()+"如果不知道,请无视。" ;
EmailUtil.sendMail(email, massage);
session.setAttribute("code", code.toString());
}
}
这个Service里面有三个比较难,一个是发送邮件,第二个则是校验邮件格式,第三个SpringBoot对Session的存取。
1. 发送邮件需要导入两个包。
<!-- 发送邮件所需要的jar包-->
<dependency>
<groupId>javax.activation</groupId>
<artifactId>activation</artifactId>
<version>1.1</version>
</dependency>
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.4</version>
</dependency>
这两个包导入后,写一个Email工具类->EmailUtil
import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import java.util.Date;
import java.util.Properties;
/**
* @ClassName EmailUtil
* @Description 用户邮箱的帮助类
* @Author 过道
* @Date 2018/12/22 21:21
* @Version 1.0
*/
public class EmailUtil {
// 发件人 账号和密码,我使用的是163邮箱,如何开启163邮箱的API接口,请百度。
/**
* 发送邮箱:XXX@163.com
*/
private static final String MY_EMAIL_ACCOUNT = "XXX@163.com";
/**
* 授权码:123456
*/
private static final String MY_EMAIL_PASSWORD = "123456";// 密码,是你自己的设置的授权码
// SMTP服务器(这里用的163 SMTP服务器)
/**
* 163代理服务器:smtp.163.com
*/
private static final String MEAIL_163_SMTP_HOST = "smtp.163.com";
/**
* 163 使用的端口:25
*/
private static final String SMTP_163_PORT = "25";// 端口号,这个是163使用到的;QQ的应该是465或者875
/**
* @param targetAddr 目标邮箱地址
* @param code 验证码
*/
public static void sendMail(String targetAddr, String code) {
Properties p = new Properties();
p.setProperty("mail.smtp.host", MEAIL_163_SMTP_HOST);
p.setProperty("mail.smtp.port", SMTP_163_PORT);
p.setProperty("mail.smtp.socketFactory.port", SMTP_163_PORT);
p.setProperty("mail.smtp.auth", "true");
p.setProperty("mail.smtp.socketFactory.class", "SSL_FACTORY");
Session session = Session.getInstance(p, new Authenticator() {
// 设置认证账户信息
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(MY_EMAIL_ACCOUNT, MY_EMAIL_PASSWORD);
}
});
// session.setDebug(true);
MimeMessage message = new MimeMessage(session);
try {
// 发件人
message.setFrom(new InternetAddress(MY_EMAIL_ACCOUNT));
// 收件人和抄送人
message.setRecipients(Message.RecipientType.TO, targetAddr);
// 内容(这个内容还不能乱写,有可能会被SMTP拒绝掉;多试几次吧)
message.setSubject("博客注册验证码");
message.setContent("您的验证码为 : <h1>" + code+"</h1>", "text/html;charset=UTF-8");
message.setSentDate(new Date());
message.saveChanges();
Transport.send(message);
} catch (MessagingException e) {
e.printStackTrace();
}
}
}
2. 校验邮箱格式。我这里使用的是网上提供的一套校验格式的工具类。
import java.util.regex.Pattern;
/**
* @ClassName FormatUtil
* @Description 一些格式的校验:如邮箱格式,手机号格式
* @Author 任耀
* @Date 2018/12/22 21:14
* @Version 1.0
*/
public class FormatUtil {
/**
* 正则表达式:验证用户名
*/
private static final String REGEX_USERNAME = "^[a-zA-Z]\\w{5,20}$";
/**
* 正则表达式:验证密码
*/
private static final String REGEX_PASSWORD = "^[a-zA-Z0-9]{6,20}$";
/**
* 正则表达式:验证手机号
*/
private static final String REGEX_MOBILE = "^((17[0-9])|(14[0-9])|(13[0-9])|(15[^4,\\D])|(18[0,5-9]))\\d{8}$";
/**
* 正则表达式:验证邮箱
*/
private static final String REGEX_EMAIL = "^([a-z0-9A-Z]+[-|\\.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\\.)+[a-zA-Z]{2,}$";
/**
* 正则表达式:验证汉字
*/
private static final String REGEX_CHINESE = "^[\u4e00-\u9fa5],{0,}$";
/**
* 正则表达式:验证身份证
*/
private static final String REGEX_ID_CARD = "(^\\d{18}$)|(^\\d{15}$)";
/**
* 正则表达式:验证URL
*/
private static final String REGEX_URL = "http(s)?://([\\w-]+\\.)+[\\w-]+(/[\\w- ./?%&=]*)?";
/**
* 正则表达式:验证IP地址
*/
private static final String REGEX_IP_ADDR = "(25[0-5]|2[0-4]\\d|[0-1]\\d{2}|[1-9]?\\d)";
/**
* 校验用户名
*
* @param username
* @return 校验通过返回true,否则返回false
*/
public static boolean isUsername(String username) {
return Pattern.matches(REGEX_USERNAME, username);
}
/**
* 校验密码
*
* @param password
* @return 校验通过返回true,否则返回false
*/
public static boolean isPassword(String password) {
return Pattern.matches(REGEX_PASSWORD, password);
}
/**
* 校验手机号
*
* @param mobile
* @return 校验通过返回true,否则返回false
*/
public static boolean isMobile(String mobile) {
return Pattern.matches(REGEX_MOBILE, mobile);
}
/**
* 校验邮箱
*
* @param email
* @return 校验通过返回true,否则返回false
*/
public static boolean isEmail(String email) {
return Pattern.matches(REGEX_EMAIL, email);
}
/**
* 校验汉字
*
* @param chinese
* @return 校验通过返回true,否则返回false
*/
public static boolean isChinese(String chinese) {
return Pattern.matches(REGEX_CHINESE, chinese);
}
/**
* 校验身份证
*
* @param idCard
* @return 校验通过返回true,否则返回false
*/
public static boolean isIDCard(String idCard) {
return Pattern.matches(REGEX_ID_CARD, idCard);
}
/**
* 校验URL
*
* @param url
* @return 校验通过返回true,否则返回false
*/
public static boolean isUrl(String url) {
return Pattern.matches(REGEX_URL, url);
}
/**
* 校验IP地址
*
* @param ipAddr
* @return
*/
public static boolean isIPAddr(String ipAddr) {
return Pattern.matches(REGEX_IP_ADDR, ipAddr);
}
}
关于SpringBoot的HttpSession,笨办法就是Controller层每次都去接收 HttpServletRequest,当然,这太费劲。
我选择了自动注入到类中。
@Autowired
HttpServletRequest request;
//然后再需要使用的方法中得到对应的session
// HttpSession session = request.getSession();
以上就是我最近在邮箱注册方面遇到的所有问题了。