----------------------------------------------------写在前面-------------------------------------------------------
作为一名小小程序猿,已经工作一年多了,由于平时不用功学习,导致技术上积累太单薄。2015年即将结束,突然发现自己这一年来进不如此至少,心里有点发慌。于是想改头换面,从新学习。
Java Web知识点多,想要系统的学习需要多做一些实战项目。于是我决定通过写一个个我们常用的模块来系统的学习Java web相关技术。首先决定从登陆注册模块开始,因为这是我们平时最常用的一个模块。
时间有限,我就不一一讲解项目从头到尾是如何创建的,这篇文章也是给有一定基础的Java开发人员看的。由于技术有限,难免会有很多疏忽,如果大家发现有什么不对的地方,欢迎指正!谢谢!
------------------------------------------------------------正文---------------------------------------------------
(我是用MySQL workbench创建的表,没用SQL语句。表的数据结构如下图)
主要有留个字段: username用户名,password密码,email邮箱,status激活状态,validateCode激活码,signupTime注册时间。
(这里我就只贴出execute方法里面的代码,全部代码请见github,github地址我会在博文最后贴出)
private String signupUsername; private String signupPassword; private String signupEmail; private int status; private String validateCode; private Date signupTime; private UserService userService; @Override public String execute() throws Exception { ActionContext context = ActionContext.getContext(); ValueStack stack = context.getValueStack(); signupUsername = (String) stack.findValue("signupUsername"); signupPassword = (String) stack.findValue("signupPassword"); signupPassword = MD5Util.encode2hex(signupPassword); signupEmail = (String) stack.findValue("signupEmail"); User existingUser = this.userService.find(signupEmail); if (existingUser != null) { return ERROR; } else { signupTime = new Date(); status=0; validateCode = MD5Util.encode2hex(signupEmail); User user = new User(signupUsername,signupPassword,signupEmail,status,validateCode,signupTime); userService.save(user); StringBuffer sb=new StringBuffer("Please active your account within 48 hours!"); sb.append("<br/>"); sb.append("<a href = \"http://localhost:8080/RegistrationAndLoginExample/activeAccount?signupEmail="); sb.append(signupEmail); sb.append("&validateCode="); sb.append(user.getValidateCode()); sb.append("\">Click here to activate your account!</a>"); SendEmail.send(signupEmail, sb.toString()); return SUCCESS; } }
public class SendEmail { public static final String HOST = "smtp.163.com"; public static final String PROTOCOL = "smtp"; public static final int PORT = 25; public static final String FROM = "请填写你的邮箱"; public static final String PWD = "请填写你邮箱密码"; private static Session getSession() { Properties props = new Properties(); props.put("mail.smtp.host", HOST); props.put("mail.store.protocol" , PROTOCOL); props.put("mail.smtp.port", PORT); props.put("mail.smtp.auth" , true); Authenticator authenticator = new Authenticator() { @Override protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication(FROM, PWD); } }; Session session = Session.getInstance(props , authenticator); return session; } public static void send(String toEmail , String content) { Session session = getSession(); try { System.out.println("--send--"+content); Message msg = new MimeMessage(session); msg.setFrom(new InternetAddress(FROM)); InternetAddress[] address = {new InternetAddress(toEmail)}; msg.setRecipients(Message.RecipientType.TO, address); msg.setSubject("Account Activation"); msg.setSentDate(new Date()); msg.setContent(content , "text/html;charset=utf-8"); Transport.send(msg); } catch (MessagingException mex) { mex.printStackTrace(); } } }
public class MD5Util { public static byte[] encode2bytes(String source) { byte[] result = null; try { MessageDigest md = MessageDigest.getInstance("MD5"); md.reset(); md.update(source.getBytes("UTF-8")); result = md.digest(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } return result; } public static String encode2hex(String source) { byte[] data = encode2bytes(source); StringBuffer hexString = new StringBuffer(); for (int i = 0; i < data.length; i++) { String hex = Integer.toHexString(0xff & data[i]); if (hex.length() == 1) { hexString.append('0'); } hexString.append(hex); } return hexString.toString(); } public static boolean validate(String unknown , String okHex) { return okHex.equals(encode2hex(unknown)); } }
private static final long serialVersionUID = 1L; private String signupEmail; private String validateCode; private UserService userService; @Override public String execute() throws Exception { ActionContext context = ActionContext.getContext(); ValueStack stack = context.getValueStack(); String signupEmail = (String) stack.findValue("signupEmail"); String validateCode = (String) stack.findValue("validateCode"); User user = this.userService.find(signupEmail); if(user!=null) { if(user.getStatus()==0) { Date currentTime = new Date(); currentTime.before(user.getSignupTime()); if(currentTime.before(user.getLastActivateTime())) { if(validateCode.equals(user.getValidateCode())) { //update status to 1 user.setStatus(1); this.userService.modify(user); } else { throw new ServiceException("validate code is not correct!"); } } else { throw new ServiceException("validate code has been expired!"); } } else { throw new ServiceException("email has been activated!"); } } else { throw new ServiceException("this email has not been registered!"); } return SUCCESS; }
private String email; private String password; private UserService userService; @Override public String execute() throws Exception { ActionContext context = ActionContext.getContext(); ValueStack stack = context.getValueStack(); String email = (String) stack.findValue("email"); String password = (String) stack.findValue("password"); password = MD5Util.encode2hex(password); if (email != null && email.length() > 0) { if (password != null && password.length() > 0) { if (this.userService == null) { return ERROR; } User user = this.userService.find(email); if (user != null) { if(user.getStatus()==0){ return ERROR; }else if (user.getPassword().equals(password)) { HttpServletRequest request = ServletActionContext.getRequest(); HttpSession session = request.getSession(); session.setAttribute("user", user); return SUCCESS; } } } } return ERROR; }
<!DOCTYPE html> <html> <head> <title>Login Example</title> <link rel="stylesheet" href="http://netdna.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css"> <link href="http://maxcdn.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css" rel="stylesheet"> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> <script src="http://ajax.aspnetcdn.com/ajax/jquery.validate/1.13.0/jquery.validate.min.js"></script> <script src="http://netdna.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script> <script src="js/main.js"></script> <script src="js/alert.js"></script> </head> <body> <div class="container"> <div id="loginbox" style="margin-top:50px;" class="mainbox col-md-6 col-md-offset-3 col-sm-8 col-sm-offset-2"> <div class="panel panel-info" > <div class="panel-heading"> <div class="panel-title">Sign In</div> <div style="float:right; font-size: 80%; position: relative; top:-10px"> <a href="#" onclick="$('#signupbox').hide(); $('#forgetpasswordbox').show();$('#loginbox').hide()">Forgot password?</a> </div> </div> <div style="padding-top:30px" class="panel-body" > <div style="display:none" id="login-alert" class="alert alert-danger col-sm-12"></div> <form action="login" method="post" id="loginform" class="form-horizontal" role="form"> <div class="form-group"> <label class="col-md-3 control-label" for="email">Email</label> <div class="col-md-6"> <div class="input-group"> <span class="input-group-addon"><i class="fa fa-envelope-o fa-fw"></i></span> <input id="email" name="email" type="text" placeholder="Enter Your Email" class="form-control input-md"> </div> </div> </div> <div class="form-group"> <label class="col-md-3 control-label" for="Password">Password</label> <div class="col-md-6"> <div class="input-group"> <span class="input-group-addon"><i class="fa fa-key fa-fw"></i></span> <input id="password" name="password" type="password" placeholder="Enter Your Password" class="form-control input-md"> </div> </div> </div> <div class="form-group"> <label class="col-md-3 control-label" for="Submit"></label> <div class="checkbox col-md-4"> <label><input id="login-remember" type="checkbox" name="remember" value="1" > Remember me</label> </div> <div class="col-md-4"> <input id="Submit" class="btn btn-success" type="submit" value="Login"> </div> </div> <div class="form-group"> <div class="col-md-12 control"> <div style="border-top: 1px solid#888; padding-top:15px; font-size:85%" > Don't have an account? <a href="#" onClick="$('#loginbox').hide();$('#forgetpasswordbox').hide(); $('#signupbox').show()">Sign Up Here</a> </div> </div> </div> </form> </div> </div> </div> <div id="signupbox" style="display:none; margin-top:50px" class="mainbox col-md-6 col-md-offset-3 col-sm-8 col-sm-offset-2"> <div class="panel panel-info"> <div class="panel-heading"> <div class="panel-title">Sign Up</div> <div style="float:right; font-size: 85%; position: relative; top:-10px"> <a id="signinlink" onclick="$('#signupbox').hide(); $('#forgetpasswordbox').hide();$('#loginbox').show()">Sign In</a></div> </div> <div class="panel-body" > <form action="register" method="post" id="signupform" class="form-horizontal" role="form" onSubmit="return checkForm('signUpEmail')"> <div class="form-group"> <label for="signUpEmail" class="col-md-3 control-label">Email</label> <div class="col-md-9"> <input type="text" class="form-control" id = "signupEmail" name="signupEmail" placeholder="Email Address" onblur="checkEmail(signupEmail)"> </div> </div> <div class="form-group"> <label for="username" class="col-md-3 control-label">User Name</label> <div class="col-md-9"> <input type="text" class="form-control" name="signupUsername" placeholder="User Name"> </div> </div> <div class="form-group"> <label for="signupPassword" class="col-md-3 control-label">Password</label> <div class="col-md-9"> <input type="password" id="signupPassword" class="form-control" name="signupPassword" placeholder="Password"> </div> </div> <div class="form-group"> <label for="confirmPassword" class="col-md-3 control-label">Confirm Password</label> <div class="col-md-9"> <input type="password" class="form-control" name="confirm" id="confirm" placeholder="Confirm Password"> </div> </div> <div class="form-group"> <div class="col-md-offset-3 col-md-9"> <input id="btn-signup" type="submit" class="btn btn-info" value="Sign Up"/> </div> </div> </form> </div> </div> </div> <div id="forgetpasswordbox" style="display:none; margin-top:50px" class="mainbox col-md-6 col-md-offset-3 col-sm-8 col-sm-offset-2"> <div class="panel panel-info"> <div class="panel-heading"> <div class="panel-title">Forgot Password</div> <div style="float:right; font-size: 85%; position: relative; top:-10px"><a id="signinlink" href="#" onclick="$('#signupbox').hide();$('#forgetpasswordbox').hide();$('#loginbox').show()">Sign In</a></div> </div> <div class="panel-body" > <form action="forgotPassword" method="post" id="forgotPasswordForm" class="form-horizontal" role="form" onSubmit="return checkForm('forgotPasswordEmail')"> <div class="form-group"> <label class="col-md-3 control-label" for="email">Email</label> <div class="col-md-6"> <div class="input-group"> <span class="input-group-addon"><i class="fa fa-envelope-o fa-fw"></i></span> <input id="forgotPasswordEmail" name="forgotPasswordEmail" type="text" placeholder="Enter Your Email" class="form-control input-md" onblur="checkForm('forgotPasswordEmail')"> </div> </div> <div class="col-md-3"> <input id="btn-sendEmail" type="submit" class="btn btn-success" value="Send Email"/> </div> </div> <div class="form-group"> <div class="col-md-12 control"> <div style="border-top: 1px solid#888; padding-top:15px; font-size:85%" > Don't have an account? <a href="#" onClick="$('#loginbox').hide(); $('#forgetpasswordbox').hide();$('#signupbox').show()">Sign Up Here</a> </div> </div> </div> </form> </div> </div> </div> </div> </body> </html>
这里引用了bootstrap, 和JQury, 同时用到了Ajax去实时查询用户所填写的邮箱是否已经注册过。
private String forgotPasswordEmail; private UserService userService; public String execute() throws Exception { ActionContext context = ActionContext.getContext(); ValueStack stack = context.getValueStack(); forgotPasswordEmail = (String) stack.findValue("forgotPasswordEmail"); User existingUser = this.userService.find(forgotPasswordEmail); if (existingUser == null) { return ERROR; } else { Long validateCode = System.currentTimeMillis()+30*60*1000; StringBuffer sb=new StringBuffer("Please reset your password within 30 mins!"); sb.append("<br/>"); sb.append("<a href = \"http://localhost:8080/RegistrationAndLoginExample/resetPassword?email="); sb.append(forgotPasswordEmail); sb.append("&validateCode="); sb.append(validateCode); sb.append("\">Click here to reset your password!</a>"); SendEmail.send(forgotPasswordEmail, sb.toString()); return SUCCESS; } }
当用户请求忘记密码时,发一封邮件到用户邮箱, 要求用户30分钟内完成修改密码。否则此次请求过期。
private String email; private String validateCode; private UserService userService; @Override public String execute() throws Exception { ActionContext context = ActionContext.getContext(); ValueStack stack = context.getValueStack(); String email = (String) stack.findValue("email"); String validateCode = (String) stack.findValue("validateCode"); User user = this.userService.find(email); if(user!=null) { if(user.getStatus()!=0) { Long currentTime = System.currentTimeMillis(); if(currentTime<Long.parseLong(validateCode)) { return SUCCESS; } else { return ERROR; } } else { throw new ServiceException("email has not been activated!"); } } else { throw new ServiceException("this email has not been registered!"); } }
private String email; private String oldPassword; private String newPassword; private UserService userService; @Override public String execute() throws Exception { ActionContext context = ActionContext.getContext(); ValueStack stack = context.getValueStack(); String email = (String) stack.findValue("email"); String oldPassword = (String) stack.findValue("oldPassword"); String newPassword = (String) stack.findValue("newPassword"); User user = this.userService.find(email); if(user!=null) { if(user.getStatus()==1) { if(user.getPassword().equals(MD5Util.encode2hex(oldPassword))){ user.setPassword(MD5Util.encode2hex(newPassword)); this.userService.modify(user); } else { throw new ServiceException("Old password is not correct!"); } } else { throw new ServiceException("email has not been activated!"); } } else { throw new ServiceException("this email has not been registered!"); } return SUCCESS; }
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1//EN" "http://struts.apache.org/dtds/struts-2.1.dtd"> <struts> <constant name="struts.objectFactory" value="spring" /> <package name="user" extends="struts-default"> <global-results> <result name="serviceException">/exception.jsp</result> </global-results> <global-exception-mappings> <exception-mapping exception="ServiceException" result="serviceException" /> </global-exception-mappings> <action name="login" class="LoginAction"> <result name="success">success.jsp</result> <result name="error">error.jsp</result> </action> <action name="register" class="RegisterAction"> <result name="success">success.jsp</result> <result name="error">error.jsp</result> </action> <action name="userCheck" class="UserCheckAction"> </action> <action name="activeAccount" class="ActiveAccountAction"> <result name="success">success.jsp</result> </action> <action name="forgotPassword" class="ForgotPasswordAction"> <result name="error">error.jsp</result> <result name="success">success.jsp</result> </action> <action name="resetPassword" class="ResetPasswordAction"> <result name="success">resetPassword.jsp</result> <result name="error">error.jsp</result> </action> <action name="updatePassword" class="UpdatePasswordAction"> <result name="success">success.jsp</result> <result name="error">error.jsp</result> </action> </package> <package name="ajax_json" extends="json-default"> <action name="userCheck" class="UserCheckAction"> <result name="success" type="json"/> </action> </package> </struts>
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"> </property> <property name="url" value="jdbc:mysql://127.0.0.1:3306/test"> </property> <property name="username" value="root"></property> <property name="password" value="root"></property> </bean> <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> <property name="dataSource"> <ref bean="dataSource" /> </property> <property name="hibernateProperties"> <props> <prop key="hibernate.dialect"> org.hibernate.dialect.MySQLDialect </prop> </props> </property> <property name="mappingResources"> <list> <value>com/model/User.hbm.xml</value> </list> </property> </bean> <bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate"> <property name="sessionFactory" ref="sessionFactory"></property> </bean> <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory"></property> </bean> <bean id="userDao" class="com.dao.UserDaoImpl"> <property name="hibernateTemplate" ref="hibernateTemplate"></property> </bean> <bean id="userService" class="com.service.UserServiceImpl"> <property name="userDao" ref="userDao"></property> </bean> <bean id="LoginAction" class="com.action.LoginAction"> <property name="userService" ref="userService"></property> </bean> <bean id="RegisterAction" class="com.action.RegisterAction"> <property name="userService" ref="userService"></property> </bean> <bean id="ActiveAccountAction" class="com.action.ActiveAccountAction"> <property name="userService" ref="userService"></property> </bean> <bean id="UserCheckAction" class="com.action.UserCheckAction"> <property name="userService" ref="userService"></property> </bean> <bean id="ForgotPasswordAction" class="com.action.ForgotPasswordAction"> <property name="userService" ref="userService"></property> </bean> <bean id="ResetPasswordAction" class="com.action.ResetPasswordAction"> <property name="userService" ref="userService"></property> </bean> <bean id="UpdatePasswordAction" class="com.action.UpdatePasswordAction"> <property name="userService" ref="userService"></property> </bean> </beans>
项目全部代码我已经上传到我个人的github上,欢迎大家fork,把这个模块做的越来越完善。
https://github.com/aoxinxing/RegistrationAndLoginExample