当前位置: 首页 > news >正文

Java实战:实现用户的登录注册功能

系列文章目录

Java文件 I/O流的操作实战和高级UI组件和事件监听的综合


文章目录

  • 系列文章目录
  • 前言
  • 一、大致流程思路分析:
  • 二、定义用户类:
  • 三、服务层的实现:
    • 1.保护用户数据功能的实现
    • 2.登录操作的实现
  • 四、实现用户的注册界面:
    • 大体流程:
  • 五、实现用户的登录界面(在这里面相当于总界面)
    • 大体流程:
  • 六、在实现时的易错点:
    • 以我自己举例:
  • 总结


前言

    在学习完文件和IO流的操作后,包括事件监听机制和UI组件以后,我们可能会想这些知识可以用来干什么,今天我们就用一个实战案例来帮大家将学过的知识运用起来。(但是这个实战案例本来是可以用数据库与Java进行连接,但是这篇我们也可以用将用户数据存储到文件当中来实现,因为像MySQL等数据库,本质都是存储在文件当中的)。


一、大致流程思路分析:

        我将用最通俗易懂的话向大家解释一下这个的具体流程:

     首先我们想要实现用户的注册和登录功能,就要先定义出来用户类,把用户的数据当作成员属性定义出来,然后我们需要建一个窗口来实现登录,注册,重置的操作,注册和登录需要我们输入文本,这些都是基础的,最关键的操作是什么呢?

     就是要定义一个能实现注册和登录的类作为服务层,注册的时候就是把在窗口得到的数据写到文件当中存储起来,那文件当中肯定会有一个又一个的用户的数据,因此我们实现登录的功能就需要把这些个用户全都读取出来,和登录窗口得到的文本核对,看是否能登录成功,大体流程就是这些,反正就是服务层和窗口层的连接,包括数据库的连接也是如此,这个我们后来再讲。

二、定义用户类:

    首先我们需要把用户当成一个用户类,它的属性就是我们理解的用户的数据。

           这里面的用户数据包括了:用户名,密码,性别,爱好,地址,学历。

         以下是代码:

public class User {//用户实体private int id;   //用户private String userName;  //用户名private String passWord;   //密码private int sex;  //性别private String hobby;   //爱好private String address;   //地址private String degree;  //学历public User(String userName, String passWord, int sex, String hobby, String address, String degree) {this.userName = userName;this.passWord = passWord;this.sex = sex;this.hobby = hobby;this.address = address;this.degree = degree;}public User(int id, String userName, String passWord, int sex, String hobby, String address, String degree) {this.id = id;this.userName = userName;this.passWord = passWord;this.sex = sex;this.hobby = hobby;this.address = address;this.degree = degree;}public void setId(int id) {this.id = id;}public void setUserName(String userName) {this.userName = userName;}public void setPassWord(String passWord) {this.passWord = passWord;}public void setSex(int sex) {this.sex = sex;}public void setAddress(String address) {this.address = address;}public void setHobby(String hobby) {this.hobby = hobby;}public void setDegree(String degree) {this.degree = degree;}public int getId() {return id;}public String getUserName() {return userName;}public String getPassWord() {return passWord;}public String getHobby() {return hobby;}public int getSex() {return sex;}public String getAddress() {return address;}public String getDegree() {return degree;}}

三、服务层的实现:

public static String filePath = "E:\\User.txt";private static final String DELIMITER = "|";

   先创建出来文件路径,以方便下面的操作。

1.保存用户数据功能的实现:

       这个方法是用来将用户的数据读取到文件当中的、

以下是代码实现:

public boolean saveUser(User user) throws IOException {File file = new File(filePath);if (!file.exists()) {if (!file.createNewFile()) {System.out.println("存储用户文件创建失败");return false;}}//下面开始对文件进行输入保存BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(filePath, true));//这是我们在注册窗口时通过输入的文本框的内容放在一个User对象// 得到我们在注册时的用户信息String userData = String.join(DELIMITER, String.valueOf(user.getId()), user.getUserName(),user.getPassWord(), String.valueOf(user.getSex()), user.getHobby(),user.getAddress(), user.getDegree());bufferedWriter.write(userData);bufferedWriter.newLine();bufferedWriter.close();return true;}

         2.登录操作的实现(即从文件中读取数据)

 这里面最关键的一点是:

我们要想对登录的用户进行验证,首先肯定要得到存储在文件中的所有用户资源
因此我们肯定需要写一个ReadAllUsers的方法,然后再对每一个对象进行一一遍历

  以下是代码实现:

//这个方法用来完成登录的操作// 首先我们肯定要得到用户名和密码,这个应该是在界面层通过输入的文本来得到// 相应的用户名和密码进行验证public boolean vaildateLogin(String inputUserName,String inputPassWord) throws IOException {//我们要想对登录的用户进行验证,首先肯定要得到存储在文件中的所有用户资源//因此我们肯定需要写一个ReadAllUsers的方法,然后再对每一个对象进行一一遍历List<User> users = readAllUsers();//下面开始对文件当中的每一个用户数据进行验证判断是否能登陆成功for(User user:users){if(user.getUserName().equals(inputUserName)&&user.getPassWord().equals(inputPassWord)){return true;}}return false;}public List<User> readAllUsers() throws IOException {//先创建一个列表来存放每一个用户数据对象List<User> list = new ArrayList<>();File file = new File(filePath);if (file.exists()) {//开始进行读操作BufferedReader bufferedReader = new BufferedReader(new FileReader(file));String line;while ((line = bufferedReader.readLine()) != null) {String[] parts = line.split("\\" + DELIMITER);//下面开始创建User对象并传入到列表当中if (parts.length == 7) {list.add(new User(Integer.parseInt(parts[0]), // IDparts[1],                   // 用户名parts[2],                   // 密码Integer.parseInt(parts[3]), // 性别parts[4],                   // 爱好parts[5],                   // 地址parts[6]                    // 学历));}}}return list;}

  四、实现用户的注册界面:

   大体流程:       

        对于注册界面我们肯定要设置标签和文本框,还需要设置布局方式,并且对确认和重置按钮作监听。

下面是代码的实现:

   

public class RegistFrame extends JFrame {//这是实现用户注册界面//主面板private JPanel p;//标签private JLabel lblName, lblPwd, lblRePwd, lblSex, lblHobby,lblAdress, lblDegree;//用户名文本框private JTextField txtName;//密码共和确认密码文本框private JPasswordField txtPwd, txtRepwd;//性别,单选按钮private JRadioButton rbMale, rbFemale;//爱好,多选框private JCheckBox ckbRead, ckbNet, ckbSwim, ckbTour;//地址,文本框private JTextArea txtAdress;//学历,组合框private JComboBox<String> cmbDegree;//确认和取消,按钮private JButton btnOk, btnCancle;//注册的用户private static User user;//用户业务类private UserService userService;//构造方法public RegistFrame() {super("用户注册");//实例化用户业务类对象userService = new UserService();//设置窗体的icon
//.......//设置面板布局,网格布局p = new JPanel(new GridLayout(8, 1, 0, 10));//实例化组件lblName = new JLabel("用  户   名:");lblPwd = new JLabel("密  码:");lblRePwd = new JLabel("确认密码:");lblSex = new JLabel("性  别:");lblHobby = new JLabel("爱  好:");lblAdress = new JLabel("地   址:");lblDegree = new JLabel("学  历");txtName = new JTextField(25);txtPwd = new JPasswordField(25);txtRepwd = new JPasswordField(25);rbMale = new JRadioButton("男");rbFemale = new JRadioButton("女");//性别的单选逻辑ButtonGroup bg = new ButtonGroup();bg.add(rbMale);bg.add(rbFemale);ckbRead = new JCheckBox("阅读");ckbNet = new JCheckBox("上网");ckbSwim = new JCheckBox("游泳");ckbTour = new JCheckBox("旅游");txtAdress = new JTextArea(3, 20);//组合框显示学历数组// 正确初始化组合框cmbDegree = new JComboBox<>(new String[]{"小学", "初中", "高中", "本科", "硕士", "博士"});//设置组合框可编辑cmbDegree.setSelectedIndex(0);// 默认选中第一项cmbDegree.setPreferredSize(new Dimension(200, 30));cmbDegree.setEditable(true);btnOk = new JButton("确定");btnCancle = new JButton("重置");btnOk.setPreferredSize(new Dimension(120, 35));   // 宽度120,高度35btnCancle.setPreferredSize(new Dimension(120, 35));Font bigFont = new Font("宋体", Font.PLAIN, 16);// 统一设置组件字体txtName.setFont(bigFont);txtPwd.setFont(bigFont);txtRepwd.setFont(bigFont);rbMale.setFont(bigFont);rbFemale.setFont(bigFont);ckbRead.setFont(bigFont);ckbNet.setFont(bigFont);ckbSwim.setFont(bigFont);ckbTour.setFont(bigFont);txtAdress.setFont(bigFont);cmbDegree.setFont(bigFont);btnOk.setFont(bigFont);btnCancle.setFont(bigFont);//这一步需要注册监听器,监听确定按钮btnOk.addActionListener(new RegisterListener());//还需要注册监听器,监听重置按钮btnCancle.addActionListener(new ResetListener());/*将组件分组放入面板,然后将小面板放入主面板*/JPanel p1 = new JPanel(new FlowLayout(FlowLayout.LEFT));p1.setBorder(BorderFactory.createEmptyBorder(5,10,5,10));p1.add(lblName);p1.add(txtName);p.add(p1);JPanel p2 = new JPanel(new FlowLayout(FlowLayout.LEFT));p2.setBorder(BorderFactory.createEmptyBorder(5,10,5,10));p2.add(lblPwd);p2.add(txtPwd);p.add(p2);JPanel p3 = new JPanel(new FlowLayout(FlowLayout.LEFT));p3.setBorder(BorderFactory.createEmptyBorder(5,10,5,10));p3.add(lblRePwd);p3.add(txtRepwd);p.add(p3);JPanel p4 = new JPanel(new FlowLayout(FlowLayout.LEFT));p4.setBorder(BorderFactory.createEmptyBorder(5,10,5,10));p4.add(lblSex);p4.add(rbMale);p4.add(rbFemale);p.add(p4);JPanel p5 = new JPanel(new FlowLayout(FlowLayout.LEFT));p5.setBorder(BorderFactory.createEmptyBorder(5,10,5,10));p5.add(lblHobby);p5.add(ckbRead);p5.add(ckbNet);p5.add(ckbSwim);p5.add(ckbTour);p.add(p5);JPanel p6 = new JPanel(new FlowLayout(FlowLayout.LEFT));p6.setBorder(BorderFactory.createEmptyBorder(5,10,5,10));p6.add(lblAdress);p6.add(txtAdress);p.add(p6);JPanel p7 = new JPanel(new FlowLayout(FlowLayout.LEFT));p7.setBorder(BorderFactory.createEmptyBorder(5,10,5,10));p7.add(lblDegree);p7.add(cmbDegree);p.add(p7);JPanel p8 = new JPanel(new FlowLayout(FlowLayout.CENTER));p8.setBorder(BorderFactory.createEmptyBorder(5,10,5,10));p8.add(btnOk);p8.add(btnCancle);p.add(p8);//主面板放入窗体中this.add(p);//设置窗体的大小和位置居中this.setSize(450, 500);this.setLocationRelativeTo(null);//设置窗体不可改变大小this.setResizable(false);//设置窗体初始可见this.setVisible(true);}//监听类,负责处理确认按钮的业务逻辑private class RegisterListener implements ActionListener {@Overridepublic void actionPerformed(ActionEvent e) {//获取用户输入的数据String userName = txtName.getText().trim();String passWord = new String(txtPwd.getPassword());String rePassWord = new String(txtRepwd.getPassword());//将性别"男""女"对应转化为"1""0"int sex = Integer.parseInt(rbFemale.isSelected() ? "0" : "1");String hobby = (ckbRead.isSelected() ? "阅读" : "")+ (ckbNet.isSelected() ? "上网" : "")+ (ckbSwim.isSelected() ? "游泳" : "")+ (ckbTour.isSelected() ? "旅游" : "");String address = txtAdress.getText();Object selectedDegree = cmbDegree.getSelectedItem();String degree = (selectedDegree != null) ? selectedDegree.toString().trim() : "";//判断两次输入密码是否一致if (passWord.equals(rePassWord)) {//将数据封装到对象当中user = new User(userName, passWord, sex, hobby, address, degree);//保存数据try {if (userService.saveUser(user)) {System.out.println("注册成功!");}} catch (IOException ex) {throw new RuntimeException(ex);}} else {System.out.println("两次密码输入的不一致!");}}}public class ResetListener implements ActionListener {@Overridepublic void actionPerformed(ActionEvent e) {//清空姓名,密码,确认密码等内容txtName.setText("");txtPwd.setText("");txtRepwd.setText("");//重置单选按钮为未选择rbMale.setSelected(false);rbFemale.setSelected(false);//重置所有复选按钮为未选择ckbRead.setSelected(false);ckbNet.setSelected(false);ckbSwim.setSelected(false);ckbTour.setSelected(false);//清空地址栏txtAdress.setText("");//重置组合框为未选择状态cmbDegree.setSelectedIndex(0);}}}

 五、实现用户的登录界面(在这里面相当于总界面)

          大体流程:

这里的用户登录肯定也需要多个组件,用户名和密码的标签和文本框,然后登录,注册,重置按钮,并对其实现监听机制,这里面需要和服务层的登录方法匹配

    以下是代码实现:

  

/*** @author 袁敬尧* @version 1.0*/
public class LoginFrame extends JFrame {//这是用户登录 注册界面,我们需要多个组件//主面板private JPanel p;//标签private JLabel lblName, lblPwd;//用户名,文本框private JTextField txtName;//密码,密码框private JPasswordField txtPwd;//确认,取消和注册,按钮private JButton btnOk, btnCancle, btnRegist;//登录用户private static User user;//用户业务类private UserService userService;//构造方法public LoginFrame() {super("登录");//实例化用户业务类对象userService = new UserService();//实例化组件p = new JPanel();Font inputFont = new Font("微软雅黑", Font.PLAIN, 16);//使用null布局p.setLayout(null);lblName = new JLabel("用户名:");lblPwd = new JLabel("密码:");txtName = new JTextField(20);txtPwd = new JPasswordField(20);txtPwd.setEchoChar('*');btnOk = new JButton("登录");btnOk.addActionListener(new LoginListener());btnCancle = new JButton("重置");btnCancle.addActionListener(new ResetListener());btnRegist = new JButton("注册");btnRegist.addActionListener(new RegistListener());lblName.setBounds(30, 30, 80, 30);          // 增大标签宽度lblPwd.setBounds(30, 80, 80, 30);          // 下移密码标签位置txtName.setBounds(120, 30, 200, 30);       // 宽度200 → 300txtPwd.setBounds(120, 80, 200, 30);         // 同用户名框对齐btnOk.setBounds(50, 130, 80, 35);          // 增大按钮尺寸btnCancle.setBounds(150, 130, 80, 35);btnRegist.setBounds(250, 130, 80, 35);p.add(lblName);p.add(txtName);p.add(lblPwd);p.add(txtPwd);p.add(btnOk);p.add(btnCancle);p.add(btnRegist);txtName.setFont(inputFont);txtPwd.setFont(inputFont);//主面板放入窗体中this.add(p);//设置窗体的大小和位置this.setSize(420, 300);//设置窗口在屏幕中央this.setLocationRelativeTo(null);//设置窗体的默认关闭按钮this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//设置窗体初始可见this.setVisible(true);}public class LoginListener implements ActionListener {@Overridepublic void actionPerformed(ActionEvent e) {//这里我在服务层里面已经写好了验证的数据String userName = txtName.getText().trim();String passWord = new String(txtPwd.getPassword());try {if (userService.vaildateLogin(userName,passWord)) {LoginFrame.this.setVisible(false);JOptionPane.showMessageDialog(null,"登录成功!欢迎您:" + userName,"系统提示",JOptionPane.INFORMATION_MESSAGE);}else{//输出提示信息System.out.println("密码错误,请重新输入");//清空密码框txtPwd.setText("");txtName.setText("");}} catch (IOException ex) {throw new RuntimeException(ex);}}}//监听类,负责处理重置按钮public class ResetListener implements ActionListener{@Overridepublic void actionPerformed(ActionEvent e) {txtName.setText("");txtPwd.setText("");}}//监听类,负责处理注册按钮public class RegistListener implements ActionListener{@Overridepublic void actionPerformed(ActionEvent e) {new RegistFrame();}}public static void main(String[] args){new LoginFrame();}}

    六、在实现时的易错点:

     以我自己举例:

              我在实现这个功能的时候,就报了空指针异常的错误,包括像我当时写坦克大战的时候也犯了空指针异常的错误,因为可能我们使用的类还没有分配内存就被使用了,那肯定会抛异常的,

private JComboBox<String> cmbDegree;
...
cmbDegree.setEditable(true); // 未初始化直接调用方法

我这里面未初始化就直接调用方法了

// 正确初始化组合框
private JComboBox<String> cmbDegree = new JComboBox<>(new String[]{"小学", "初中", "高中", "本科", "硕士", "博士"});

密码字段也错了

// LoginFrame.java
String userPwd = txtPwd.getPassword().toString(); // 错误!得到的是数组地址// RegistFrame.java
String passWord = new String(txtPwd.getPassword()); // 正确但未去空格

具体改正:

// LoginFrame.java
String userPwd = new String(txtPwd.getPassword()).trim(); // 转换为字符串并去空格// RegistFrame.java
String passWord = new String(txtPwd.getPassword()).trim();

还有最关键的一点就是使用文件流一定要记得关流。


总结

以上就是我要讲的内容了,这是一个实现用户登录和注册的基本功功能,其实这个还有很多可以扩充功能的,具体怎么实现我会和大家一起思考的,下面两周我会持续更新蓝桥杯算法题的,希望大家多多关注,我们一起加油,谢谢大家。


http://www.mrgr.cn/news/96358.html

相关文章:

  • CS2 DEMO导入blender(慢慢更新咯)
  • 5G_WiFi_CE_杂散测试
  • Centos7,tar包方式部署rabbitmq-3.7.6
  • 【研究方向】联邦|自然语言
  • AB包介绍及导出工具实现+AB包资源简单加载
  • 【蓝桥杯速成】| 15.完全背包
  • 求职笔试题
  • GAMES101-现代计算机图形学入门(Animation/simulation)
  • Enhanced PEC-YOLO:电力施工场景安全装备检测的轻量化算法解析
  • 海量数据处理
  • 【测试】每日3道面试题 3/29
  • 【计网】网络交换技术之电路交换(复习自用)
  • 智能预测维护:让设备“未卜先知”,减少宕机烦恼
  • 第三卷:覆舟山决战(73-108回)正反人物群像
  • Python中multiprocessing的使用详解
  • (一)初始化窗口
  • [AI绘图] ComfyUI 中自定义节点插件安装方法
  • leetcode102 二叉树的层次遍历 递归
  • Android设计模式之单例模式
  • 【学Rust写CAD】16 0、1、-1代数单位元(algebraic_units.rs)