# Erste Schritte mit JavaServerFace



## mad-din (5. Jan 2008)

Hi Leute!

Ich versuch grad meine ersten Schritte mit JavaServerFaces, dafür hab ich mir gleich ein eigenes Projekt aufgebrummt, das mir sogar was bringt  Ich hab mir einen MailServer aufgesetzt, der Domains, Emails, Weiterleitungen, etc. über MySQL-Tabellen verwaltet. 
Damit ich nicht immer direkt auf der Datenbank rumschrubben muss, will ich mir jetzt eine JSF Webapplikation schreiben, die mir diese Verwaltung abnimmt. 

Dazu habe ich jetzt erstmal die Domains in Auge gefasst. Ich will also eine Seite, auf der alle Domains gelistet werden. Über eine Checkbox soll man eine Domain löschen oder bearbeiten können, zudem soll man noch eine neue Domain hinzufügen können.

Soweit bin ich nun schon: ich hab die Seite, die mir die Domains auflistet. Dafür habe ich eine JSP domains.jsp, eine Klasse Domain und eine Klasse DomainList (die sehr einfach ist und sogar auch die Datenbankverbindung herstellt, aber das war ja nur zum Testen). 

Hier mal der Quellcode:

domains.jsp


```
<?xml version="1.0" encoding="ISO-8859-1" ?>
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<f:view>
<f:loadBundle basename="de.resolution_m.mailadmin.messages.global" var="global" />
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
<link rel="stylesheet" type="text/css" href="css/style.css" />
<title><h:outputText value="#{global.appTitle}" /></title>
</head>
<body>
<h:form>
<div id="header">[img]images/logo.jpg[/img]</div>

<div id="menu">
<ul>
 [*][url="domains.html"]Domains[/url]
 [*][url="#"]Benutzer[/url]
 [*][url="#"]E-Mail Adressen[/url]
 [*][url="#"]Weiterleitungen[/url]
[/list]
</div>

<div id="content">
<h1>Domains</h1>

<div id="actionMenu">
 <ul>
  [*][url="#"]Neue Domain hinzufügen[/url]
 [/list]
</div>

<h:dataTable var="domain" value="#{domainList.domainList}" id="domainTable" headerClass="th" columnClasses="td">
	<h:column>
		<f:facet name="header">
			<h:outputText value="#{global['domainTable.header.id']}" />
		</f:facet>
		<h:outputText value="#{domain.id}" />
	</h:column>
	<h:column>
		<f:facet name="header">
			<h:outputText value="#{global['domainTable.header.name']}" />
		</f:facet>
		<h:outputText value="#{domain.name}" />
	</h:column>
	<h:column>
		<f:facet name="header">
			<h:outputText value="#{global['domainTable.header.users']}" />
		</f:facet>
		<h:outputText value="#{domain.users}" />
	</h:column>
	<h:column id="aliases">
		<f:facet name="header">
			<h:outputText value="#{global['domainTable.header.aliases']}" />
		</f:facet>
		<h:outputText value="#{domain.aliases}" />
	</h:column>
	<h:column>
		<f:facet name="heder">
			<h:outputText value="" />
		</f:facet>
		<h:selectBooleanCheckbox />
	</h:column>
</h:dataTable>

<h:commandButton action="do" value="ausführen" />

</div>
</h:form>
</body>
</f:view>
</html>
```

Domain.java

```
package de.resolution_m.mailadmin;

public class Domain {

	private String name;
	private String id;
	private String users;
	private String aliases;
	
	public Domain(String name, String id, String users, String aliases) {
		this.name = name;
		this.id = id;
		this.users = users;
		this.aliases = aliases;
	}
	
	public String getName() {
		return name;
	}
	
	public String getId() {
		return id;
	}
	
	public String getUsers() {
		return users;
	}
	
	public String getAliases() {
		return aliases;
	}
	
}
```

DomainList.java

```
package de.resolution_m.mailadmin;

import java.sql.*;
import java.util.ArrayList;
import java.util.List;

public class DomainList {

	private List domainList;
	
	public DomainList() {
		
	}
	
	public List getDomainList() {
		
		domainList = new ArrayList();
		
		try {
			
			Class.forName("org.gjt.mm.mysql.Driver");
			Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/mailserver", "mailuser", "mailuser");
			Statement stmt = connection.createStatement();
			ResultSet domains = stmt.executeQuery("select d.id, " + 
												  "		  d.name, " + 
												  "		  count(u.id) as users, " +
												  "		  count(a.id) as aliases " +
												  "from virtual_domains d " +
												  "left join virtual_users u on d.id = u.domain_id " + 
												  "left join virtual_aliases a on d.id = a.domain_id " +
												  "group by d.id, d.name");
			
			while (domains.next()) {
				
				String id = domains.getString(1);
				String name = domains.getString(2);
				String users = domains.getString(3);
				String aliases = domains.getString(4);
				
				domainList.add(new Domain(name, id, users, aliases));
				
			}
			
			domains.close();
			stmt.close();
			connection.close();
			
		} catch (SQLException se) {
			se.printStackTrace();
		} catch (ClassNotFoundException cnfe) {
			cnfe.printStackTrace();
		}
		
		return domainList;
		
	}
	
}
```

