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

我正在编写一个简单的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 allUsernames = new ArrayList(); 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); } } } 

SaveUser类(序列化)

 package passwordProgram; import java.io.FileOutputStream; import java.io.ObjectOutputStream; import java.io.Serializable; public class SaveUser implements Serializable{ public void createAccount(User u) { try { FileOutputStream fileOS = new FileOutputStream("userInfo.ser"); ObjectOutputStream objectOS = new ObjectOutputStream(fileOS); objectOS.writeObject(u); objectOS.close(); } catch (Exception e) { e.printStackTrace(); } } } 

这是我尝试运行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) { } } }