Serialisierung in Java

mortilus

Mitglied
Guten Abend, ich bin wieder da für ein neues Problem.
Mit diesem Programm muss ich einfach ein Objekt speichern.
Es geht, um sich registrieren und anmelden zu können, ich eine Main wo alles ausgeführt wird und zwei anderen Klassen: Benutzer --> da habe ich alle Get und set Methoden; dann AnmeldenRegistrien --> hier habe ich die zwei Methoden anmelden und registrieren; ich habe so programmiert, dass bei der Registrierung das Objekt Benutzer übergeben wird und später wird es in den ArrayList gespeichert. Bei der Methode Anmelden wird den Benutzername und das Passwort übergeben und einfach überprüft, ob sie mit dem Objekt, das in der ArrayList befindet, stimmt bzw gleich ist. Das Problem liegt eben beim Speicher des Objektes AnmeldenRegistrieren und ich habe keine Ahnung wieso.
Java:
public class Main {
    public static void main(String[] args) {
        String benutzer, password;

        int auswahl, x = 0;

        Scanner input = new Scanner(System.in);
        AnmeldenRegistrieren anmregi = new AnmeldenRegistrieren();

        while(x != 1) {
        System.out.println("*    Anmelden als User   <1>    *");
        System.out.println("*    Anmelden als Admin  <2>    *");
        System.out.println("*         Registrieren   <3>    *");
        System.out.println("*            EXIT        <4>    *");
        auswahl = input.nextInt();

            switch(auswahl){
            case 1:
                    System.out.println("Enlesung vom gespeicherten Object");
                    try {
                        ObjectInputStream is = new ObjectInputStream(new FileInputStream("data.ser"));
                        anmregi = (AnmeldenRegistrieren) is.readObject();
                        is.close();
                    } catch (FileNotFoundException e) {
                        System.out.println("File not found");
                    } catch (IOException e) {
                        System.out.println("Error");
                    } catch (ClassNotFoundException e) {
                        e.printStackTrace();
                    }

                    System.out.println("Geben Sie den Benutzername ein!");
                    benutzer = input.next();
                    System.out.println("Passwort eingeben!");
                    password = input.next();
                    anmregi.anmelden(benutzer, password);
                    if(anmregi.getZustand() == true){
                        System.out.println("Erfolgreiche Anmeldung");
                    }else{
                        System.out.println("Fehlgeschlagene Anmeldung");
                    }
                    break;
                case 2:
                    //Admin kommt später
                    break;
                case 3:
                    System.out.println("Geben Sie den Nickname ein!");
                    benutzer = input.next();
                    System.out.println("Geben Sie das Passwort ein!");
                    password = input.next();
                    anmregi.registrieren(new Benutzer(benutzer, password));

                    // Objekt wird gespeichert // Problem beim speichern
                    try {
                        ObjectOutputStream ou = new ObjectOutputStream(new FileOutputStream("data.ser"));
                        ou.writeObject(anmregi);
                        ou.close();
                    } catch (FileNotFoundException e) {
                        System.out.println("Klasse wurde nicht gefunden!");
                    } catch (IOException e) {
                        System.out.println("Error");
                    }

                break;
                case 4:
                    x = 1;
                break;
            }
        }
    }
}
Java:
public class AnmeldenRegistrieren {
    private Benutzer user;
    private boolean zustand;
    private ArrayList<Benutzer> usernameList = new ArrayList<>();

    public void registrieren(Benutzer user){
        usernameList.add(user);
        System.out.println(user.getUsername());
        System.out.println(user.getPassword());
    }
    public boolean anmelden(String nickname, String password){
        for(Benutzer i:usernameList){
            if(i.getUsername().equals(nickname) && i.getPassword().equals(password)){
                zustand = true;
            }else{
                zustand = false;
            }
        }
        return zustand;
    }
    public boolean getZustand(){
        return zustand;
    }
}
Java:
public class Benutzer {
    private String username;
    private String password;

    public Benutzer(String username, String password){
        this.username = username;
        this.password = password;
    }

    public String getUsername(){
        return username;
    }
    public String getPassword(){
        return password;
    }
}


Ich würde mich freuen, wenn mir eine Person helfen könnte! 🙂
 
Zuletzt bearbeitet von einem Moderator:
Ok dann habe ich in der Klasse Benutzer das Interface Serializable implementiert, aber was meinen Sie mit "equals überschrieben ", entschuldigen Sie aber das verstehe ich nicht. Wo muss ich was und wo schreiben? :/ Ps. Danke für deine Antwort
 
