Java 如何解决登录/创建帐户程序中的此序列化错误?

Java 如何解决登录/创建帐户程序中的此序列化错误?,java,swing,serialization,user-interface,Java,Swing,Serialization,User Interface,我正在编写一个简单的GUI程序,它使用文本文件中的登录信息。它从另一个创建用户帐户的GUI程序获取登录信息。我不知道如何轻松有效地序列化它,因为这只是我最近学到的东西。我该怎么办?如何解决此序列化错误,以及如何改进它并使其正常工作 用户类别: package passwordProgram; import java.util.ArrayList; import java.util.Arrays; import java.awt.BorderLayout; import java.awt.Co

我正在编写一个简单的GUI程序,它使用文本文件中的登录信息。它从另一个创建用户帐户的GUI程序获取登录信息。我不知道如何轻松有效地序列化它,因为这只是我最近学到的东西。我该怎么办?如何解决此序列化错误,以及如何改进它并使其正常工作

用户类别:

package passwordProgram;

import java.util.ArrayList;
import java.util.Arrays;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import java.io.Serializable;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
import javax.swing.UIManager;

public class User implements Serializable, ActionListener {

    public static ArrayList<String> allUsernames = new ArrayList<String>();

    String username;
    String password;

    public static void main(String[] args) {
        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } catch (Exception e) {
            e.printStackTrace();
        }
        User user = new User();
        user.mainGUI();
    }



    JFrame frame;
    JPanel panel;
    JTextField createUsername;
    JPasswordField createPassword;
    JPasswordField confirmPassword;
    JButton createAccount;
    JLabel noValid;

    public void mainGUI() {
        noValid = new JLabel();
        frame = new JFrame("Create a new account!");
        panel = new JPanel();
        panel.setBackground(Color.ORANGE);
        createPassword = new JPasswordField(10);
        confirmPassword = new JPasswordField(10);
        createUsername = new JTextField(10);
        JLabel userTxt = new JLabel("New Username: ");
        JLabel userPass = new JLabel("New Password: ");
        JLabel confirmPass = new JLabel("Confirm Password: ");
        createAccount = new JButton("Create your account!");

        panel.setLayout(new GridBagLayout());
        GridBagConstraints left = new GridBagConstraints();
        left.anchor = GridBagConstraints.WEST;
        GridBagConstraints right = new GridBagConstraints();
        right.anchor = GridBagConstraints.EAST;
        right.weightx = 2.0;
        right.fill = GridBagConstraints.HORIZONTAL;
        right.gridwidth = GridBagConstraints.REMAINDER;

        frame.getContentPane().add(BorderLayout.NORTH, noValid);
        frame.getContentPane().add(BorderLayout.CENTER, panel);
        panel.add(userTxt, left);
        panel.add(createUsername, right);
        panel.add(userPass, left);
        panel.add(createPassword, right);
        panel.add(confirmPass, left);
        panel.add(confirmPassword, right);

        frame.getContentPane().add(BorderLayout.SOUTH, createAccount);
        frame.setVisible(true);
        frame.setSize(500, 300);

        createAccount.addActionListener(this);
    }

    public void actionPerformed(ActionEvent event) {
        if (createUsername.getText().length() <= 0 ) {
            noValid.setText("That is not a valid username. Please try again.");
            frame.getContentPane().add(BorderLayout.NORTH, noValid);
        }

        else if (allUsernames.contains(createUsername.getText())) {
            noValid.setText("That username is already taken. Please try again.");
            frame.getContentPane().add(BorderLayout.NORTH, noValid);
        }

        else if (!(Arrays.equals(createPassword.getPassword(), confirmPassword.getPassword()))) {
            noValid.setText("Your passwords do not match!");
            frame.getContentPane().add(BorderLayout.NORTH, noValid);
        } else {    
            SaveUser sUser = new SaveUser();
            sUser.createAccount(this);
            noValid.setText("Account created successfully");
            frame.getContentPane().add(BorderLayout.NORTH, noValid);
        }
    }
}
这是我在尝试运行User类时遇到的错误

