最近在仿造一個書城的網(wǎng)站: http://www.yousuu.com ,UI直接拿來用,前端后端自己寫,目前大部分功能已經(jīng)實現(xiàn),
就把具體的 登錄注冊功能 拿來分享一下。PS:又寫登錄注冊會不會被人噴啊=。=
一、開發(fā)環(huán)境的部署
程序結(jié)構(gòu):
BootStrap+Ajax+Struts2+Hibernate+MySql
僅供參考:能實現(xiàn)相關(guān)功能即可
操作系統(tǒng):ubuntu 14.10
前端框架:BootStrap 注:此框架只是為了實現(xiàn)用戶界面,和具體功能無關(guān)
數(shù)據(jù)庫:mysql-5.5 數(shù)據(jù)庫工具:emma
服務(wù)器:tomcat 服務(wù)器工具:Myeclipse 10(已配置好Struts2和Hibernate環(huán)境)
注意:
程序調(diào)試過程可能會產(chǎn)生亂碼,只需保持所有工具編碼方式相同即可。
二、項目文件配置
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>
!-- 郵件發(fā)送 -->
action name="sendmail" class="com.action.SendMail" method="sendmail">/action>
/package>
/struts>
4、配置/src/hibernate.cfg.xml(hibernate數(shù)據(jù)庫配置文件),注意倒數(shù)第4行有個mapping />是沒有的需要自己創(chuàng)建,將在下一步配置
?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路徑、指明數(shù)據(jù)庫名稱-->
property name="connection.url">jdbc:mysql://localhost:3306/test/property>
!--指明數(shù)據(jù)庫賬戶和密碼-->
property name="connection.username">root/property>
property name="connection.password">root/property>
!--指明JDBC驅(qū)動-->
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下創(chuàng)建com.hibernate包,在該包下創(chuàng)建bookchat.hbm.xml(hibernate對象關(guān)系映射文件),并配置
注意class name="com.hibernate.User" />中的這個User類是自定義的數(shù)據(jù)庫對象類(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類名,指明數(shù)據(jù)庫表名-->
class name="com.hibernate.User" table="user">
id column="id" type="int">
generator class="native" />
/id>
!--指明數(shù)據(jù)庫字段名、字段類型-->
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包下創(chuàng)建User類
package com.hibernate;
public class User {
private int user_id; //對應(yīng)數(shù)據(jù)庫中user_id
private int phone; //手機(jī)號
private String email; //郵件
private String username; //用戶名
private String password; //密碼
private String icon; //用戶頭像
private String description; //自定義描述
private int followThreadNum; //關(guān)注書單數(shù)量
private int followPeopleNum; //關(guān)注的人數(shù)量
private int fansNum; //粉絲數(shù)量
private int haveMsg; //當(dāng)前是否有新消息
public User() {
super();
}
//這個構(gòu)造方法在注冊時有用
public User(String email, String username, String password) {
// 用戶內(nèi)容:username,password,email
// 系統(tǒng)定義: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包下創(chuàng)建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) {
// 默認(rèn)讀取hibernate.cfg.xml文件
Configuration cfg = new Configuration().configure();
SchemaExport export = new SchemaExport(cfg);
export.create(true, true);
}
}
三、檢查數(shù)據(jù)庫
1、打開數(shù)據(jù)庫GUI工具,查看test數(shù)據(jù)庫下是否有一個user表,若能打開user表說明之前配置成功。
2、編輯user表:設(shè)置字段默認(rèn)值,可以向表中添加數(shù)據(jù)。
四、網(wǎng)頁UI設(shè)計
1、我們在struts.xml文件配置中已經(jīng)埋下伏筆:
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>
我們可以在網(wǎng)頁中請求/login,/logout,/register來訪問這三個Action處理類,當(dāng)然這三個類具體的內(nèi)容我們還沒寫,先放著。
2、現(xiàn)在開始思考網(wǎng)頁設(shè)計需要什么東西...
1> 首頁提供登陸和注冊鏈接
2> 登陸彈出框和注冊頁面
3> 登陸/注冊成功,登陸和注冊消失,顯示用戶名和退出登陸
4> 我們想達(dá)到的效果:登陸/注冊成功后顯示用戶名,登陸失敗后動態(tài)提示錯誤詳情!
五、JQuery+Ajax設(shè)計
1、 主要的JQuery和Ajax代碼
(function(window, $) {
var SOKK = {};
ys.common = SOKK;
//郵箱驗證
SOKK.sendmail = function(){
var email = $("#inputEmail").val().trim();
if(!checkEmail(email)){
return false;
}
//發(fā)送請求
$.get("/sendmail","email="+email,function(data){
data = JSON.parse(data);
tip(data.code);
})
}
//注冊
SOKK.signup = function(form){
var form = $(form);
//成功方可繼續(xù)執(zhí)行
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(); //如何跳轉(zhuǎn)到首頁?
} 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是鍵值對,但服務(wù)器獲取的時候是?username=xxpassword=xx;
// 如果使用json傳輸那么就不能用這種方式而必須用$.ajax,而且json在服務(wù)器端還要再解析,
// 所以在發(fā)送請求時,不建議使用json。接受數(shù)據(jù)可以使用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(info300){
switch(info){
case 100: msg="加入書架成功!"; break;
case 101: msg="關(guān)注本書成功!"; break;
case 102: msg="已移動到【正在看】!"; break;
case 103: msg="已移動到【準(zhǔn)備看】!"; break;
case 104: msg="已移動到【已看完】!"; break;
case 105: msg="已移動到【回收站】!"; break;
case 110: msg="驗證郵件已發(fā)送到你的郵箱!";break;
case 200: msg="請求成功!"; break;
case 202: msg="請求已接受,但尚未處理。"; break;
case 204: msg="請求成功,但無返回內(nèi)容。"; break;
default : break;
}
toastr.success(msg);
}else if(info1000){
switch(info){
case 301: msg="請求網(wǎng)頁的位置發(fā)生改變!"; break;
case 400: msg="錯誤請求,請輸入正確信息!"; break;
case 401: msg="非法請求,未授權(quán)進(jìn)入此頁面!"; break;
case 403: msg="拒絕請求!"; break;
case 404: msg="請求頁面不存在!"; break;
case 408: msg="請求超時!"; break;
case 500: msg="服務(wù)器出錯!"; break;
case 500: msg="服務(wù)不可用!"; break;
case 900: msg="用戶名/密碼錯誤,請重新輸入"; break;
case 903: msg="服務(wù)器出錯,請重試!"; break;
case 904: msg="服務(wù)器無返回信息!"; break;
case 905: msg="網(wǎng)絡(luò)出錯!"; break;
case 906: msg="注冊失敗,請重試!";break;
case 907: msg="郵箱驗證碼錯誤!";break;
case 908: msg="用戶名已存在!";break;
case 909: msg="郵箱已被注冊!";break;
case 910: msg="驗證郵件發(fā)送失??!";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("所有內(nèi)容不得為空!");
return false;
}
};
if(username.length4){
tip("用戶名不得少于4個字符!");
return false;
}
if(password1!==password2){
tip("兩次輸入的密碼不同!");
return false;
}
if(password1.length6){
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("郵箱地址不符合規(guī)范!");
return false;
}
}else{
tip("郵箱地址不得為空!");
return false;
}
}
3、toastr是一個前端非阻塞的提示插件,可以到 http://www.bootcdn.cn/toastr.js/ 下載使用
六、Action設(shè)計
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設(shè)置完畢~");
System.out.println("用戶id的Session設(shè)置完畢~");
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;
}
// 構(gòu)建User對象
User user = new User(email, username, password);
// 建立對象關(guān)系映射
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協(xié)議發(fā)送郵件的類,使用前需要導(dǎo)入mail的jar包,同時,還要設(shè)置開啟發(fā)件人郵箱的smtp服務(wù)
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服務(wù)器主機(jī)名
private static String PASS = "xxxxxxxx"; // SMTP服務(wù)器密碼
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 = "歡迎您使用書聊網(wǎng)! 立即激活您的賬戶";
String mailContent = "p>尊敬的用戶:/p>p>你好!立即激活您的賬戶,和書聊網(wǎng)會員一起看書交流。要激活您的賬戶,只需復(fù)制下面的驗證碼到注冊頁面確認(rèn)。 /p>"
+ mailCode + "p>版權(quán)所有© 1999 - 2015 BookChat。保留所有權(quán)利。/p>";
// 設(shè)置主要信息
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);
// 設(shè)置發(fā)件人/收件人/主題/發(fā)信時間
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());
// 設(shè)置消息對象內(nèi)容
BodyPart mdp = new MimeBodyPart();// 新建一個存放信件內(nèi)容的BodyPart對象
mdp.setContent(mailContent, "text/html;charset=utf-8");// 給BodyPart對象設(shè)置內(nèi)容和格式/編碼方式
Multipart mm = new MimeMultipart();// 新建一個MimeMultipart對象用來存放BodyPart對象(事實上可以存放多個)
mm.addBodyPart(mdp);// 將BodyPart加入到MimeMultipart對象中(可以加入多個BodyPart)
message.setContent(mm);// 把mm作為消息對象的內(nèi)容
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("----------返回的數(shù)據(jù)是:" + json);
try {
PrintWriter out = ServletActionContext.getResponse().getWriter();
out.print(json);
out.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
}
七、Hibernate Dao設(shè)計
這塊都是一些操作數(shù)據(jù)庫的內(nèi)容,大家都有自己的風(fēng)格,仔細(xì)一點寫就好了。代碼太亂,我就不放出來嚇人了-.-! 。
八、總結(jié)
開始想展示下結(jié)果的還是算了,也就那么回事。一個小例子,瑕疵難免,還望大神們指正。
寫完了,心情好多了,招聘會去看看也好,找不找工作不重要,重要的是我走在正確的路上,只有依靠自己才是強(qiáng)者...
您可能感興趣的文章:- 防止未登錄用戶操作—基于struts2攔截器的簡單實現(xiàn)
- Struts2攔截器 關(guān)于解決登錄的問題
- 詳解Struts2中對未登錄jsp頁面實現(xiàn)攔截功能
- Struts2攔截器登錄驗證實例
- Struts2開發(fā)環(huán)境搭建 附簡單登錄功能實例
- struts2與cookie 實現(xiàn)自動登錄和驗證碼驗證實現(xiàn)代碼
- Java struts2 validate用戶登錄校驗功能實現(xiàn)
- 使用MyEclipse 開發(fā)struts2框架實現(xiàn)登錄功能(結(jié)構(gòu)教程)
- struts2+jquery組合驗證注冊用戶是否存在
- 基于struts2和hibernate實現(xiàn)登錄和注冊功能