Java: JSF 2 Webanwendung Teil I

In diesem Artikel will ich euch zeigen, wie sich eine simple Webanwendung mit JSF 2 entwickeln lässt. Das Beispiel ist mit Absicht einfach gehalten, damit es in den folgenden Artikeln erweitert werden kann. Geplant sind fünf bis sechs weitere Blogartikel die sich mit Themen wie Primefaces, Spring, JPA und der Java EL beschäftigen.

Um eine Webanwendung auf Basis des JSF Frameworks zu entwickeln, werden folgende zwei Dinge benötigt:

  • ein Webcontainer (Tomcat, Jetty, Glassfish, JBoss, etc.)
  • eine JSF Implementierung (Mojarra, Apache MyFaces)

Sobald der Webcontainer und die JSF Implementierung heruntergeladen und installiert wurden, kann es gleich mit dem nächsten Schrifft weiter gehen. Erstellt über die IDE eurer Wahl ein Java Web Projekt und öffnet im WEB-INF Verzeichnis die web.xml. Sollte die Datei nicht vorhanden sein, so erstellt sie. Für das erste Beispiel ist die web.xml noch sehr kurz. Wir geben über die welcome-file-list die HTML-Dateien an, die für die Webanwendung als Einstiegspunkt gelten sollen. In unseren Beispiel ist das die Datei login.xhtml. Sobald der Benutzer unsere Webanwendung aufruft, wird er an die Login Seite weitergeleitet. Über das servlet und servlet-mapping Tag laden wir den FacesContext und geben an, dass unsere JSF Seiten die Dateiendung *.xhtml besitzen.

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">

	<welcome-file-list>
        <welcome-file>login.xhtml</welcome-file>
    </welcome-file-list>

    <servlet>
        <servlet-name>Faces Servlet</servlet-name>
        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>*.xhtml</url-pattern>
    </servlet-mapping>	

</web-app>

Unsere Webanwendung soll nach dem erfolgreichen Einloggen eine Liste mit Benutzern darstellen. Die einzelnen Benutzer werden über die Klasse User abgebildet. Bei der Klasse handelt es sich um ein einfaches POJO. Die Klasse dient lediglich dazu die Daten über einen Benutzer zu speichern und besitzt dafür set-und get-Methoden.

package de.chuckandwayne.net.SimpleJsfApp.beans;

public class User {
	long id;
	String username;
	String firstname;
	String lastname;

	public User(long id, String username, String firstname, String lastname) {
		super();
		this.id = id;
		this.username = username;
		this.firstname = firstname;
		this.lastname = lastname;
	}

	public long getId() {
		return id;
	}

	public void setId(long id) {
		this.id = id;
	}

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public String getFirstname() {
		return firstname;
	}

	public void setFirstname(String firstname) {
		this.firstname = firstname;
	}

	public String getLastname() {
		return lastname;
	}

	public void setLastname(String lastname) {
		this.lastname = lastname;
	}

}

Die Klasse UserController bildet die Verbindung zwischen View (den xhtml-Dateien) und dem Model (der User-Klasse). Im JSF Sprachgebrauch werden diese Klassen als ManagedBean bezeichnet. Die ManagedBean enthält die Logik, die entscheidet was bei einer Benutzeraktion als nächstes geschieht. Die Klasse wird mit der Annotation @ManagedBean als solche deklariert. Über das name-Attribut wird ein Name für die Bean vergeben, über den in den xhtml-Dateien darauf zugegriffen werden kann. Die Annotation @SessionScoped gibt an, dass die Bean über die gesamte Session des Benutzers erhalten bleibt. Die Methode doLogin() wird ausgeführt, wenn der Benutzer auf den Login-Button auf der Startseite drückt. Wie dem Quellcode zu entnehmen ist, wird nur der Benutzer test akzeptiert. Alle anderen Benutzer bekommen die Nachricht angezeigt, dass Benutzername oder Passwort inkorrekt waren.

package de.chuckandwayne.net.SimpleJsfApp.controller;

import java.util.ArrayList;
import java.util.List;

import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;

import de.chuckandwayne.net.SimpleJsfApp.beans.User;

@ManagedBean(name = "userController")
@SessionScoped
public class UserController {
	String username;
	String password;
	List<User> user;

	public String doLogin() {
		if (username.equals("test") && password.equals("test")) {
			return "userList";
		} else {
			FacesContext context = FacesContext.getCurrentInstance();
			context.addMessage("username", new FacesMessage(
					"Benutzername/Password sind inkorrekt."));
			return "login";
		}
	}