java.io.NotSerializableException: passwordProgram.User
    at java.io.ObjectOutputStream.writeObject0(Unknown Source)
    at java.io.ObjectOutputStream.writeObject(Unknown Source)
    at passwordProgram.SaveUser.createAccount(SaveUser.java:12)
    at passwordProgram.User.actionPerformed(User.java:104)
    at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
    at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
    at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
    at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
    at javax.swing.AbstractButton.doClick(Unknown Source)
    at javax.swing.plaf.basic.BasicRootPaneUI$Actions.actionPerformed(Unknown Source)
    at javax.swing.SwingUtilities.notifyAction(Unknown Source)
    at javax.swing.JComponent.processKeyBinding(Unknown Source)
    at javax.swing.KeyboardManager.fireBinding(Unknown Source)
    at javax.swing.KeyboardManager.fireKeyboardAction(Unknown Source)
    at javax.swing.JComponent.processKeyBindingsForAllComponents(Unknown Source)
    at javax.swing.JComponent.processKeyBindings(Unknown Source)
    at javax.swing.JComponent.processKeyEvent(Unknown Source)
    at java.awt.Component.processEvent(Unknown Source)
    at java.awt.Container.processEvent(Unknown Source)
    at java.awt.Component.dispatchEventImpl(Unknown Source)
    at java.awt.Container.dispatchEventImpl(Unknown Source)
    at java.awt.Component.dispatchEvent(Unknown Source)
    at java.awt.KeyboardFocusManager.redispatchEvent(Unknown Source)
    at java.awt.DefaultKeyboardFocusManager.dispatchKeyEvent(Unknown Source)
    at java.awt.DefaultKeyboardFocusManager.preDispatchKeyEvent(Unknown Source)
    at java.awt.DefaultKeyboardFocusManager.typeAheadAssertions(Unknown Source)
    at java.awt.DefaultKeyboardFocusManager.dispatchEvent(Unknown Source)
    at java.awt.Component.dispatchEventImpl(Unknown Source)
    at java.awt.Container.dispatchEventImpl(Unknown Source)
    at java.awt.Window.dispatchEventImpl(Unknown Source)
    at java.awt.Component.dispatchEvent(Unknown Source)
    at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
    at java.awt.EventQueue.access$000(Unknown Source)
    at java.awt.EventQueue$3.run(Unknown Source)
    at java.awt.EventQueue$3.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
    at java.awt.EventQueue$4.run(Unknown Source)
    at java.awt.EventQueue$4.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
    at java.awt.EventQueue.dispatchEvent(Unknown Source)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.run(Unknown Source)
这是我的登录课程:

包密码程序

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.FileInputStream;
import java.io.ObjectInputStream;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
import javax.swing.UIManager;


public class LogInScreen implements ActionListener {


