-3

so, let's say that i have this code

String some = ("my name|username|password");
String[] split = some.split("|");

i want to have a string like this

split[0] = "my name";
split[1] = "username";
split[0] = "password";

here is my code

String record = null;
FileReader in = null;
MainMenu menu = null;
public void checkLogin() throws FileNotFoundException, IOException, ArrayIndexOutOfBoundsException {
    in = new FileReader("D:\\Login.txt");
    BufferedReader br = new BufferedReader(in);

    String username = txfUsername.getText();
    String password = new String(txfPassword.getPassword());

    while ((record = br.readLine()) != null) {

        String[] split = record.split("-");

        if (username.equals(split[1]) && password.equals(split[2])) {

            JFrame frame = new JFrame();
            menu = new MainMenu(split[0]);
            this.setVisible(false);
            menu.setVisible(true);

            break;
        }
    }

    if (menu == null) {
        JOptionPane.showMessageDialog(null, "Username or Password wrong.");
    }
}

and here is login.txt

my name-user-pass

when i run the program it will throw arrayindexoutofbound exception how to get rid of that?

  • You need to show us the full stack trace of the exception, and tell us which line numbers in your program the array accesses are happening at. You also need to print out the value of record to make sure that you are reading it correctly. – tgdavies May 05 '18 at 08:18
  • Have a look in a debugger at the value of `split` – Thorbjørn Ravn Andersen May 05 '18 at 08:23
  • 1
    *"when i run the program it will throw `ArrayIndexOutOfBoundsException` exception. How to get rid of that?"* You check `split.length` before doing `split[1]` and `split[2]`, to make sure you got 3 values. If you don't get 3 values when you think you should, you *debug* the code to figure out why your expectations are not met. – Andreas May 05 '18 at 08:49
  • Possible duplicate of [Splitting a Java String by the pipe symbol using split("|")](https://stackoverflow.com/questions/10796160/splitting-a-java-string-by-the-pipe-symbol-using-split) – Tom May 05 '18 at 10:59

1 Answers1

0

In my opinion, when dealing with a text file you want to always make sure you are actually processing a data line especially if your app is not responsible for creating the text file. You should also always be aware of the fact that the data line may not contain all the required data so as to eliminate the possibility of encountering a ArrayIndexOutOfBoundsException when utilizing the String.split() method.

You may also want to allow for a mechanism to handle comment lines within the text file so that some can be added. These lines would of course be ignored as would blank lines. In this case the text file path and file name is hard coded within the method but if the file was to be User selectable via a JFileChooser (or whatever) it would be good if the very first line of the file was a comment line indicating what the file is for, for example:

;MyAppName Login Data

;Real Name, Login Name, Password
John Doe, johnnyboy, cGFzczEyMzQ
Bill Smith, BoperBill, U3VwZXJDb29sMQ
Tracey Johnson, tracey, NzcyMzQ2Ng
Fred Flinstone, PebblesDaddy, V2lsbWEnc19EdWRl 

In the example file layout above, lines that start with a semi-colon (;) are considered comment lines. The very first comment is the File Descriptor. When the file is read then this line is checked and if it states what is expected then you know for a fact that it is most likely a correct text file to process otherwise the User supplied or selected a wrong text file.

You will notice that the passwords are encrypted. Not even you should know what they are. Passwords are private to the User only. A simple Base64 Encryption is used here (Java 8+ required) but only for example purposes. It may be good enough for a some applications but definitely not for all, but still, something is better than nothing at all.

To encrypt a password in Base64 in your case you might use (import java.util.Base64 required):

String password = Base64.getEncoder().withoutPadding().
        encodeToString(String.valueOf(txfPassword.
        getPassword()).getBytes());

Do this before saving the User Password to file.

Here is how your checkLogin() method might look:

public void checkLogin() throws FileNotFoundException, IOException {
    // Try with Resources...This will auto-close the BufferReader.
    try (BufferedReader br = new BufferedReader(new FileReader("D:\\Login.txt"))) {
        // Install code here to validate that txfUsername and txfPassword 
        // text boxes actually contain something. Exit method if not.
        // ................................

        String userName = txfUsername.getText();
        // Encrypt supplied password and compare to what is in file
        String password = Base64.getEncoder().withoutPadding().encodeToString(String.valueOf(txfPassword.getPassword()).getBytes());

        if (userName.equals("") || password.equals("")) {
            return;
        }

        String line;
        int lineCounter = 0;
        boolean loginSuccess = false;
        while ((line = br.readLine().trim()) != null) {
            lineCounter++;
            // Is this the right data file?
            if (lineCounter == 1 && !line.equals(";MyAppName Login Data")) {
                JOptionPane.showMessageDialog(this, "Wrong Text File Supplied!",
                        "Invalid Data File", JOptionPane.WARNING_MESSAGE);
                return;
            }
            // Skip blank and comment lines...
            if (line.equals("") || line.startsWith(";")) { continue; }

            // Split the comma/space delimited data line (", ")
            String[] lineSplit = line.split(",\\s+"); // \\s+ means 1 or more spaces
            // make sure we have three array elements
            if (lineSplit.length == 3 && userName.equals(lineSplit[1]) && password.equals(lineSplit[2])) {
                loginSuccess = true;
                JFrame frame = new JFrame();
                menu = new MainMenu(lineSplit[0]);
                this.setVisible(false);
                menu.setVisible(true);
                break;
            }
        }
        // Can't find login name or password in file.
        if (!loginSuccess) {
            JOptionPane.showMessageDialog(this, "Invalid User Name or Password!", 
                    "Invalid Login", JOptionPane.WARNING_MESSAGE);
        }
    } 
}
DevilsHnd - 退職した
  • 8,739
  • 2
  • 19
  • 22