Sorry, ich habe gestern beim überfliegen nicht den kompletten Code überschaut, wegen fehlender Formatierung des Codes. Jetzt habe ich ich es mir jedoch genauer angesehen.
1. Du verschluckst die wertvollen Exception-Informationen in deinen catch-Blöcken.
So auch in jenem in den du hereinkommst:
Java:
 } catch (IOException e) {
    System.out.println("Error");
}
Besser:
Java:
 } catch (IOException e) {
    System.out.println("Error");
    e.printStackTrace();
}
Um überhaupt was mitzubekommen. Oder einen Logger benutzen.
Jetzt sieht man auch eine Exception:
Java:
java.io.NotSerializableException: AnmeldenRegistrieren
-> Auch AnmeldenRegistrieren muss Serializable implementieren.

2. Du hattest im Text angesprochen, dass du prüfen möchtest ob das Objekt in der Liste ist. Hier benutzt du vermutlich boolean contains(Object o); aus dem List Interface. Was macht contains? Das steht wunderbar im Javadoc:
Returns true if this list contains the specified element. More formally, returns true if and only if this list contains at least one element e such that (o==null ? e==null : o.equals(e)).
Es ruft also für jeden Benutzer equals auf. Wenn du equals nicht überschreibst wird die equals-Funktion aus Object verwendet, die Adressen vergleicht. Das wirst du nicht wollen, da gerade nach dem serialisieren und dann deserialisieren die Adresse verschieden sein wird. Deshalb musst du die equals überschreiben und selbst bestimmen, wann zwei Objekte gleich sind. Dabei musst du den equals-Contract einhalten.
Java:
@Override
public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;
    Benutzer benutzer = (Benutzer) o;
    return Objects.equals(username, benutzer.username);
}
 
Entschuldigung, aber ich bin wieder da, denn ich habe ein Problem bei der Anmeldung. Wenn ich mich registriere wird das Objekt richtig gespeichert. Aber ich mich anmelden muss, liest er den ArrayList wo alle User gespeichert sind, aber ich kann mich nur mit dem letzten User, der hinzugefügt wurde,anmelden. Das verstehe ich nicht! Entschuldigung, vielleicht ist was du mir vorher geschrieben hast, aber ich hab es einfach nicht ganz verstanden.
Java:
public class AnmeldenRegistrieren implements Serializable{
    private Benutzer user;
    private boolean zustand, zustand2;
    private ArrayList<Benutzer> usernameList = new ArrayList<>();
    //private static String adminPassword = "Hallo";
    //private static int pinAdmin = 1243;


    public void registrieren(Benutzer user){
        usernameList.add(user);
        System.out.println(user.getUsername());
        System.out.println(user.getPassword());
    }
    public boolean anmelden(String nickname, String password){
        for(Benutzer i: usernameList){
            if(i.getUsername().equals(nickname) && i.getPassword().equals(password)){
                zustand = true;
            }else if(i.getUsername().equals(nickname) && !i.getPassword().equals(password)){
                zustand = false;
            }else if(!i.getUsername().equals(nickname)){
                zustand = false;
            }
        }
        return zustand;
    }
    public boolean getZustand(){
        return zustand;
    }
    //public boolean getZustand2() { return zustand2;}

    public void getList(){
        for(Benutzer i: usernameList){
            System.out.println("Benutzername: "+i.getUsername());
            System.out.println("Password    : "+i.getPassword());
        }
    }
    /*public boolean adminAnmelden(Administrator admin){
        if(admin.getPasswordAdmin().equals(adminPassword)){
            zustand2 = true;
        }else{
            zustand2 = false;
        }
        return zustand2;
    }*/
}
Java:
public class Benutzer implements Serializable{
    private String username;
    private String password;

    public Benutzer(String username, String password){
        this.username = username;
        this.password = password;
    }

