java是目前最流行的编程语言,学会java,我们就可以利用java开发各种软件以及应用,那java注册功能如何编写?下面来我们就用实例给大家讲解一下java注册功能编写方法。
首先要先明确有个大体的思路,要实现什么样的功能,了解完成整个模块要运用到哪些方面的知识,以及从做的过程中去发现自己的不足。技术方面的进步大都都需要从实践中出来的。
功能:用户注册功能+系统登录功能+生成验证码
知识:窗体设计、数据库设计、JavaBean封装属性、JDBC实现对数据库的连接、验证码(包括彩色验证码)生成技术,还有就些比如像使用正则表达式校验用户注册信息、随机获得字符串、对文本可用字符数的控制等
设计的模块预览图:
彩色验证码预览图:
所用数据库: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语句检查一下所建立的表格:
编写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 > rsh = new ColumnListHandler(); // 创建结果集处理类 try { List 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 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窗体设计
使用BoxLayout布局,将控件排列方式设置从上至下:
复制代码代码如下:
contentPane.setLayout(new BoxLayout(contentPane,BoxLayout.PAGE_AXIS));
窗体使用了标签、文本域、密码域和按钮等控件
实现代码:
public class login extends JFrame { private static final long serialVersionUID = -4655235896173916415 L; 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("用户名:"); 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("密 码:"); 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("验证码:"); 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 = -963570191302793615 L; 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 = -963570191302793615 L; 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窗体设计
public class Register extends JFrame { /** * */ private static final long serialVersionUID = 2491294229716316338 L; 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("用户注册"); 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("用 户 名:"); usernameLabel.setFont(new Font("微软雅黑", Font.PLAIN, 15)); usernamePanel.add(usernameLabel); usernameTextField = new JTextField(); usernameTextField.setToolTipText("请输入5~15个由字母数字下划线组成的字符串"); 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("输入密码:"); 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("确认密码:"); 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("电子邮箱:"); 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("提交"); 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("取消"); 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; } }
至此,一个简单而有完整的登陆注册模块就完成了。设计java注册功能,看似比较复杂,其实你有明确的设计思路,就会很简单了!最后大家如果想要了解更多java实例知识,敬请关注奇Q工具网。
推荐阅读: