# Servlet als Login



## mamelinchen (19. Mai 2010)

Hallo!

Ich habe ein Servlet in Eclipse geschrieben, welches sich mit der Datenbank verbinden soll und testen soll, 
ob sich die gesendeten Werte in der Datenbank befinden, und wenn ja ein true zurücksenden bzw. das es auf der ClientSeite als true erkannt werden soll.

Auf der Client Seite benutze ich Flex, der Server ist ein Tomcat mit XAMPP.
Die Datenbank ist eine mysql-Datenbank, den Treiber dafür habe ich auch installiert.
Beispielwerte sind drin.
Nur kriege ich erstmal keine Nachricht, ich weiss nicht genau wo der Fehler liegt.


hier das Servlet:


```
package meinservletpackage;

import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.UnavailableException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


public class LoginServlet extends HttpServlet {

	private static final long serialVersionUID = 1L;

	public void init(ServletConfig config) throws ServletException {
		super.init(config);
		try {
			// Treiber laden
			Class.forName("com.mysql.jdbc.Driver").newInstance();
		} catch (ClassNotFoundException e) {
			throw new UnavailableException(
					"Login init() ClassNotFoundException: " + e.getMessage());
		} catch (IllegalAccessException e) {
			throw new UnavailableException(
					"Login init() IllegalAccessException: " + e.getMessage());
		} catch (InstantiationException e) {
			throw new UnavailableException(
					"Login init() InstantiationException: " + e.getMessage());
		}
	}

	public void doPost(HttpServletRequest req, HttpServletResponse res)
			throws ServletException, IOException {
		System.out.println("request: " + req);
		res.setContentType("text/html");
		PrintWriter out = res.getWriter();
		// Holen der Parameter aus dem POST
		String username = req.getParameter("username");
		String password = req.getParameter("password");
		System.out.println("username: " + username);
		System.out.println("password: " + password);

		try {
			if (userInDB(username, password)) {
				[COLOR="Red"]//out.println("Wert=true");[/COLOR]
wäre das die Alternative?
				out.println(true);
			} else {
				out.println(false);

			}
		} catch (SQLException e) {

			e.printStackTrace();
		}
	}

	protected boolean userInDB(String username, String password)throws SQLException {
		if (username == null || password == null) {
			// Register
			System.out.println("Nicht vorhanden.");
		} else {
			Connection connection = DriverManager.getConnection(
			// Ersetzen durch übergebene Parameter username, password!
					"jdbc:mysql://localhost:3306/einkaufDB", "root", "");
			Statement statement = null;
			ResultSet resultSet = null;
			try {
				// Prüft, ob Kombi in Datenbank, wenn result
				statement = connection.createStatement();
				resultSet = statement
						.executeQuery("SELECT username, password FROM userlogin    
                                                                WHERE username="
								+ "'"
								+ username
								+ "'"
								+ "AND password="
								+ "'"
								+ password + "'");
			} catch (SQLException e) {
				System.out.println("Nicht vorhanden:" + e.getMessage());
			} finally {
				if (resultSet != null)
					try {
						resultSet.close();

					} catch (SQLException ignore) {
					}
				if (statement != null)
					try {
						statement.close();
					} catch (SQLException ignore) {
					}
			}

		}
		return true;
	}
}
```

Auf der Flex-Seite erhalte ich das URLLOader-Objekt, wo ich dann sage:

data.loader==true

für die Alternative:
data.loader.Wert=="true".


----------



## Antoras (19. Mai 2010)

Was heißt du bekommst keine Nachricht? Du gibst die ganze Zeit irgendwelche Werte aus. Welche davon sollen jetzt fehlerhaft sein?

Deine Methode 
	
	
	
	





```
userInDB()
```
 gibt übrigens immer true zurück, egal ob der Benutzer existiert oder nicht.


----------



## mamelinchen (19. Mai 2010)

Ich meine mit Nachrichten, ich kann eigentlich nicht auf der Konsole testen, da ich ja die Eingabewerte in die html-seite eingebe und die zum servlet schicke. wo soll ich die sachen dann sehen?
Wie kann ich testen?