    public String getUsername(){
        return username;
    }
    public String getPassword(){
        return password;
    }
}
Java:
public class Main {
    public static void main(String[] args) {
        String benutzer, password;
        String adminPassword;
        int adminPin;

        int auswahl, x = 0, auswahl2, y = 0;

        Scanner input = new Scanner(System.in);
        AnmeldenRegistrieren anmregi = new AnmeldenRegistrieren();

        while(x != 1) {
        System.out.println("*    Anmelden als User   <1>    *");
        System.out.println("*    Anmelden als Admin  <2>    *");
        System.out.println("*         Registrieren   <3>    *");
        System.out.println("*            EXIT        <4>    *");
        auswahl = input.nextInt();

            switch(auswahl){
            case 1:
                    System.out.println("Enlesung vom gespeicherten Object");
                    try {
                        ObjectInputStream is = new ObjectInputStream(new FileInputStream("data.ser"));
                        anmregi = (AnmeldenRegistrieren) is.readObject();
                        anmregi.getList();
                        is.close();
                    } catch (FileNotFoundException e) {
                        System.out.println("Keine Accounts wurden hergestellt");
                        break;
                    } catch (IOException e){
                        System.out.println("Error");
                        break;
                    } catch (ClassNotFoundException e) {
                        e.printStackTrace();
                    }

                    System.out.println("Geben Sie den Benutzername ein!");
                    benutzer = input.next();
                    System.out.println("Passwort eingeben!");
                    password = input.next();
                    anmregi.anmelden(benutzer, password);
                    if(anmregi.getZustand() == true){
                        System.out.println("Erfolgreiche Anmeldung");
                        System.out.println();
                        y = 0;
                        while(y != 1) {
                            System.out.println("----------------------------");
                            System.out.println("| Angemeldet als: "+benutzer+" |");
                            System.out.println("----------------------------");
                            System.out.println();
                            System.out.println("*    Video hinzufuegen   <1>   *");
                            System.out.println("*      Video loeschen    <2>   *");
                            System.out.println("*           MENU         <3>   *");
                            auswahl2 = input.nextInt();

                            switch (auswahl2){
                                case 1:
                                    //video hinzufuegen kommt später
                                break;
                                case 2:
                                    //video loschen kommt später
                                break;
                                case 3:
                                    System.out.println();
                                    System.out.println();
                                    y = 1;
                                break;
                            }
                        }
                    }else{
                        System.out.println("Fehlgeschlagene Anmeldung");
                    }
                    break;
                case 2:
                    /*System.out.println("Geben Sie das Administrator Passwort ein");
                    adminPassword = input.next();
                    System.out.println("Geben Sie den PIN");
                    adminPin = input.nextInt();
                    Administrator admin = new Administrator(adminPassword, adminPin);
                    anmregi.adminAnmelden(admin);
                    if(anmregi.getZustand2() == true){
                        System.out.println("Success --> Anmeldung als Administrator");
                    }else{
                        System.out.println("Wrong!");
                    }
                    break;*/
                case 3:
                    System.out.println("Geben Sie den Nickname ein!");
                    benutzer = input.next();
                    System.out.println("Geben Sie das Passwort ein!");
                    password = input.next();
                    anmregi.registrieren(new Benutzer(benutzer, password));

                    // Objekt wird gespeichert // Problem beim speichern
                    try {
                        ObjectOutputStream ou = new ObjectOutputStream(new FileOutputStream("data.ser"));
                        ou.writeObject(anmregi);
                        ou.close();
                        System.out.println("Objeckt wurde gespeichert!");
                    } catch (FileNotFoundException e) {
                        System.out.println("Klasse wurde nicht gefunden!");
                    } catch (IOException e) {
                        System.out.println("Error");
                    }

                break;
                case 4:
                    x = 1;
                break;
            }
        }
    }
}
Ps. ich entschuldige mich für die kontinuierliche Fragen 🙁
 
Zuletzt bearbeitet von einem Moderator:
Leider hast du den Vorschlag mit der Ausgabe der Exception nicht umgesetzt.
Deine Methode anmelden ist nicht richtig implementiert: Du iterierst über ALLE Benutzer, dabei überschreibst du den Zustand. Die Aussage von zustand ist nur für den letzten Benutzer, der geprüft wird richtig.
Du solltest dringend zustand und zustand2 in sinnvolle Variablennamen umbenennen.
 
Die Variable zustand lässt sich ganz verwerfen, da sie sich aus den Informationen rekonstruieren lässt. Hier eine einfache Implementierung der Anmeldung:
Java:
public boolean anmelden(String nickname, String password) {
   boolean zugriff = false;
   for( Benutzer benutzer: usernameList ){
      // Benutzer anhand des Namen filtern
      if( !benutzer.getUsername().equals(nickname) ) {
         continue;
      }
      zugriff = benutzer.getPassword().equals(password);
   }
   return zugriff;
}
Wichtig ist, dass nur der Benutzer mit dem übergebenen namen auch geprüft wird. (Im Gegensatz zu deiner vorherigen Implementierung). Du kannst sobald der Benutzer geprüft wurde auch die Schleife verlassen. Hier gibt es viele Möglichkeiten und Geschmäcker dies richtig zu tun.
In deiner Main kannst du die Funktion dann benutzen:
Java:
 if( anmregi.anmelden(benutzer, password) ) {
 
Zuletzt bearbeitet:

Zurück
Oben