Jordy
Jordy

Reputation: 3

HTTP Status 500 - NoSuchElementException

I've been getting this error and I haven't found a way to come around it yet. Seems to be something regarding the scanner, but I'm not sure what to change here.

My LoginServlet:

package web;

import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Scanner;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class LoginServlet extends HttpServlet {
    protected void doPost(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        // ______________________________________________________________
        boolean loginSuccess = false;
        String naam = "";
        String pass = "";
        RequestDispatcher rd = null;
        String operator = req.getParameter("operator");

        if (operator.equals("Register")) {
            req.getRequestDispatcher("Register.jsp").forward(req, resp);
        }
        // _________________________*******_________________________________

        // ___________________scanner declaratie________
        FileReader fr = new FileReader("users.txt");
        Scanner sc = new Scanner(fr);
        // _________________________*******____________

        // ___________________!! Lezen van file !!________________________
        if (operator.equals("Login")) {
            while (sc.hasNextLine()) {
                String regel = sc.nextLine();
                sc.useDelimiter("\\s:\\s");
                naam = sc.next();
                pass = sc.next();

                System.out.println(naam);
                System.out.println(pass);
                // ___________________Toevoegen aan logged users_____
                if (req.getParameter("username").equals(naam)
                        && (req.getParameter("password").equals(pass))) {
                    PrintWriter out = new PrintWriter(new BufferedWriter(
                            new FileWriter("loggedusers.txt", true)));

                    out.println(naam);
                    out.close();
                    loginSuccess = true;
                    break;
                } else if (req.getParameter("username").equals(naam)
                        && (!req.getParameter("password").equals(pass))) {
                    req.setAttribute("error", "Password incorrect");
                    loginSuccess = false;
                    break;
                } else if (!sc.hasNextLine()) {
                    req.setAttribute("error", "Username doesn't exist");
                    loginSuccess = false;
                    break;
                }
            }
            sc.close();

            if (loginSuccess = true) {
                req.getRequestDispatcher("Welcome.jsp").forward(req, resp);
            } else if (loginSuccess = false) {
                req.getRequestDispatcher("Login.jsp").forward(req, resp);
            }


        }
    }
}

My Login.jsp:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
<title>Login page</title>
</head>
<body>
    <form action="LoginServlet.do" method="post">
        <table>
            <tr>
                <td align="right">Username:</td>
                <td align="left"><input type="text" name="username" /></td>
            </tr>
            <tr>
                <td align="right">Password:</td>
                <td align="left"><input type="text" name="password" /></td>
            </tr>
            <tr>
                <td align="left"><input type="submit" name="operator" value="Register" /></td>
                <td align="right"><input type="submit" name="operator" value="Login" /></td>
            </tr>
        </table>

    </form>
    <h1><%=request.getAttribute("error") %></h1>
</body>
</html>

The web.xml should be correct because it worked before, but after writing the rest of the code from the servlet, it jams.

The error it gives me in Eclipse:

jun 03, 2015 4:44:44 PM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [Dynamic Example Servlet] in context with path [/DynamicExample] threw exception
java.util.NoSuchElementException
    at java.util.Scanner.throwFor(Unknown Source)
    at java.util.Scanner.next(Unknown Source)
    at web.LoginServlet.doPost(LoginServlet.java:41)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:648)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
    at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:617)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:518)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1091)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:668)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1521)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1478)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Unknown Source)

And a screenshot of what I see in my browser when I run it: http://puu.sh/iaWY9/5b0da53a66.png

I'd love to hear from you guys! Cheers and thanks in advance!

Upvotes: 0

Views: 2248

Answers (3)

Jordy
Jordy

Reputation: 3

I figured it out, I tried it a little different:

FileReader fr = new FileReader("users.txt");
			BufferedReader br = new BufferedReader(fr);

			while (true) {
				String regel = br.readLine();
				if (regel == null) {
					break;
				}
				sc = new Scanner(regel);
				sc.useDelimiter("\\s:\\s");
				naam = sc.next();
				pass = sc.next();

It works!

Thanks for the solution with the arrays, I saved that piece of code, I think I might try such method later on, thanks everyone!

Upvotes: 0

Makoto
Makoto

Reputation: 106389

Look before you leap. Or more accurately, don't double-advance your Scanner.

These lines are the culprit:

String regel = sc.nextLine();
naam = sc.next();
pass = sc.next();

hasNextLine() is valid for the call to nextLine(), but not to subsequent next() calls.

What you probably want to do is read out the naam and paas values from regel instead.

String regel = sc.nextLine();
String[] regelBroken = regel.split();
naam = regelBroken[0];
paas = regelBroken[1];

This way, you only ever advance the scanner once, so you don't run into a scenario in which you're out of things to scan.

Upvotes: 1

Simimmo
Simimmo

Reputation: 668

Do you have an empty line at the end of "users.txt"?

On last iteration, that could cause naam = sc.next(); throw the exception.

Upvotes: 0

Related Questions