Wie returne ich dann richtig?


```
} finally {
				if (resultSet != null) {
					try {
						resultSet.close();
					} catch (SQLException ignore) {
					}
					if (statement != null) {
						try {
							statement.close();
						} catch (SQLException ignore) {
						}
					}return true;
				}
			}
			return false;
```
?
Wenn ein Result vorleigt dann war doch die Abfrage erfolgreich oder nicht?

Es geht um den Wert true in Java  vom Printer, ob der als String geschickt wird oder ...als sonst was, damit ich ihn in Flex empfangen und behandeln kann.
out.println("Wert=true");
Deswegen auch nie möglcihe schreibweise.
Ich habe keine Ahnung, bin totaler Anfänger in sowas!
Und sowas spezielles findet man nie in Foren.


----------



## Antoras (19. Mai 2010)

Statt einer Konsole kannst du auch einen Debugger benutzen und dir die Werte anzeigen lassen. Im übrigen kannst du dir von einem Servlet aus sehr wohl Werte auf der Konsole ausgeben lassen.


```
executeQuery()
```
 gibt niemals null zurück, selbst dann nicht wenn die Abfrage kein Ergebnis lieferte. Um zu überprüfen ob ein Benutzer existiert machst du es dir am einfachsten wenn du die Anzahl der angezeigten Datensätze ausgibst:

```
SELCT COUNT(username) FROM table WHERE ... LIMIT 1
```
Danach kannst du das ResultSet auf den Wert abfragen. Bei 1 existiert der User, bei 0 existiert er nicht. Je nach Ergebnis gibst du dann true oder false zurück.


----------



## mamelinchen (19. Mai 2010)

Aber die 1 liegt dann als String vor, und ich vergleiche mit equals, jA?


----------



## Antoras (19. Mai 2010)

Du kannst dir das sowohl als String als auch als int aus dem ResultSet holen. Musst dann halt nur auf die Vergleichsmethode achten.


----------



## mamelinchen (19. Mai 2010)

Du meinst als
resultSet.getString(1).equals("1")?

Und nicht als 

resultSet.equals("1")?


----------



## Antoras (19. Mai 2010)

Ja, oder 
	
	
	
	





```
ResultSet.getInt(1) == 1
```


----------



## mamelinchen (19. Mai 2010)

Das Problem mit dem Servlet besteht darin, das ich es nicht schaffe, den Tomcat in Eclipse zum Laufen zu bringen.
Die bootstrap.jar wird dauernd übernommen, obwohl ich sie immer wieder lösche und ich n Fehler bekomme.
Ich hatte dann einen anderen Apache Tomcat eingebunden, das funzte, bloss beim Debuggen kam ein 404 Error, liegt wohl an der JVm des Tomcats, und für diese Infos muss ich zu lange suchen , und ich habe leider keine Zeit
Ausserdem hatte der dann den Xampp Tmcat blockiert, welcher am Ende garnet mehr funzte und ich alles deinstallieren musste :S

Ich habe auch zu wenig Erfahrung.
Die Werte könnt ich ja noch so übergeben, stellt das Servlet dann direkt die Verbindung zur Datenbank her und liefert mir das Ergebnis?


----------



## Antoras (20. Mai 2010)

Guck dir mal dieses Plugin an, damit kannst du den Tomcat komfortabel über Eclipse starten: EclipseTotale - Sysdeo Tomcat Launcher Plugin

Ohne einen ServletContainer wie er beim Tomcat mitgeliefert wird, wirst du die Servlets nicht benutzen können. Ansonsten kannst du in einem Servlet alles machen was du sonst in Java machen kannst, also auch die Datenbank ansteuern.


----------



## maki (20. Mai 2010)

Sysdeo ist steinalt und kannst du vergessen, nutzt das WTP.


----------



## Antoras (20. Mai 2010)