    public static void main(String[] args) {
        try {
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } 
        catch (Exception e) {
        }
        LogInScreen logger = new LogInScreen();
        logger.start();
    }

就我个人而言,我认为在这种情况下,对象序列化是过火了

您只需将详细信息写入文本文件

public TestFileIO() {
    try {
        writeUser(new File("User.inf"), "Test", "Password".toCharArray());
    } catch (IOException ex) {
        ex.printStackTrace();
    }
}

public void writeUser(File file, String name, char[] password) throws IOException {
    BufferedWriter bw = null;
    try {
        bw = new BufferedWriter(new FileWriter(file));
        bw.write(name);
        bw.newLine();
        bw.write(password);
        bw.flush();
    } finally {
        try {
            bw.close();
        } catch (Exception e) {
        }
    }
}
这只需将用户名和密码写入一个文件,并用新行分隔

如果文件中需要多个用户,可以使用预定义的分隔符在同一行中简单地写入用户名密码

public TestFileIO() {
    try {
        writeUser(new File("User.inf"), "Test", "Password".toCharArray());
    } catch (IOException ex) {
        ex.printStackTrace();
    }
}

public void writeUser(File file, String name, char[] password) throws IOException {
    BufferedWriter bw = null;
    try {
        bw = new BufferedWriter(new FileWriter(file));
        bw.write(name);
        bw.write(";");
        bw.write(password);
        bw.flush();
    } finally {
        try {
            bw.close();
        } catch (Exception e) {
        }
    }
}
现在,如果您担心将密码保存为纯文本,您可以(个人)将密码保存为MD5哈希

public TestFileIO() {
    try {
        writeUser(new File("User.inf"), "Test", "Password".toCharArray());
    } catch (Exception ex) {
        ex.printStackTrace();
    }
}

public void writeUser(File file, String name, char[] password) throws IOException, NoSuchAlgorithmException {

    BufferedWriter bw = null;

    try {
        MessageDigest md = MessageDigest.getInstance("MD5");
        byte[] bytes = new byte[password.length];
        for (int i = 0; i < bytes.length; i++) {
            bytes[i] = (byte) password[i];
        }
        md.update(bytes);
        byte[] mdbytes = md.digest();

        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < mdbytes.length; i++) {
            sb.append(Integer.toString((mdbytes[i] & 0xff) + 0x100, 16).substring(1));
        }

        bw = new BufferedWriter(new FileWriter(file));
        bw.write(name);
        bw.newLine();
        bw.write(sb.toString());
        bw.flush();
    } finally {
        try {
            bw.close();
        } catch (Exception e) {
        }
    }
}
publictestfileio(){
试一试{
writeUser(新文件(“User.inf”),“Test”,“Password”.toCharArray());
}捕获(例外情况除外){
例如printStackTrace();
}
}
public void writeUser(文件名、字符串名、字符[]密码)引发IOException、NoSuchAlgorithmException{
BufferedWriter bw=null;
试一试{
MessageDigest md=MessageDigest.getInstance(“MD5”);
字节[]字节=新字节[password.length];
for(int i=0;i
将用户信息带到单独的类中,并将详细信息封装在该类中。因此,根据您的示例,User类将只具有用户名和密码。然后在一个单独的类中创建GUI和主方法。让用户类可以用它自己的字段序列化。@dinukadev所以最好的方法就是重新编写程序?我同意,这只是一个玩具,但我需要确认。如果您的目标是将用户名和密码存储为对象状态的一部分,那么是的,我认为您应该只将用户名和密码封装到一个单独的类中,并将该对象写入输出流。其他成员也可以就此给出建议,这样你就可以对如何前进做出更合理的判断:)我不知道这些代码的很多含义,但感谢您给出的精彩答案。在我读过之后,我会添加一些内容。基本上,它所做的就是将用户名和密码作为文本写入文本文件。签出[Basic I/O]9http://docs.oracle.com/javase/tutorial/essential/io/)欲知详情
public TestFileIO() {
    try {
        writeUser(new File("User.inf"), "Test", "Password".toCharArray());
    } catch (Exception ex) {
        ex.printStackTrace();
    }
}

public void writeUser(File file, String name, char[] password) throws IOException, NoSuchAlgorithmException {

    BufferedWriter bw = null;

    try {
        MessageDigest md = MessageDigest.getInstance("MD5");
        byte[] bytes = new byte[password.length];
        for (int i = 0; i < bytes.length; i++) {
            bytes[i] = (byte) password[i];
        }
        md.update(bytes);
        byte[] mdbytes = md.digest();

        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < mdbytes.length; i++) {
            sb.append(Integer.toString((mdbytes[i] & 0xff) + 0x100, 16).substring(1));
        }

        bw = new BufferedWriter(new FileWriter(file));
        bw.write(name);
        bw.newLine();
        bw.write(sb.toString());
        bw.flush();
    } finally {
        try {
            bw.close();
        } catch (Exception e) {
        }
    }
}