欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

JAVA实现简单系统登陆注册模块

程序员文章站 2024-03-05 20:29:07
前期准备 首先要先明确有个大体的思路,要实现什么样的功能,了解完成整个模块要运用到哪些方面的知识,以及从做的过程中去发现自己的不足。技术方面的进步大都都需要从实践中出来的...

前期准备
首先要先明确有个大体的思路,要实现什么样的功能,了解完成整个模块要运用到哪些方面的知识,以及从做的过程中去发现自己的不足。技术方面的进步大都都需要从实践中出来的。
功能:用户注册功能+系统登录功能+生成验证码
知识:窗体设计、数据库设计、javabean封装属性、jdbc实现对数据库的连接、验证码(包括彩色验证码)生成技术,还有就些比如像使用正则表达式校验用户注册信息、随机获得字符串、对文本可用字符数的控制等
设计的模块预览图:

JAVA实现简单系统登陆注册模块JAVA实现简单系统登陆注册模块

JAVA实现简单系统登陆注册模块

彩色验证码预览图:

JAVA实现简单系统登陆注册模块

所用数据库:mysql

数据库设计

创建一个数据库db_database01,其中包含一个表格tb_user,用来保存用户的注册的数据。
其中包含4个字段
id int(11)
username varchar(15)
password varchar(20)
email varchar(45)

mysql语句可以这样设计:

create schema db_database01;
use db_database01;
create table tb_user(
id int(11) not null auto_increment primary key,
username varchar(15) not null,
password varchar(20) not null,
email varchar(45) not null
);
insert into tb_user values(1,"lixiyu","lixiyu",lixiyu419@gmail.com);

这样把lixiyu作为用户名。
select语句检查一下所建立的表格:

JAVA实现简单系统登陆注册模块

编写javabean封装用户属性

package com.lixiyu.model;
public class user {
private int id;// 编号
private string username;// 用户名
private string password;// 密码
private string email;// 电子邮箱
public int getid() {
return id;
}
public void setid(int id) {
this.id = id;
}
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 getemail() {
return email;
}
public void setemail(string email) {
this.email = email;
}
}

编写jdbc工具类

将与数据库操作相关的代码放置在dbconfig接口和dbhelper类中
dbconfig接口用于保存数据库、用户名和密码信息
代码:

package com.lixiyu.util;
public interface dbconfig {
string databasename = "db_database01";// 数据库名称
string username = "root";// 数据库用户名
string password = "lixiyu";// 数据库密码
}

 

为简化jdbc开发,dbhelper使用了了commons dbutil组合。
dbhelper类继承了dbconfig接口,该类中包含4种方法:
(1)getconnection()方法:获得数据库连接,使用mysql数据源来简化编程,避免因加载数据库驱动而发生异常。
(2)exists()方法:判断输入的用户名是否存在。
(3)check()方法:当用户输入用户名和密码,查询使用check()方法是否正确。
(4)save()方法:用户输入合法注册信息后,,将信息进行保存。

详细代码:


package com.lixiyu.util;
import java.sql.connection;
import java.sql.sqlexception;
import java.util.arrays;
import java.util.list;
import org.apache.commons.dbutils.dbutils;
import org.apache.commons.dbutils.queryrunner;
import org.apache.commons.dbutils.resultsethandler;
import org.apache.commons.dbutils.handlers.columnlisthandler;
import org.apache.commons.dbutils.handlers.scalarhandler;
import org.apache.commons.lang.stringescapeutils;
import com.lixiyu.model.user;
import com.mysql.jdbc.jdbc2.optional.mysqldatasource;
public class dbhelper implements dbconfig {
 /*
 * 使用mysql数据源获得数据库连接对象
 *
 * @return:mysql连接对象,如果获得失败返回null
 */
 public static connection getconnection() {
 mysqldatasource mds = new mysqldatasource();// 创建mysql数据源
 mds.setdatabasename(databasename);// 设置数据库名称
 mds.setuser(username);// 设置数据库用户名
 mds.setpassword(password);// 设置数据库密码
 try {
 return mds.getconnection();// 获得连接
 } catch (sqlexception e) {
 e.printstacktrace();
 }
 return null;// 如果获取失败就返回null
 }
 /*
 * 判断指定用户名的用户是否存在
 *
 * @return:如果存在返回true,不存在或者查询失败返回false
 */
 public static boolean exists(string username) {
 queryrunner runner = new queryrunner();// 创建queryrunner对象
 string sql = "select id from tb_user where username = '" + username + "';";// 定义查询语句
 connection conn = getconnection();// 获得连接
 resultsethandler<list<object>> rsh = new columnlisthandler();// 创建结果集处理类
 try {
 list<object> result = runner.query(conn, sql, rsh);// 获得查询结果
 if (result.size() > 0) {// 如果列表中存在数据
 return true;// 返回true
 } else {// 如果列表中没有数据
 return false;// 返回false
 }
 } catch (sqlexception e) {
 e.printstacktrace();
 } finally {
 dbutils.closequietly(conn);// 关闭连接
 }
 return false;// 如果发生异常返回false
 }
 /*
 * 验证用户名和密码是否正确 使用commons lang组件转义字符串避免sql注入
 *
 * @return:如果正确返回true,错误返回false
 */
 public static boolean check(string username, char[] password) {
 username = stringescapeutils.escapesql(username);// 将用户输入的用户名转义
 queryrunner runner = new queryrunner();// 创建queryrunner对象
 string sql = "select password from tb_user where username = '" + username + "';";// 定义查询语句
 connection conn = getconnection();// 获得连接
 resultsethandler<object> rsh = new scalarhandler();// 创建结果集处理类
 try {
 string result = (string) runner.query(conn, sql, rsh);// 获得查询结果
 char[] querypassword = result.tochararray();// 将查询到得密码转换成字符数组
 if (arrays.equals(password, querypassword)) {// 如果密码相同则返回true
 arrays.fill(password, '0');// 清空传入的密码
 arrays.fill(querypassword, '0');// 清空查询的密码
 return true;
 } else {// 如果密码不同则返回false
 arrays.fill(password, '0');// 清空传入的密码
 arrays.fill(querypassword, '0');// 清空查询的密码
 return false;
 }
 } catch (sqlexception e) {
 e.printstacktrace();
 } finally {
 dbutils.closequietly(conn);// 关闭连接
 }
 return false;// 如果发生异常返回false
 }
 /*
 * 保存用户输入的注册信息
 *
 * @return:如果保存成功返回true,保存失败返回false
 */
 public static boolean save(user user) {
 queryrunner runner = new queryrunner();// 创建queryrunner对象
 string sql = "insert into tb_user (username, password, email) values (?, ?, ?);";// 定义查询语句
 connection conn = getconnection();// 获得连接
 object[] params = { user.getusername(), user.getpassword(), user.getemail() };// 获得传递的参数
 try {
 int result = runner.update(conn, sql, params);// 保存用户
 if (result > 0) {// 如果保存成功返回true
 return true;
 } else {// 如果保存失败返回false
 return false;
 }
 } catch (sqlexception e) {
 e.printstacktrace();
 } finally {
 dbutils.closequietly(conn);// 关闭连接
 }
 return false;// 如果发生异常返回false
 }
}

系统登录
1.1窗体设计

JAVA实现简单系统登陆注册模块

使用boxlayout布局,将控件排列方式设置从上至下:

复制代码 代码如下:
contentpane.setlayout(new boxlayout(contentpane,boxlayout.page_axis));

窗体使用了标签、文本域、密码域和按钮等控件
实现代码:

public class login extends jframe{
private static final long serialversionuid = -4655235896173916415l;
private jpanel contentpane;
private jtextfield usernametextfield;
private jpasswordfield passwordfield;
private jtextfield validatetextfield;
private string randomtext;
public static void main(string args[]){
try {
uimanager.setlookandfeel("com.sun.java.swing.plaf.nimbus.nimbuslookandfeel");
} catch (throwable e) {
e.printstacktrace();
}
eventqueue.invokelater(new runnable(){
public void run(){
try{
login frame=new login();
frame.setvisible(true);
}catch(exception e){
e.printstacktrace();
}
}
});

}
public login(){
settitle("系统登录");
setdefaultcloseoperation(jframe.exit_on_close);
contentpane=new jpanel();
setcontentpane(contentpane);
contentpane.setlayout(new boxlayout(contentpane,boxlayout.page_axis));

jpanel usernamepanel=new jpanel();
contentpane.add(usernamepanel);

jlabel usernamelable=new jlabel("\u7528\u6237\u540d\uff1a");
usernamelable.setfont(new font("微软雅黑", font.plain, 15));
usernamepanel.add(usernamelable);

usernametextfield=new jtextfield();
usernametextfield.setfont(new font("微软雅黑", font.plain, 15));
usernamepanel.add(usernametextfield);
usernametextfield.setcolumns(10);

jpanel passwordpanel = new jpanel();
contentpane.add(passwordpanel);
jlabel passwordlabel = new jlabel("\u5bc6 \u7801\uff1a");
passwordlabel.setfont(new font("微软雅黑", font.plain, 15));
passwordpanel.add(passwordlabel);
passwordfield = new jpasswordfield();
passwordfield.setcolumns(10);
passwordfield.setfont(new font("微软雅黑", font.plain, 15));
passwordpanel.add(passwordfield);
jpanel validatepanel = new jpanel();
contentpane.add(validatepanel);
jlabel validatelabel = new jlabel("\u9a8c\u8bc1\u7801\uff1a");
validatelabel.setfont(new font("微软雅黑", font.plain, 15));
validatepanel.add(validatelabel);
validatetextfield = new jtextfield();
validatetextfield.setfont(new font("微软雅黑", font.plain, 15));
validatepanel.add(validatetextfield);
validatetextfield.setcolumns(5);
randomtext = randomstringutils.randomalphanumeric(4);
captchalabel label = new captchalabel(randomtext);//随机验证码
label.setfont(new font("微软雅黑", font.plain, 15));
validatepanel.add(label);

jpanel buttonpanel=new jpanel();
contentpane.add(buttonpanel);

jbutton submitbutton=new jbutton("登录");
submitbutton.addactionlistener(new actionlistener() {
@override
public void actionperformed(actionevent e) {
do_submitbutton_actionperformed(e);
}
});
submitbutton.setfont(new font("微软雅黑", font.plain, 15));
buttonpanel.add(submitbutton);

jbutton cancelbutton=new jbutton("退出");
cancelbutton.addactionlistener(new actionlistener(){
public void actionperformed(actionevent e){
do_cancelbutton_actionperformed(e);
}
});
cancelbutton.setfont(new font("微软雅黑",font.plain,15));
buttonpanel.add(cancelbutton);

pack();// 自动调整窗体大小
setlocation(com.lixiyu.util.swingutil.centrecontainer(getsize()));// 让窗体居中显示

}

窗体居中显示:

public class swingutil {
/*
* 根据容器的大小,计算居中显示时左上角坐标
*
* @return 容器左上角坐标
*/
public static point centrecontainer(dimension size) {
dimension screensize = toolkit.getdefaulttoolkit().getscreensize();// 获得屏幕大小
int x = (screensize.width - size.width) / 2;// 计算左上角的x坐标
int y = (screensize.height - size.height) / 2;// 计算左上角的y坐标
return new point(x, y);// 返回左上角坐标
}
}

1.2获取及绘制验证码

public class captchalabel extends jlabel {
private static final long serialversionuid = -963570191302793615l;
private string text;// 用于保存生成验证图片的字符串
public captchalabel(string text) {
this.text = text;
setpreferredsize(new dimension(60, 36));// 设置标签的大小
}
@override
public void paint(graphics g) {
super.paint(g);// 调用父类的构造方法
g.setfont(new font("微软雅黑", font.plain, 16));// 设置字体
g.drawstring(text, 5, 25);// 绘制字符串
}
}

*彩色验证码:

public class colorfulcaptchalabel extends jlabel {
private static final long serialversionuid = -963570191302793615l;
private string text;// 用于保存生成验证图片的字符串
private color[] colors = { color.black, color.blue, color.cyan, color.dark_gray, color.gray, color.green, color.light_gray, color.magenta, color.orange,
color.pink, color.red, color.white, color.yellow };// 定义画笔颜色数组
public colorfulcaptchalabel(string text) {
this.text = text;
setpreferredsize(new dimension(60, 36));// 设置标签的大小
}
@override
public void paint(graphics g) {
super.paint(g);// 调用父类的构造方法
g.setfont(new font("微软雅黑", font.plain, 16));// 设置字体
for (int i = 0; i < text.length(); i++) {
g.setcolor(colors[randomutils.nextint(colors.length)]);
g.drawstring("" + text.charat(i), 5 + i * 13, 25);// 绘制字符串
}
}
}

1.3非空校验

if (username.isempty()) {// 判断用户名是否为空
joptionpane.showmessagedialog(this, "用户名不能为空!", "警告信息", joptionpane.warning_message);
return;
}
if (new string(password).isempty()) {// 判断密码是否为空
joptionpane.showmessagedialog(this, "密码不能为空!", "警告信息", joptionpane.warning_message);
return;
}
if (validate.isempty()) {// 判断验证码是否为空
joptionpane.showmessagedialog(this, "验证码不能为空!", "警告信息", joptionpane.warning_message);
return;
}

1.4合法性校验

if (!dbhelper.exists(username)) {// 如果用户名不存在则进行提示
joptionpane.showmessagedialog(this, "用户名不存在!", "警告信息", joptionpane.warning_message);
return;
}
if (!dbhelper.check(username, password)) {// 如果密码错误则进行提示
joptionpane.showmessagedialog(this, "密码错误!", "警告信息", joptionpane.warning_message);
return;
}
if (!validate.equals(randomtext)) {// 如果校验码不匹配则进行提示
joptionpane.showmessagedialog(this, "验证码错误!", "警告信息", joptionpane.warning_message);
return;
}

1.5显示主窗体

eventqueue.invokelater(new runnable() {
@override
public void run() {
try {
mainframe frame = new mainframe();// 创建主窗体
frame.setvisible(true);// 设置主窗体可见
} catch (exception e) {
e.printstacktrace();
}
}
});
dispose();// 将登录窗体销毁
}