Dass man über WTP den Tomcat direkt starten kann hab ich nicht gewusst. Dabei hatte ich die Funktion die ganze Zeit verwendet. Zwar hab ich schon ewig das Plugin von Sysdeo bei Eclipse eingebunden, ich hab es aber nie benutzt. Lediglich zum Beenden des Tomcats hab ich es dann doch gebraucht - den Startvorgang hatte aber WTP eingeleitet, was mir aber nie aufgefallen ist, da die Einstellungen bei beiden Plugins richtig gesetzt waren.

Gibt es bei WTP eine Funktion mit der man den Tomcat explizit beenden kann? Momentan kill ich nur das Programm über Eclipse, hab aber keine Ahnung ob das so gut ist.

Aber zumindest hab ich jetzt ein Plugin weniger, das ist ja nur vorteilhaft.


----------



## maki (20. Mai 2010)

> Gibt es bei WTP eine Funktion mit der man den Tomcat explizit beenden kann? Momentan kill ich nur das Programm über Eclipse, hab aber keine Ahnung ob das so gut ist.


Du kannst die Server (Tomcat, JBoss, etc. pp.) über Eclipse starten/stoppen, mit dem Roten Botton wird er gekillt, du hast aber auch ein shutdown Kommando, das WTP ist bei der JEE Version von Eclipse dabei.

Sysdeo verwende ich nur noch wenn ich skurille Legacy  Projekte habe die noch einen Tomcat 3.3 verwenden, weil das WTP diesen Uralt Schinken nicht unterstützt


----------



## Antoras (20. Mai 2010)

Über den Server-Monitor hab ich jetzt die Funktion gefunden um den Tomcat herunterzufahren. Jetzt kann ich das Plugin von Sysdeo beruhigt vergessen.


----------



## mamelinchen (20. Mai 2010)

Ich habe ja den Tomcat drin, bloss ich nutze in einmal in XAMPP und einmal in eclipse.

Die beiden beiissen sich dann.

Nu teste ich das ganze in einer normalen Klasse,
und ich weiss nicht wieso aber es funzt nicht:


```
public static boolean userInDB(String username, String password) throws Exception{

		try {
			// Treiber laden
			Class.forName("com.mysql.jdbc.Driver").newInstance();
		} catch (ClassNotFoundException e) {
			throw new Exception(
					"Login init() ClassNotFoundException: " + e.getMessage());
		} catch (IllegalAccessException e) {
			throw new Exception(
					"Login init() IllegalAccessException: " + e.getMessage());
		} catch (InstantiationException e) {
			throw new Exception(
					"Login init() InstantiationException: " + e.getMessage());
		}
		if (username == null || password == null) {
			// Register
			System.out.println("Nicht vorhanden.");

		} else {
			Connection connection = DriverManager.getConnection(
			// Ersetzen durch übergebene Parameter username, password!
					"jdbc:mysql://localhost:3306/einkaufDB", "root", "");
			Statement statement = null;
			ResultSet resultSet = null;
			try {
				// Prüft, ob Kombi in Datenbank, wenn result
				statement = connection.createStatement();
				
				//resultSet = statement .executeQuery("SELECT * FROM userlogin");
				resultSet = statement
						.executeQuery("SELECT COUNT(username) FROM userlogin WHERE username="
								+ "'"
								+ username
								+ "'"
								+ "AND password="
								+ "'"
								+ password + "' LIMIT 1");
				  
				  ResultSetMetaData rsmd = (ResultSetMetaData) resultSet.getMetaData();
				  int n = rsmd.getColumnCount();
				  while( resultSet.next() ) {
			          for( int i=1; i<=n; i++ )  // Attention: first column with 1 instead of 0
			          //  System.out.print( extendStringTo14( ResultSet.getString( i ) ) );
			          System.out.println(  resultSet.getString( i ) ) ;
			          System.out.println(  "" ) ;
			          System.out.println(resultSet.getString(1));
				  }
			} catch (SQLException e) {
				System.out.println("Nicht vorhanden:" + e.getMessage());
			} finally {
				if (resultSet != null) {
					try {
						[COLOR="Red"]if (resultSet.getInt(1)==1){[/COLOR]
							return true;
						}
						resultSet.close();
					} catch (SQLException ignore) {
					}
					if (statement != null) {
						try {
							statement.close();
						} catch (SQLException ignore) {
						}
					}
				}
			}

		}
		return false;
	}
```

