JQuery+Ajax+Struts2+Hibernate框架整合实现完整的登录注册
最近在仿造一个书城的网站: ,ui直接拿来用,前端后端自己写,目前大部分功能已经实现,
就把具体的 登录注册功能 拿来分享一下。ps:又写登录注册会不会被人喷啊=。=
一、开发环境的部署
程序结构:
bootstrap+ajax+struts2+hibernate+mysql
仅供参考:能实现相关功能即可
操作系统:ubuntu 14.10
前端框架:bootstrap 注:此框架只是为了实现用户界面,和具体功能无关
数据库:mysql-5.5 数据库工具:emma
服务器:tomcat 服务器工具:myeclipse 10(已配置好struts2和hibernate环境)
注意:
程序调试过程可能会产生乱码,只需保持所有工具编码方式相同即可。
二、项目文件配置
1、新建web project,命名为root
2、配置/webroot/web-inf/web.xml
<?xml version="1.0" encoding="utf-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/xmlschema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemalocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="webapp_id" version="3.0"> <display-name>root</display-name> <filter> <filter-name>struts2</filter-name> <filter-class> org.apache.struts2.dispatcher.ng.filter.strutsprepareandexecutefilter </filter-class> </filter> <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <error-page> <error-code>404</error-code> <location>/error.jsp</location> </error-page> <error-page> <error-code>500</error-code> <location>/error.jsp</location> </error-page> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> <welcome-file>default.html</welcome-file> <welcome-file>default.htm</welcome-file> <welcome-file>default.jsp</welcome-file> </welcome-file-list> </web-app>
3 、 配置/src/struts.xml(struts配置文件),其他的action和interceptor被我删了,这点够用了。
<?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> <package name="default" namespace="/" extends="struts-default"> <!-- 登录 --> <action name="login" class="com.action.login" method="login"></action> <!-- 登出 --> <action name="logout" class="com.action.logout" method="logout"></action> <!-- 注册 --> <action name="register" class="com.action.register" method="register"></action> <!-- 邮件发送 --> <action name="sendmail" class="com.action.sendmail" method="sendmail"></action> </package> </struts>
4、配置/src/hibernate.cfg.xml(hibernate数据库配置文件),注意倒数第4行有个<mapping />是没有的需要自己创建,将在下一步配置
<?xml version='1.0' encoding='utf-8'?> <!doctype hibernate-configuration public "-//hibernate/hibernate configuration dtd 3.0//en" "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"> <!-- generated by myeclipse hibernate tools. --> <hibernate-configuration> <session-factory> <property name="myeclipse.connection.profile">myeclipse mysql</property> <!--指明jdbc路径、指明数据库名称--> <property name="connection.url">jdbc:mysql://localhost:3306/test</property> <!--指明数据库账户和密码--> <property name="connection.username">root</property> <property name="connection.password">root</property> <!--指明jdbc驱动--> <property name="connection.driver_class">com.mysql.jdbc.driver</property> <!--指明mysql方言--> <property name="dialect">org.hibernate.dialect.mysqldialect</property> <property name="hibernate.current_session_context_class">thread</property> <property name="hibernate.dialect">org.hibernate.dialect.mysqldialect</property> <property name="show_sql">true</property> <property name="format_sql">true</property> <mapping resource="com/hibernate/bookchat.hbm.xml" /> </session-factory> </hibernate-configuration>
5、/src下创建com.hibernate包,在该包下创建bookchat.hbm.xml(hibernate对象关系映射文件),并配置
注意<class name="com.hibernate.user" />中的这个user类是自定义的数据库对象类(pojo),将在下一步配置
<?xml version="1.0"?> <!doctype hibernate-mapping public "-//hibernate/hibernate mapping dtd 3.0//en" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <!--指明bean类名,指明数据库表名--> <class name="com.hibernate.user" table="user"> <id column="id" type="int"> <generator class="native" /> </id> <!--指明数据库字段名、字段类型--> <property name="user_id" column="user_id" type="int" /> <property name="phone" column="phone" type="int" /> <property name="email" column="email" type="string" /> <property name="username" column="username" type="string" /> <property name="password" column="password" type="string" /> <property name="icon" column="icon" type="string" /> <property name="description" column="description" type="string" /> <property name="followthreadnum" column="followthreadnum" type="int" /> <property name="followpeoplenum" column="followpeoplenum" type="int" /> <property name="fansnum" column="fansnum" type="int" /> <property name="havemsg" column="havemsg" type="int" /> </class> </hibernate-mapping>
6、/src下的com.hibernate包下创建user类
package com.hibernate; public class user { private int user_id; //对应数据库中user_id private int phone; //手机号 private string email; //邮件 private string username; //用户名 private string password; //密码 private string icon; //用户头像 private string description; //自定义描述 private int followthreadnum; //关注书单数量 private int followpeoplenum; //关注的人数量 private int fansnum; //粉丝数量 private int havemsg; //当前是否有新消息 public user() { super(); } //这个构造方法在注册时有用 public user(string email, string username, string password) { // 用户内容:username,password,email // 系统定义:user_id,icon,followthreadnum,followpeoplenum,fansnum,havemsg // 留空:phone,description, this.user_id = 39212; // this.phone = phone; this.email = email; this.username = username; this.password = password; this.icon = "images/icon.png"; // this.description = description; this.followthreadnum = 0; this.followpeoplenum = 0; this.fansnum = 0; this.havemsg = 0; } public int getuser_id() { return user_id; } public void setuser_id(int user_id) { this.user_id = user_id; } public int getphone() { return phone; } public void setphone(int phone) { this.phone = phone; } public string getemail() { return email; } public void setemail(string email) { this.email = email; } 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 geticon() { return icon; } public void seticon(string icon) { this.icon = icon; } public string getdescription() { return description; } public void setdescription(string description) { this.description = description; } public int getfollowthreadnum() { return followthreadnum; } public void setfollowthreadnum(int followthreadnum) { this.followthreadnum = followthreadnum; } public int getfollowpeoplenum() { return followpeoplenum; } public void setfollowpeoplenum(int followpeoplenum) { this.followpeoplenum = followpeoplenum; } public int getfansnum() { return fansnum; } public void setfansnum(int fansnum) { this.fansnum = fansnum; } public int gethavemsg() { return havemsg; } public void sethavemsg(int havemsg) { this.havemsg = havemsg; } }
7、/src下的com.db包下创建createtable类,之后run as - java application,查看控制台是否输出了sql语句
package com.db; import org.hibernate.cfg.configuration; import org.hibernate.tool.hbm2ddl.schemaexport; public class creattabledonot { public static void main(string[] args) { // 默认读取hibernate.cfg.xml文件 configuration cfg = new configuration().configure(); schemaexport export = new schemaexport(cfg); export.create(true, true); } }
三、检查数据库
1、打开数据库gui工具,查看test数据库下是否有一个user表,若能打开user表说明之前配置成功。
2、编辑user表:设置字段默认值,可以向表中添加数据。
四、网页ui设计
1、我们在struts.xml文件配置中已经埋下伏笔:
<action name="login" class="com.action.login" method="login"></action>
<action name="logout" class="com.action.logout" method="logout"></action>
<action name="register" class="com.action.register" method="register"></action>
<action name="sendmail" class="com.action.sendmail" method="sendmail"></action>
我们可以在网页中请求/login,/logout,/register来访问这三个action处理类,当然这三个类具体的内容我们还没写,先放着。
2、现在开始思考网页设计需要什么东西...
<1> 首页提供登陆和注册链接
<2> 登陆弹出框和注册页面
<3> 登陆/注册成功,登陆和注册消失,显示用户名和退出登陆
<4> 我们想达到的效果:登陆/注册成功后显示用户名,登陆失败后动态提示错误详情!
五、jquery+ajax设计
1、 主要的jquery和ajax代码
(function(window, $) { var sokk = {}; ys.common = sokk; //邮箱验证 sokk.sendmail = function(){ var email = $("#inputemail").val().trim(); if(!checkemail(email)){ return false; } //发送请求 $.get("/sendmail","email="+email,function(data){ data = json.parse(data); tip(data.code); }) } //注册 sokk.signup = function(form){ var form = $(form); //成功方可继续执行 if(!checksignup(form.find("input"))) return false; //序列化表单,生成json对象 var jstr =form.serialize(); // var jstr = json.stringify(jform); tip(jstr); $.post("/register",jstr,function(data){ data = json.parse(data); if (data.code == 200) { location.reload(); //如何跳转到首页? } else { tip(data.code); } }) }; // 登录 sokk.login = function(form) { var form = $(form); var input = form.find("input"); var username=$.trim(input[0].value); var password=$.trim(input[1].value); if(checklogin(username,password)){ return false; } var dataparam = {}; dataparam.username = username; dataparam.password = password; // 这里的dataparam是键值对,但服务器获取的时候是?username=xx&password=xx; // 如果使用json传输那么就不能用这种方式而必须用$.ajax,而且json在服务器端还要再解析, // 所以在发送请求时,不建议使用json。接受数据可以使用json $.post("/login", dataparam, function(data) { // json字符串->json对象 data = json.parse(data); if (data.code == 200) { location.reload(); } else { tip(data.code); } }) }; //登出 sokk.logout = function(){ $.get("/logout", function (data) { //json字符串->json对象 data = json.parse(data); if (data.code==200){ location.reload(); } }) }; })(window, $)
2、自定义工具代码
// 自定义提示 function tip(info){ if(isnan(info)){ toastr.info(info); }else{ var msg; if(info<300){ switch(info){ case 100: msg="加入书架成功!"; break; case 101: msg="关注本书成功!"; break; case 102: msg="已移动到【正在看】!"; break; case 103: msg="已移动到【准备看】!"; break; case 104: msg="已移动到【已看完】!"; break; case 105: msg="已移动到【回收站】!"; break; case 110: msg="验证邮件已发送到你的邮箱!";break; case 200: msg="请求成功!"; break; case 202: msg="请求已接受,但尚未处理。"; break; case 204: msg="请求成功,但无返回内容。"; break; default : break; } toastr.success(msg); }else if(info<1000){ switch(info){ case 301: msg="请求网页的位置发生改变!"; break; case 400: msg="错误请求,请输入正确信息!"; break; case 401: msg="非法请求,未授权进入此页面!"; break; case 403: msg="拒绝请求!"; break; case 404: msg="请求页面不存在!"; break; case 408: msg="请求超时!"; break; case 500: msg="服务器出错!"; break; case 500: msg="服务不可用!"; break; case 900: msg="用户名/密码错误,请重新输入"; break; case 903: msg="服务器出错,请重试!"; break; case 904: msg="服务器无返回信息!"; break; case 905: msg="网络出错!"; break; case 906: msg="注册失败,请重试!";break; case 907: msg="邮箱验证码错误!";break; case 908: msg="用户名已存在!";break; case 909: msg="邮箱已被注册!";break; case 910: msg="验证邮件发送失败!";break; default : break; } toastr.error(msg); }else{ toastr.info(info); } } } //注册检查 function checksignup(input){ var username = $.trim(input[0].value); var password1 = $.trim(input[1].value); var password2 = $.trim(input[2].value); var email = $.trim(input[3].value); var emailcode = $.trim(input[4].value); for (var i = 0; i < input.length; i++) { if(input[i].value.length<=0){ tip("所有内容不得为空!"); return false; } }; if(username.length<4){ tip("用户名不得少于4个字符!"); return false; } if(password1!==password2){ tip("两次输入的密码不同!"); return false; } if(password1.length<6){ tip("密码不得少于6个字符!"); return false; } return true; } function checklogin(username,password){ if(!username){ tip("请输入用户名!"); return false; } if(!password){ tip("请输入密码!"); return false; } } function checkemail(email){ var reg = /^([a-za-z0-9]+[_|\_|\.]?)*[a-za-z0-9]+@([a-za-z0-9]+[_|\_|\.]?)*[a-za-z0-9]+\.[a-za-z]{2,3}$/; if(email){ if(reg.test(email)){ return true; }else{ tip("邮箱地址不符合规范!"); return false; } }else{ tip("邮箱地址不得为空!"); return false; } }
3、toastr是一个前端非阻塞的提示插件,可以到 下载使用
六、action设计
1、login.java
package com.action; import javax.servlet.http.httpservletrequest; import org.apache.struts2.servletactioncontext; import com.opensymphony.xwork2.actionsupport; import com.service.baseservice; import com.service.baseserviceimpl; import com.util.operatejson; public class login extends actionsupport { private static final long serialversionuid = 4679952956618457478l; private string username; private string password; public void login() { httpservletrequest request = servletactioncontext.getrequest(); baseservice hs = new baseserviceimpl(); operatejson oj = new operatejson(); username = request.getparameter("username"); password = request.getparameter("password"); system.out.println("用户名:" + username + "--密码:" + password); // 登陆返回用户id object obj = hs.login(username, password); if (obj != null) { system.out.println("用户名密码正确"); request.getsession().setattribute("username", username); request.getsession().setattribute("userid", obj); system.out.println("用户名" + username + "的session设置完毕~"); system.out.println("用户id的session设置完毕~"); oj.putcode(200); } else { system.out.println("用户名密码错误"); oj.putcode(900); } oj.send(); } }
2、logout.java
package com.action; import javax.servlet.http.httpservletrequest; import javax.servlet.http.httpservletresponse; import org.apache.struts2.servletactioncontext; import com.opensymphony.xwork2.actionsupport; import com.util.operatejson; public class logout extends actionsupport { private static final long serialversionuid = -6758897982192371466l; httpservletrequest request = servletactioncontext.getrequest(); httpservletresponse response = servletactioncontext.getresponse(); operatejson oj = new operatejson(); public void logout() { request.getsession().removeattribute("username"); request.getsession().invalidate(); if (request.getsession().getattribute("username") == null) { oj.putcode(200); } else { oj.putcode(903); } oj.send(); } }
3、register.java
package com.action; import javax.servlet.http.httpservletrequest; import javax.servlet.http.httpservletresponse; import org.apache.struts2.servletactioncontext; import com.hibernate.user; import com.opensymphony.xwork2.actionsupport; import com.service.baseservice; import com.service.baseserviceimpl; import com.util.operatejson; public class register extends actionsupport { private static final long serialversionuid = -3356620731966076779l; httpservletrequest request = servletactioncontext.getrequest(); httpservletresponse response = servletactioncontext.getresponse(); baseservice bs = new baseserviceimpl(); operatejson oj = new operatejson(); sendmail sm = new sendmail(); public void register() { string username = request.getparameter("username"); string password1 = request.getparameter("password1"); string password2 = request.getparameter("password2"); string password = (password1.equals(password2) ? password1 : null); string email = request.getparameter("email"); string emailcode = request.getparameter("emailcode"); // 判断用户输入和生成的邮箱验证码是否相同 if (!(emailcode.equals(sm.getmailcode()))) { oj.putcode(907); oj.send(); return; } // 检测用户名/邮箱是否唯一 if (!bs.isunique("user", "username", username)) { oj.putcode(908); oj.send(); return; } if (!bs.isunique("user", "email", email)) { oj.putcode(909); oj.send(); return; } // 构建user对象 user user = new user(email, username, password); // 建立对象关系映射 boolean reged = bs.register(user); if (reged) { system.out.println("用户注册成功"); request.getsession().setattribute("username", username); oj.putcode(200); } else { system.out.println("注册失败"); oj.putcode(906); } oj.send(); } }
4、 sendmail.java smtp协议发送邮件的类,使用前需要导入mail的jar包,同时,还要设置开启发件人邮箱的smtp服务
package com.action; import java.util.date; import java.util.properties; import javax.mail.bodypart; import javax.mail.message; import javax.mail.messagingexception; import javax.mail.multipart; import javax.mail.session; import javax.mail.transport; import javax.mail.internet.internetaddress; import javax.mail.internet.mimebodypart; import javax.mail.internet.mimemessage; import javax.mail.internet.mimemultipart; import javax.servlet.http.httpservletrequest; import org.apache.struts2.servletactioncontext; import com.opensymphony.xwork2.actionsupport; import com.util.operatejson; public class sendmail extends actionsupport { private static final long serialversionuid = -4724909293302616101l; private static string qq = "392102018"; // qq private static string host = "qq.com"; // smtp服务器主机名 private static string pass = "xxxxxxxx"; // smtp服务器密码 private static string mailcode; // 邮件验证码 operatejson oj = new operatejson(); public void sendmail() { httpservletrequest request = servletactioncontext.getrequest(); string email = request.getparameter("email"); system.out.println(email); string mailcode = sendmail.setmailcode(); try { beginsend(email, mailcode); oj.putcode(110); } catch (messagingexception e) { oj.putcode(910); } finally { oj.send(); } } public static string setmailcode() { mailcode = 100000 + (int) (math.random() * 900000) + "bc"; system.out.println(mailcode); return mailcode; } public string getmailcode() { return sendmail.mailcode; } public void beginsend(string email, string mailcode) throws messagingexception { string mailto = email; // 收件方mail地址 string mailtitle = "欢迎您使用书聊网! 立即激活您的账户"; string mailcontent = "<p>尊敬的用户:</p><p>你好!立即激活您的账户,和书聊网会员一起看书交流。要激活您的账户,只需复制下面的验证码到注册页面确认。 </p>" + mailcode + "<p>版权所有© 1999 - 2015 bookchat。保留所有权利。</p>"; // 设置主要信息 properties props = new properties(); props.put("mail.smtp.host", "smtp." + host); props.put("mail.smtp.auth", "true"); session session = session.getinstance(props); session.setdebug(true); // 开启邮件对象 mimemessage message = new mimemessage(session); // 设置发件人/收件人/主题/发信时间 internetaddress from = new internetaddress(qq + "@" + host); message.setfrom(from); internetaddress to = new internetaddress(mailto); message.setrecipient(message.recipienttype.to, to); message.setsubject(mailtitle); message.setsentdate(new date()); // 设置消息对象内容 bodypart mdp = new mimebodypart();// 新建一个存放信件内容的bodypart对象 mdp.setcontent(mailcontent, "text/html;charset=utf-8");// 给bodypart对象设置内容和格式/编码方式 multipart mm = new mimemultipart();// 新建一个mimemultipart对象用来存放bodypart对象(事实上可以存放多个) mm.addbodypart(mdp);// 将bodypart加入到mimemultipart对象中(可以加入多个bodypart) message.setcontent(mm);// 把mm作为消息对象的内容 message.savechanges(); // 开启传输对象 transport transport = session.gettransport("smtp"); transport.connect("smtp." + host, qq, pass); // 这里的115798090也要修改为您的qq号码 transport.sendmessage(message, message.getallrecipients()); transport.close(); } }
5、opreatejson
package com.util; import java.io.ioexception; import java.io.printwriter; import org.apache.struts2.servletactioncontext; import net.sf.json.jsonobject; public class operatejson { jsonobject json; public operatejson() { json = new jsonobject(); json.put("code", ""); json.put("msg", ""); json.put("data", ""); } public operatejson(string str) { json = jsonobject.fromobject(str); } public void put(string key, object value) { json.remove(key); json.put(key, value); } public void putcode(object value) { json.remove("code"); this.put("code", value); } public void putmsg(object value) { json.remove("msg"); this.put("msg", value); } public void remove(string key) { json.remove(key); } public void send() { system.out.println("----------返回的数据是:" + json); try { printwriter out = servletactioncontext.getresponse().getwriter(); out.print(json); out.flush(); } catch (ioexception e) { e.printstacktrace(); } } }
七、hibernate dao设计
这块都是一些操作数据库的内容,大家都有自己的风格,仔细一点写就好了。代码太乱,我就不放出来吓人了-.-! 。
八、总结
开始想展示下结果的还是算了,也就那么回事。一个小例子,瑕疵难免,还望大神们指正。
写完了,心情好多了,招聘会去看看也好,找不找工作不重要,重要的是我走在正确的路上,只有依靠自己才是强者...
上一篇: ajax与传统web开发的异同点
下一篇: ASP.NET文本框密码赋默认值的方法
推荐阅读
-
JQuery+Ajax+Struts2+Hibernate框架整合实现完整的登录注册
-
SSM框架下实现登录注册的示例代码
-
Python实现的登录验证系统完整案例【基于搭建的MVC框架】
-
Laravel 框架基于自带的用户系统实现登录注册及错误处理功能分析
-
Laravel框架实现修改登录和注册接口数据返回格式的方法
-
SSM框架下实现登录注册的示例代码
-
JQuery+Ajax+Struts2+Hibernate框架整合实现完整的登录注册
-
自己的系统怎么整合配套论坛,实现同步注册登录注销等
-
Python实现的登录验证系统完整案例【基于搭建的MVC框架】
-
自己的系统怎么整合配套论坛,实现同步注册登录注销等