Ich weiß, dass das nicht wirklich sauber ist, aber für die ersten Schritte reicht es ja mal. Mein Problem ist jetzt folgendes:

Vor den Button "ausführen" soll eine Select-Box hin, die die Aktionen "löschen" und "bearbeiten" beinhaltet. Je nachdem, was der Benutzer ausführt soll nun die entsprechende Aktion ausgeführt werden und genau da liegt das Problem: wie krieg ich raus, welche Aktion der Benutzer gewählt hat? Wo sollen diese Aktionen ausgeführt werden? Soll die Klasse Domain.java die Methoden delete() und edit() bekommen oder soll ich eine eigene Klasse DomainActions.java schreiben, die die entsprechenden Aktionen ausführt?

Bin in dem Thema leider nicht so bewandert, wäre es aber gerne  Die Tutorials, die ich bis jetzt gesehen habe, behandeln so ein Thema leider nicht.

Danke schonmal und viele Grüße,
Martin


----------



## maki (5. Jan 2008)

Was genau ist denn die Klasse Domain?
Ein Domänenobjekt oder eine JSF ManagedBean?
Du wirst beides brauchen, Methoden wie löschen etc. haben in der ManagedBean zu stehen, das Dömanenobjekt ist ein "Business" Objekt.

Kann ja auch sein das du zufällig mit "Domain" ein schlechtes Beispiel gewählt hast


----------



## mad-din (5. Jan 2008)

Hi!

Also die Domain.java ist eigentlich nur eine Abbildung einer Domäne, die benötige ich zum Beispiel für die DataTable. Das heißt es wären folgende Klassen sinnvoll:

 - Domain.java -> Abbildung einer Domäne
 - DomainList.java -> Liste für DataTable
 - DomainBean.java -> ManagedBean für Aktionen

Wäre es aber an dieser Stelle nicht auch sinnvoller eine ManagedBean (DomainBean.java) zu haben, die alle Aktionen beinhaltet und auch die Liste für die DataTable bereitstellt und eine Domain.java, die eine Domäne abbildet?

Viele Grüße,
Martin


----------



## maki (5. Jan 2008)

Dann ist der Name gut gewählt 

Schreib dir doch mal deine DomainBean 

Zum suchen, löschen, editieren, anlegen, ansehen etc. von Domain Objekten, zur Ablaufsteuerung der Views, etc.


----------



## mad-din (6. Jan 2008)

Hi!

Also ich hab es jetzt so gemacht:

 - Klasse Domain.java: das Abbild einer Domäne
 - Klasse DomainBean.java: Methoden für Löschen, Einfügen, Bearbeiten, Auflistung aller Domains

Und ich hab die JSP-Seite domains.jsp, in der eine DataTable mit einer Liste aller Domains vorhanden ist. Zudem gibt es da eine Spalte mit einer CheckBox und einen CommandButton "löschen". Wählt der Benutzer jetzt ein oder mehrere CheckBoxen aus und klickt dann auf den Button sollen die ausgewählten Domains gelöscht werden. 

Aber wie kriege ich jetzt mit, welche Domains der Benutzer gewählt hat? Da hakt es bei mir noch, also ich hab eine Navigationsregel erstellt, die von domains.jsp auf domains.jsp verweist und die Attribute "action: delete" und "from outcome: delete" hat. Aber woher weiß jetzt meine Applikation, dass bei action: delete die ausgewählten CheckBoxen gelöscht werden sollen und woher weiß ich, welche CheckBoxen ausgewählt wurden? Muss ich mir da einen eigenen Validator schreiben?

Vielen Dank & viele Grüße,
Martin


----------



## mad-din (6. Jan 2008)

Hi!

Also ich hab jetzt folgendes: in der domain.jsp gibt es einen CommandButton:


```
<h:commandButton value="#{global.deleteButton}" action="#{domainBean.delete}" />
```

In der DomainBean gibt es die Methode "delete", die sieht so aus:


```
public void delete(ActionEvent e) {
		
		System.out.println(e.getComponent().getId());
		
	}
```

Aber jedesmal, wenn ich auf den Button klicke, dann bekomme ich folgende Meldung:


```
javax.servlet.ServletException: #{domainBean.delete}: javax.el.MethodNotFoundException: Method not found: [email]de.resolution_m.mailadmin.DomainBean@19af1f7.dele[/email]te()
```

Ändere ich die Methode in 


```
public String delete() {
		
		return "";
		
	}
```

Dann kommt diese Meldung nicht. Was mach ich hier falsch und wie greife ich auf die CheckBoxen zu??

Viele Grüße,
Martin


----------



## Verena22 (10. Jan 2008)

Hi!
Um mit dem ActionEvent/ActionListenerzu arbeiten, muss du das Attribut actionListener anstatt action auf dem h:commandButton benutzen:

<h:commandButton value="#{global.deleteButton}" actionListener="#{domainBean.delete}" />


----------