设计主窗体(比较简单这个):

public mainframe() {
setdefaultcloseoperation(jframe.exit_on_close);// 设置单击关闭窗体按钮时执行的操作
setsize(450, 300);// 设置窗体大小
contentpane = new jpanel();// 创建面板
contentpane.setlayout(new borderlayout(0, 0));// 设置面板布局使用边界布局
setcontentpane(contentpane);// 应用面板
jlabel tiplabel = new jlabel("恭喜您成功登录系统!");// 创建标签
tiplabel.setfont(new font("微软雅黑", font.plain, 40));// 设置标签字体
contentpane.add(tiplabel, borderlayout.center);// 应用标签
setlocation(swingutil.centrecontainer(getsize()));// 让窗体居中显示
}

用户注册

1.1窗体设计

JAVA实现简单系统登陆注册模块

public class register extends jframe {
/**
*
*/
private static final long serialversionuid = 2491294229716316338l;
private jpanel contentpane;
private jtextfield usernametextfield;
private jpasswordfield passwordfield1;
private jpasswordfield passwordfield2;
private jtextfield emailtextfield;
private jlabel tiplabel = new jlabel();// 显示提示信息
/**
* launch the application.
*/
public static void main(string[] args) {
try {
uimanager.setlookandfeel("com.sun.java.swing.plaf.nimbus.nimbuslookandfeel");
} catch (throwable e) {
e.printstacktrace();
}
eventqueue.invokelater(new runnable() {
@override
public void run() {
try {
register frame = new register();
frame.setvisible(true);
} catch (exception e) {
e.printstacktrace();
}
}
});
}
/**
* create the frame.
*/
public register() {
settitle("\u7528\u6237\u6ce8\u518c");
setdefaultcloseoperation(jframe.exit_on_close);
contentpane = new jpanel();
setcontentpane(contentpane);
contentpane.setlayout(new boxlayout(contentpane, boxlayout.page_axis));
jpanel usernamepanel = new jpanel();
contentpane.add(usernamepanel);
jlabel usernamelabel = new jlabel("\u7528 \u6237 \u540d\uff1a");
usernamelabel.setfont(new font("微软雅黑", font.plain, 15));
usernamepanel.add(usernamelabel);
usernametextfield = new jtextfield();
usernametextfield.settooltiptext("\u8bf7\u8f93\u51655~15\u4e2a\u7531\u5b57\u6bcd\u6570\u5b57\u4e0b\u5212\u7ebf\u7ec4\u6210\u7684\u5b57\u7b26\u4e32");
abstractdocument doc = (abstractdocument) usernametextfield.getdocument();
doc.setdocumentfilter(new documentsizefilter(15));// 限制文本域内可以输入字符长度为15
doc.adddocumentlistener(new documentsizelistener(tiplabel, 15));
usernametextfield.setfont(new font("微软雅黑", font.plain, 15));
usernamepanel.add(usernametextfield);
usernametextfield.setcolumns(10);
jpanel passwordpanel1 = new jpanel();
contentpane.add(passwordpanel1);
jlabel passwordlabel1 = new jlabel("\u8f93\u5165\u5bc6\u7801\uff1a");
passwordlabel1.setfont(new font("微软雅黑", font.plain, 15));
passwordpanel1.add(passwordlabel1);
passwordfield1 = new jpasswordfield();
doc = (abstractdocument) passwordfield1.getdocument();
doc.setdocumentfilter(new documentsizefilter(20));// 限制密码域内可以输入字符长度为20
doc.adddocumentlistener(new documentsizelistener(tiplabel, 20));
passwordfield1.setfont(new font("微软雅黑", font.plain, 15));
passwordfield1.setcolumns(10);
passwordpanel1.add(passwordfield1);
jpanel passwordpanel2 = new jpanel();
contentpane.add(passwordpanel2);
jlabel passwordlabel2 = new jlabel("\u786e\u8ba4\u5bc6\u7801\uff1a");
passwordlabel2.setfont(new font("微软雅黑", font.plain, 15));
passwordpanel2.add(passwordlabel2);
passwordfield2 = new jpasswordfield();
doc = (abstractdocument) passwordfield2.getdocument();
doc.setdocumentfilter(new documentsizefilter(20));// 限制密码域内可以输入字符长度为20
doc.adddocumentlistener(new documentsizelistener(tiplabel, 20));
passwordfield2.setfont(new font("微软雅黑", font.plain, 15));
passwordfield2.setcolumns(10);
passwordpanel2.add(passwordfield2);
jpanel emailpanel = new jpanel();
contentpane.add(emailpanel);
jlabel emaillabel = new jlabel("\u7535\u5b50\u90ae\u7bb1\uff1a");
emaillabel.setfont(new font("微软雅黑", font.plain, 15));
emailpanel.add(emaillabel);
emailtextfield = new jtextfield();
doc = (abstractdocument) emailtextfield.getdocument();
doc.setdocumentfilter(new documentsizefilter(45));// 限制文本域内可以输入字符长度为45
doc.adddocumentlistener(new documentsizelistener(tiplabel, 45));
emailtextfield.setfont(new font("微软雅黑", font.plain, 15));
emailpanel.add(emailtextfield);
emailtextfield.setcolumns(10);
jpanel buttonpanel = new jpanel();
contentpane.add(buttonpanel);
jbutton submitbutton = new jbutton("\u63d0\u4ea4");
submitbutton.addactionlistener(new actionlistener() {
@override
public void actionperformed(actionevent e) {
do_submitbutton_actionperformed(e);
}
});
buttonpanel.setlayout(new boxlayout(buttonpanel, boxlayout.line_axis));
tiplabel.setfont(new font("微软雅黑", font.plain, 15));
buttonpanel.add(tiplabel);
component glue = box.createglue();
buttonpanel.add(glue);
submitbutton.setfont(new font("微软雅黑", font.plain, 15));
buttonpanel.add(submitbutton);
jbutton cancelbutton = new jbutton("\u53d6\u6d88");
cancelbutton.addactionlistener(new actionlistener() {
@override
public void actionperformed(actionevent e) {
do_cancelbutton_actionperformed(e);
}
});
cancelbutton.setfont(new font("微软雅黑", font.plain, 15));
buttonpanel.add(cancelbutton);
pack();// 自动调整窗体大小
setlocation(swingutil.centrecontainer(getsize()));// 让窗体居中显示
}

1.2用documentfilter限制文本可用字符数

public class documentsizefilter extends documentfilter {
private int maxsize;// 获得文本的最大长度
public documentsizefilter(int maxsize) {
this.maxsize = maxsize;// 获得用户输入的最大长度
}
@override
public void insertstring(filterbypass fb, int offset, string string, attributeset attr) throws badlocationexception {
if ((fb.getdocument().getlength() + string.length()) <= maxsize) {// 如果插入操作完成后小于最大长度
super.insertstring(fb, offset, string, attr);// 调用父类中的方法
} else {
toolkit.getdefaulttoolkit().beep();// 发出提示声音
}
}
@override
public void replace(filterbypass fb, int offset, int length, string text, attributeset attrs) throws badlocationexception {
if ((fb.getdocument().getlength() + text.length() - length) <= maxsize) {// 如果替换操作完成后小于最大长度
super.replace(fb, offset, length, text, attrs);// 调用父类中的方法
} else {
toolkit.getdefaulttoolkit().beep();// 发出提示声音
}
}
}

1.3用documentlistener接口实现显示文本控件已用字符

public class documentsizelistener implements documentlistener {
private jlabel tiplabel;
private int maxsize;
public documentsizelistener(jlabel tiplabel, int maxsize) {
this.tiplabel = tiplabel;
this.maxsize = maxsize;
}
@override
public void insertupdate(documentevent e) {
settiptext(e);
}
@override
public void removeupdate(documentevent e) {
settiptext(e);
}
@override
public void changedupdate(documentevent e) {
settiptext(e);
}
private void settiptext(documentevent e) {
document doc = e.getdocument();// 获得文档对象
tiplabel.setforeground(color.black);// 设置字体颜色
if (doc.getlength() > (maxsize * 4 / 5)) {// 如果已输入字符长度大于最大长度的80%
tiplabel.setforeground(color.red);// 使用红色显示提示信息
} else {
tiplabel.setforeground(color.black);// 使用黑色显示提示信息
}
tiplabel.settext("提示信息:" + doc.getlength() + "/" + maxsize);
}
}

1.4非空校验

if (username.isempty()) {// 判断用户名是否为空
joptionpane.showmessagedialog(this, "用户名不能为空!", "警告信息", joptionpane.warning_message);
return;
}
if (new string(password1).isempty()) {// 判断密码是否为空
joptionpane.showmessagedialog(this, "密码不能为空!", "警告信息", joptionpane.warning_message);
return;
}
if (new string(password2).isempty()) {// 判断确认密码是否为空
joptionpane.showmessagedialog(this, "确认密码不能为空!", "警告信息", joptionpane.warning_message);
return;
}
if (email.isempty()) {// 判断电子邮箱是否为空
joptionpane.showmessagedialog(this, "电子邮箱不能为空!", "警告信息", joptionpane.warning_message);
return;
}

1.5使用正则表达式校验字符串(合法性校验)

// 校验用户名是否合法
if (!pattern.matches("\\w{5,15}", username)) {
joptionpane.showmessagedialog(this, "请输入合法的用户名!", "警告信息", joptionpane.warning_message);
return;
}
// 校验两次输入的密码是否相同
if (!arrays.equals(password1, password2)) {
joptionpane.showmessagedialog(this, "两次输入的密码不同!", "警告信息", joptionpane.warning_message);
return;
}
// 校验电子邮箱是否合法
if (!pattern.matches("\\w+@\\w+\\.\\w+", email)) {
joptionpane.showmessagedialog(this, "请输入合法的电子邮箱!", "警告信息", joptionpane.warning_message);
return;
}
// 校验用户名是否存在
if (dbhelper.exists(username)) {
joptionpane.showmessagedialog(this, "用户名已经存在", "警告信息", joptionpane.warning_message);
return;
}

1.6保存注册信息

user user = new user();
user.setusername(username);
user.setpassword(new string(password1));
user.setemail(email);
arrays.fill(password1, '0');// 清空保存密码的字符数组
arrays.fill(password2, '0');// 清空保存密码的字符数组
if (dbhelper.save(user)) {
joptionpane.showmessagedialog(this, "用户注册成功!", "提示信息", joptionpane.information_message);
return;
} else {
joptionpane.showmessagedialog(this, "用户注册失败!", "警告信息", joptionpane.warning_message);
return;
}
}

至此,一个简单而有完整的登陆注册模块就完成了。

以上就是本文的全部内容,希望大家可以喜欢。