	public List<User> getUser() {
		if (user == null) {
			createUser();
		}

		return user;
	}

	private void createUser() {
		user = new ArrayList<User>();
		user.add(new User(0, "test", "Thomas", "Tester"));
		user.add(new User(2, "admin", "Anke", "Asmussen"));
		user.add(new User(3, "user1", "Martin", "Schmidt"));
		user.add(new User(4, "sven", "Sven", "Mayer"));
		user.add(new User(5, "jens", "Jens", "Hintz"));
		user.add(new User(6, "nicole", "Nicole", "Kuntz"));
	}

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public void setUser(List<User> user) {
		this.user = user;
	}

}

Nach einem erfolgreichen Login liefert die Methode getUser() eine Liste mit User-Objekten die zur Befüllung der Tabelle benutzt werden. Über die createUser() Methode werden einige Beispielnutzer erzeugt. Die restlichen set-und get-Methoden werden für die Benutzereingaben auf der Loginseite benötigt. Als nächstes folgt die xhtml-Seite für den Login. Es werden jeweils zwei Label und Textfelder erzeugt, die per set-Methoden die jeweiligen Variablen in der UserController Klasse befüllen. Diese werden jedoch erst befüllt, wenn der Benutzer auf den Button klickt und damit die Methode doLogin() ausführt.

<html xmlns="http://www.w3c.org/1999/xhtml"
	xmlns:f="http://java.sun.com/jsf/core"
	xmlns:h="http://java.sun.com/jsf/html">
<h:head>

</h:head>
<h:body>
	<center>

			<h:form>
				<h:panelGrid cellpadding="2" columns="2" title="Anmelden">
					<h:outputLabel for="benutzername" value="Benutzername:" />
					<h:inputText id="benutzername" label="Benutzername:"
						value="#{userController.username}" />
					<h:outputLabel for="passwort" value="Passwort:" />
					<h:inputSecret id="passwort" value="#{userController.password}" />
					<h:commandButton action="#{userController.doLogin}" type="submit"
						value="Einloggen" />
				</h:panelGrid>
				<div>
					<h:messages></h:messages>
				</div>
			</h:form>
	</center>
</h:body>
</html>

Die Seite userList.xhtml listet die einzelnen Benutzerobjekte des UserController auf und stellt diese in einer Tabelle dar.

<html xmlns="http://www.w3c.org/1999/xhtml"
	xmlns:f="http://java.sun.com/jsf/core"
	xmlns:h="http://java.sun.com/jsf/html">
<h:head>

</h:head>
<h:body>

	<h:form>
		<br />
		<br />
		<br />
		<h:dataTable id="benutzertabelle" value="#{userController.user}"
			var="user" bgcolor="#F1F1F1" border="10" cellpadding="5"
			cellspacing="3" first="0" rows="4" width="50%" dir="LTR"
			frame="hsides" rules="all">

			<f:facet name="header">
				<h:outputText value="Benutzerliste" />
			</f:facet>

			<h:column>
				<f:facet name="header">
					<h:outputText value="Id" />
				</f:facet>
				<h:outputText value="#{user.id}"></h:outputText>
			</h:column>

			<h:column>
				<f:facet name="header">
					<h:outputText value="Benutzername" />
				</f:facet>
				<h:outputText value="#{user.username}"></h:outputText>
			</h:column>

			<h:column>
				<f:facet name="header">
					<h:outputText value="Vorname" />
				</f:facet>
				<h:outputText value="#{user.firstname}"></h:outputText>
			</h:column>

			<h:column>
				<f:facet name="header">
					<h:outputText value="Nachname" />
				</f:facet>
				<h:outputText value="#{user.lastname}"></h:outputText>
			</h:column>

		</h:dataTable>
	</h:form>

</h:body>
</html>

Damit ist der erste JSF Artikel auch schon wieder abgeschlossen. Abschliessend sei gesagt, dass diese Form des Logins natürlich nie für eine wirkliche Anwendung benutzt werden sollte. In solchen Fällen lohnt sich ein Blick in das Spring Security Framework, dass sich auf das Absichern von Webanwendungen spezialisiert hat. Die folgenden Bilder zeigen, wie der Login-Bildschirm und die Auflistung der Benutzer in dieser Webanwendung aussehen würden.

Hinterlasse eine Antwort

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind markiert *

Du kannst folgende HTML-Tags benutzen: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>