es wird mir eine 1 zurückgegeben,gebe ich auch aus auf der konsole zur prüfung, nur 
bei der if-Prüfung geht er nicht rein?

Ich kriege immer false zurück:S


----------



## mamelinchen (20. Mai 2010)

Als Type bekomme ich einen BIGINT

Kann ich was damit anfangen?Casten oder so?


----------



## Antoras (20. Mai 2010)

mamelinchen hat gesagt.:
			
		

> ```
> ResultSetMetaData rsmd = (ResultSetMetaData) resultSet.getMetaData();
> int n = rsmd.getColumnCount();
> while( resultSet.next() ) {
> ...


Was willst du mit diesem ganzen Code erreichen?

Das hier reicht vollkommen:

```
ResultSet r = statement.executeQuery(sql);

int count = 0;
while (r.next()) {
  count = r.getInt(1);
}
if (count == 1) {
  //mach was
}
```
Wenn du auf das ResultSet außerhalb von der Schleife zugreifen willst, solltest du eine Exception bekommen, was du gemerkt hättest wenn du sie dir ausgegeben hättest...



			
				mamelinchen hat gesagt.:
			
		

> Ich habe ja den Tomcat drin, bloss ich nutze in einmal in XAMPP und einmal in eclipse.


Du bindest ein mal einen Tomcat in XAMPP ein und rufst diesen dann über Eclipse auf. Solange du den Tomcat entweder nur über XAMPP oder über Eclipse starten möchtest (zur gleichen Zeit), sollte das ohne Probleme gehen.


----------



## mamelinchen (20. Mai 2010)

Aaaaaaaaaaaaaahhh so geht das!

if (resultSet.getInt(1) == 1) {

geht nicht da es ein anderer Typ ist und ich durch die Zuweisung an den count...ahhhh

und mir hat die while-Schleife gefehlt, ohne die geht nix!

Danke, es geht!!!!

Vielen dank für deine Hilfe, es geht vorwärts

Aber der Tomcat blockiert den Port trotzdem , wenn ich ihn ausschalte in eclipse, oder eclispe beende.


----------



## Antoras (20. Mai 2010)

> Aber der Tomcat blockiert den Port trotzdem , wenn ich ihn ausschalte in eclipse, oder eclispe beende.


Sollte normalerweise nicht passieren wenn du ihn richtig beendest. Guck mal im Task-Manager nach ob vllt. doch noch irgendwo ein halbtoter Tomcat rumschwirrt, nachdem du ihn terminiert hast.


----------



## mamelinchen (20. Mai 2010)

Hab ich auch schon, habe javaw, die danach noch rumschwirrt beendet und sonst alles, was danach klingt, aber trotzdem!
Der Tomcat liess sich in XAMPP auch nach NEUSTART nicht mehr starten.

Hab schon viel gesucht!
Und ich glaube ich lass die Finger davon , ihn in Eclipse nochma einzustellen.
Am Ende musst ich ihn neu installieren


----------



## Antoras (20. Mai 2010)

Ich hab den Tomcat in Verbindung mit XAMPP auch nie richtig zum laufen gebracht. Benutz ihn lieber ohne XAMPP. Ist zwar mehr Aufwand, vor allem weil du dann noch extra ein DBMS installieren musst, aber danach kannst du sicher sein, dass es funktioniert - sofern du alles richtig gemacht hast .

Aber so wie sich das anhört kann die fehlende Portfreigabe eigentlich nicht am Tomcat liegen, wenn der Prozess wirklich nicht mehr existiert. Da muss Windows sonst noch irgendwo was laufen haben. Ich rate dir mal zu einem der wenigen Sachen, zu denen man bei Windows raten kann: neu starten.


----------

