注册页面会有如下信息
而在数据库中,其实还有用户uid, 激活码code, 还有state表示用户的状态,如果state=1表示用户已激活,可以正常登陆, state的默认值是0,这个是在user这个实体类中初始化的值,表示注册了还未激活
在index.jsp中有个注册按钮:
点击按钮后跳转到路径为/user的UserServlet上的registUI这个方法上,在这个方法中再跳转到注册的jsp页面上.
public class UserServlet extends BaseServlet {
public String registUI(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
return "/jsp/register.jsp";
}
注册的jsp页面上的表单
当客户输入具体信息后点击注册按钮后,就会跳转到UserServlet的registe方法中
public String register(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
//封装数据
User user=new User();
try {
//因为我数据库里有个用户id,而这个id不是用户在注册的时候自己填的,而是后台自动生成的,所以我们需要这这里设置一下随机生成 id;
user.setUid(UUID.randomUUID().toString().replace("-", "").toUpperCase());
//code是激活码,用户注册后要通过邮箱激活码激活;这个也是随机生成的
user.setCode(UUID.randomUUID().toString().replace("-", "").toUpperCase());
//因为注册页面有个生日选项,在user这个javabean中,数据类型为Date(一般建议为string类型,就不需要转换了)
ConvertUtils.register(new DateLocaleConverter(), Date.class);//这个是BeanUtils提供的方法,这一行的代码是固定的,无须改动
BeanUtils.populate(user, request.getParameterMap());
//对用户密码进行加密处理,用到的是md5算法加密,具体代码见下面,这里需注意,因为加密后的密码很长,所以在数据库中password varchar(200),字段长度要大点
user.setPassword(MD5Utils.md5(user.getPassword()));
//调用业务逻辑
UserService us=new UserServiceImpl();
us.add(user);
request.setAttribute("msg", "注册成功,快去邮箱激活吧");
return "/jsp/msg.jsp";//返回要BaseServlet做转发处理
} catch (Exception e) {
e.printStackTrace();
request.setAttribute("msg", "稍等,出问题了");
return "/jsp/msg.jsp";//返回要BaseServlet做转发处理
}
}
而在UserServiceImpl的代码如下:
public class UserServiceImpl implements UserService {
/**
* 注册用户,发送激活邮件
*/
@Override
public void add(User user) throws Exception {
UserDao ud=new UserDaoImpl();
ud.add(user);
//发送激活邮件
//email:收件人地址
//emailMsg:邮件的内容
String emailMsg="欢迎您注册成为我们的会员,点击链接激活";
MailUtils.sendMail(user.getEmail(), emailMsg);//这个是一个工具类,代码见下面解释
}
/**
* 用户激活
*/
@Override
public User findUserByCode(String code) throws Exception {
UserDao ud=new UserDaoImpl();
User user=ud.findUserByCode(code);
if(user==null) {//说明该用户没有注册成功;返回null,在UserServl中会做判断
return null;
}
user.setState(1);//如果注册成功了就把用户的状态从初始值0改为1,说明已经激活了
ud.update(user);
return user;
}
}
这里是上面调用的UserDaoImpl里面的方法;
public class UserDaoImpl implements UserDao {
/**
* 用户注册后向数据库里添加该用户
*/
@Override
public void add(User user) throws Exception {
//c3p0Utils是自己写的数据池操作
QueryRunner qr=new QueryRunner(C3P0Utils.getDatasource());
//向数据库里插入数据(预编译写法)
String sql="insert into users values(?,?,?,?,?,?,?,?,?,?)";
//写入实际参数
qr.update(sql, user.getUid(),user.getUsername(),user.getPassword(),user.getName(),user.getEmail(),user.getTelephone(),user.getBirthday(),user.getSex(),user.getState(),user.getCode());
}
/**
* 用户注册后,通过激活码查询数据库中有没有该用户
*/
@Override
public User findUserByCode(String code) throws Exception {
QueryRunner qr=new QueryRunner(C3P0Utils.getDatasource());
String sql="select * from users where code=?";
return qr.query(sql, new BeanHandler<>(User.class), code);
}
/**
* 修改用户的state状态为1,则表示已激活,状态初识为0,表示为激活
* @throws SQLException
*/
@Override
public void update(User user) throws SQLException {
QueryRunner qr=new QueryRunner(C3P0Utils.getDatasource());
String sql="update users set username=?,password=?,name=?,email=?,telephone=?,birthday=?,sex=?,state=?,code=? where uid=?";
qr.update(sql,user.getUsername(),user.getPassword(),user.getName(),user.getEmail(),user.getTelephone(),user.getBirthday(),user.getSex(),user.getState(),null,user.getUid());
//把code值置null,说明激活码只能用一次,激活后激活码就会置空
}
}
最后是邮箱发送激活码的工具类的代码,只需3个注释为/** */的地方代码改为自己的邮箱服务器和账户密码即可
public class MailUtils {
public static void sendMail(String email, String emailMsg)
throws AddressException, MessagingException {
// 1.创建一个程序与邮件服务器会话对象 Session
Properties props = new Properties();
//设置发送的协议
props.setProperty("mail.transport.protocol", "SMTP");
//设置发送邮件的服务器
props.setProperty("mail.host", "localhost");/**localhost自己根据邮箱服务器修改的,我用的是本地的eyou服务器*/
props.setProperty("mail.smtp.auth", "true");// 指定验证为true
// 创建验证器
Authenticator auth = new Authenticator() {
public PasswordAuthentication getPasswordAuthentication() {
//设置发送人的帐号和密码
return new PasswordAuthentication("service", "123");/**eyou服务器中设置的管理员的账号密码*/
}
};
Session session = Session.getInstance(props, auth);
// 2.创建一个Message,它相当于是邮件内容
Message message = new MimeMessage(session);
//设置发送者
message.setFrom(new InternetAddress("[email protected]"));/**eyou服务器中设置的管理员的邮箱账号*/
//设置发送方式与接收者
message.setRecipient(RecipientType.TO, new InternetAddress(email));
//设置邮件主题
message.setSubject("用户激活");
//设置邮件内容
message.setContent(emailMsg, "text/html;charset=utf-8");
// 3.创建 Transport用于将邮件发送
Transport.send(message);
}
}
最后是密码加密的算法工具类代码
public class MD5Utils {
public static String md5(String plainText) {
byte[] secretBytes = null;
try {
secretBytes = MessageDigest.getInstance("md5").digest(
plainText.getBytes());
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException("找不到md5算法");
}
String md5code = new BigInteger(1, secretBytes).toString(16);
for (int i = 0; i < 32 - md5code.length(); i++) {
md5code = "0" + md5code;
}
return md5code;
}
做完了注册了,接下来就是登录的操作:在首页里,我加了C标签做判断,如果用户已经登录了,就会显示登录后的首页,如果用户没有登录的话,就会显示没有登录前的首页.
用户点击登录的时候会跳转到/user的UserServlet的loginUI这个方法上;
public String loginUI(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
return "/jsp/login.jsp";
}
然后再由这个方法请求转发到login.jsp这个页面上;
会员登录USER LOGIN
${msg }