<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Information Centre &#187; Tutorial</title>
	<atom:link href="http://my.center-of.info/tag/tutorial/feed/" rel="self" type="application/rss+xml" />
	<link>http://my.center-of.info</link>
	<description>“Wenn etwas schon da war, wie kann man es dann patentieren?” D.E.Knuth, 2002</description>
	<lastBuildDate>Mon, 28 Sep 2009 23:04:39 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Spring AOP &amp; Ehcache</title>
		<link>http://my.center-of.info/2009/09/25/spring-aop-ehcache/</link>
		<comments>http://my.center-of.info/2009/09/25/spring-aop-ehcache/#comments</comments>
		<pubDate>Fri, 25 Sep 2009 14:27:59 +0000</pubDate>
		<dc:creator>Haf</dc:creator>
				<category><![CDATA[JEE]]></category>
		<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[aop]]></category>
		<category><![CDATA[cache]]></category>
		<category><![CDATA[spring]]></category>

		<guid isPermaLink="false">http://my.center-of.info/?p=145</guid>
		<description><![CDATA[Caching ist ja bekanntlich eine Querschnitts-Anforderung (cross cutting concern), was man eigentlich nicht direkt in die Business-Logik integrieren möchte/sollte.
Hier bietet es sich an, die Cache-Funktionalität mittels AOP (Aspektorientierte Programmierung) zu realisieren.
Dieser Beitrag erklärt das exemplarisch realisieren der Cache-Funktionalität mittels Spring AOP und Ehcache.

Einführung
Vorweg. Es gibt natürlich bei den springmodules ein Cache-Modul. Dieses wird, wenn überhaupt, [...]]]></description>
			<content:encoded><![CDATA[<p>Caching ist ja bekanntlich eine Querschnitts-Anforderung (cross cutting concern), was man eigentlich nicht direkt in die Business-Logik integrieren möchte/sollte.<br />
Hier bietet es sich an, die Cache-Funktionalität mittels AOP (Aspektorientierte Programmierung) zu realisieren.<br />
Dieser Beitrag erklärt das exemplarisch realisieren der Cache-Funktionalität mittels <a href="http://static.springsource.org/spring/docs/2.5.x/reference/aop-api.html" target="_blank" title="Spring 2.5.x Reference Doc: Spring AOP">Spring AOP</a> und <a href="http://ehcache.org/" target="_blank" title="Ehcache">Ehcache</a>.<br />
<span id="more-145"></span><br />
<strong>Einführung</strong><br />
Vorweg. Es gibt natürlich bei den <a href="https://springmodules.dev.java.net/" target="_blank" title="Springmodules">springmodules</a> ein <a href="https://springmodules.dev.java.net/docs/reference/0.9/html/cache.html" target="_blank" title="Springmodules: Cache">Cache-Modul</a>. Dieses wird, wenn überhaupt, nur sehr langsam weiterentwickelt. Das neue <a href="http://www.springsource.org/extensions" target="_blank" title="Spring Source: Spring Extensions">Spring Extensions Projekt</a> beinhaltet leider kein Cache-Modul. Hinzu kommen noch fehlende Funktionalitäten wie z.B. das Löschen von nur einem Objekt aus dem Cache.<br />
Falls man jedoch doch Springmodules Cache nutzen will, kann man sich mein altes <a href="http://my.center-of.info/2009/04/07/cache-method-results-with-ehcache-and-spring/" target="_blank" title="Centre of information: Cache method results with Ehcache and Spring">Beispiel</a> anschauen.</p>
<p><strong>Technologie</strong><br />
In der Lösung wird nur Spring AOP und Ehcache direkt verwendet. Bei der AOP Implementierung wird nicht <a href="http://www.eclipse.org/aspectj/" target="_blank" title="Eclipse: AspectJ Project">AspectJ</a> verwendet um die Anzahl der abhängigen Bibliotheken gering zu halten. Dies ist auch möglich, da die benötigte Funktionalität durch <a href="http://static.springsource.org/spring/docs/2.5.x/reference/aop-api.html" target="_blank" title="Spring 2.5.x Reference Doc: Spring AOP">Spring AOP</a> bereitgestellt wird.<br />
Mittels der Spring-Klasse <a href="http://static.springsource.org/spring/docs/2.5.x/api/org/springframework/cache/ehcache/EhCacheManagerFactoryBean.html" target="_blank" title="Spring 2.5.x API: EhCacheManagerFactoryBean">EhCacheManagerFactoryBean</a> wird der Ehcache integriert.</p>
<p><strong>Bibliotheken</strong><br />
In diesem Fall braucht man mindestens (und die entsprechende Abhängigkeiten):</p>
<ul>
<li>spring 2.5.6</li>
<li>ehcache</li>
</ul>
<p><strong>XML Konfiguration</strong><br />
Die XML Konfiguration für Spring sieht wie folgt aus:</p>
<pre class="brush: xml">
 &lt;!-- ...some other spring configuration... --&gt;

 &lt;!-- Ehcache bean which gets the path the ehcache.xml config file --&gt;
 &lt;bean id=&quot;cacheManager&quot; class=&quot;org.springframework.cache.ehcache.EhCacheManagerFactoryBean&quot;&gt;
        &lt;property name=&quot;configLocation&quot; value=&quot;classpath:ehcache.xml&quot; /&gt;
    &lt;/bean&gt;

 &lt;!-- Interceptor which handels the cross cutting concerns (here: caching) --&gt;
 &lt;bean id=&quot;coInterceptor&quot; class=&quot;de.ic.jee.aop.COCacheInterceptor&quot;&gt;
		&lt;constructor-arg index=&quot;0&quot; ref=&quot;cacheManager&quot; /&gt;
  		&lt;!-- Set the name of the cache which will be used from the cache manager --&gt;
		&lt;constructor-arg index=&quot;1&quot; value=&quot;coCache&quot; /&gt;
	&lt;/bean&gt;

  &lt;!-- Advisor for the relevant methods --&gt;
    &lt;bean id=&quot;coAdvisor&quot; class=&quot;org.springframework.aop.support.RegexpMethodPointcutAdvisor&quot;&gt;
		&lt;property name=&quot;advice&quot;&gt;
        	&lt;ref local=&quot;coInterceptor&quot;/&gt;
		&lt;/property&gt;
		&lt;property name=&quot;patterns&quot;&gt;
                  &lt;!-- only the get and update methods --&gt;
        	  &lt;list&gt;
        		&lt;value&gt;.*update.*&lt;/value&gt;
        		&lt;value&gt;.*get.*&lt;/value&gt;
        	  &lt;/list&gt;
		&lt;/property&gt;
	&lt;/bean&gt;

  &lt;!-- Proxy factory for aop proxy  --&gt;
	&lt;bean id=&quot;coServiceProxy&quot; class=&quot;org.springframework.aop.framework.ProxyFactoryBean&quot;&gt;
		&lt;property name=&quot;target&quot;&gt;
                        &lt;!-- The target bean object --&gt;
			&lt;ref bean=&quot;coService&quot;/&gt;
		&lt;/property&gt;
		&lt;property name=&quot;interceptorNames&quot;&gt;
			&lt;list&gt;
				&lt;value&gt;coAdvisor&lt;/value&gt;
			&lt;/list&gt;
		&lt;/property&gt;
                &lt;!-- Name of this new generated proxy, to identify this object
                       in the autowired process.
                --&gt;
		&lt;qualifier value=&quot;coServiceProxy&quot;/&gt;
	&lt;/bean&gt;
</pre>
<p>Spring AOP ist <a href="http://static.springsource.org/spring/docs/2.5.x/reference/aop.html#aop-introduction-proxies" target="_blank" title="Spring 2.5.x Reference Doc: 6.1.3. AOP Proxies">proxy-basiert</a>. Hierfür wird deswegen ein <a href="http://static.springsource.org/spring/docs/2.5.x/api/org/springframework/aop/framework/ProxyFactoryBean.html" target="_blank" title="Spring 2.5.x API: ProxyFactoryBean">ProxyFactoryBean</a> definiert, was den Advisor (<code>coAdvisor</code>) auf ein bestimmtes Bean einsetzt, somit entsteht dann eine neue Proxy-Klasse (<code>coServiceProxy</code>).</p>
<p>Mit <a href="http://static.springsource.org/spring/docs/2.5.x/api/org/springframework/aop/support/RegexpMethodPointcutAdvisor.html" target="_blank" title="Spring 2.5.x API: RegexpMethodPointcutAdvisor">RegexpMethodPointcutAdvisor</a> kann definiert werden, welche Methoden beobachtet werden. In unserem Fall alle <code>update</code> und <code>get</code> Methoden.</p>
<p>Der Advice bzw. Interceptor (<code>coInterceptor</code>), welcher die Querschnitts-Funktionalität beinhaltet, kriegt eine Referenz auf den CacheManager (hier: <code>cacheManager</code>). Mit dieser Referenz kann beim Methoden-Aufruf vorher im Cache geprüft werden, ob die Antwort schon bekannt ist, wenn nicht, wird die Methode weiter ausgeführt und das Ergebnis (Rückgabewert) dann im Cache gespeichert.</p>
<pre class="brush: java">
public class COCacheInterceptor implements MethodInterceptor {

    private final CacheManager cacheManager;
    public COCacheInterceptor(final CacheManager cm, final String cn) {
		this.cacheManager = cm;
		this.cacheName = cn;
	}

     public Object invoke(final MethodInvocation methodInvocation) throws Throwable {

          /*
           * Cache cache = cacheManager.getCache(this.cacheName);
           * String cacheKey = .... generate cache key, maybe the arguments of the method invocation
           * get element from the cache
           * Element e = cache.get(cacheKey);
           * If element found:
           * - return e.getObjectValue()
           * otherwise:
           * - proceed the method, methodResult = methodInvocation.proceed()
           * - put the result in the cache, cache.put(new Element(cacheKey, methodResult));
           * - return methodResult;
           */

     } // invoke()
}
</pre>
<p>Mit wenig Konfiguration und Programmierung kann man sehr einfach Cache-Funktionalität einfügen, ohne die Business Logik zu verändern.</p>
<p>Links:<br />
- Spring AOP: <a href="http://static.springsource.org/spring/docs/2.5.x/reference/aop-api.html" target="_blank">http://static.springsource.org/spring/docs/2.5.x/reference/aop-api.html</a><br />
- Ehcache: <a href="http://ehcache.org/" target="_blank">http://ehcache.org/</a><br />
- Spring 2.5.x API: <a href="http://static.springsource.org/spring/docs/2.5.x/api/index.html" target="_blank">http://static.springsource.org/spring/docs/2.5.x/api/index.html</a></p>
]]></content:encoded>
			<wfw:commentRss>http://my.center-of.info/2009/09/25/spring-aop-ehcache/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Tutorial: JSF 2.0 Beispielanwendung</title>
		<link>http://my.center-of.info/2009/08/27/tutorial-jsf2-beipielanwendung/</link>
		<comments>http://my.center-of.info/2009/08/27/tutorial-jsf2-beipielanwendung/#comments</comments>
		<pubDate>Wed, 26 Aug 2009 22:22:39 +0000</pubDate>
		<dc:creator>Haf</dc:creator>
				<category><![CDATA[JEE]]></category>
		<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[jsf2]]></category>
		<category><![CDATA[web development]]></category>

		<guid isPermaLink="false">http://my.center-of.info/?p=138</guid>
		<description><![CDATA[Wie schon erwähnt, erscheinen bald die ersten Releases von JSF 2.0.
Entsprechend wird nun eine kleine Beispielanwendung erstellt, um einen ersten Eindruck zu bekommen.
Technologie:

JSF 2.0: Mojarra in Version 2.0.0-b16
Tomcat 6
Maven
Eclipse


Voraussetzung:

JDK 6
Tomcat 6
Eclipse inklusive WTP, Maven (m2eclipse)
Beim m2eclipse-Plugin &#8220;Maven integration for WTP&#8221; in Eclipse nachinstallieren, falls nicht vorhanden

Vorbereitung:

In Eclipse ein dynamische Webprojekt erstellen
Tomcat 6 als Server in [...]]]></description>
			<content:encoded><![CDATA[<p>Wie schon <a href="http://my.center-of.info/2009/08/26/jsf2overview/" title="IC: JSF 2 Überblick">erwähnt</a>, erscheinen bald die ersten Releases von JSF 2.0.<br />
Entsprechend wird nun eine kleine Beispielanwendung erstellt, um einen ersten Eindruck zu bekommen.<br />
Technologie:</p>
<ul>
<li>JSF 2.0: Mojarra in Version 2.0.0-b16</li>
<li>Tomcat 6</li>
<li>Maven</li>
<li>Eclipse</li>
</ul>
<p><span id="more-138"></span><br />
<strong>Voraussetzung:</strong></p>
<ul>
<li><a href="http://java.sun.com/javase/downloads/index.jsp" target="_blank" title="SUN: Java Download">JDK 6</a></li>
<li><a href="http://tomcat.apache.org/download-60.cgi" target="_blank" title="Apache Tomcat 6 Download">Tomcat 6</a></li>
<li><a href="http://www.eclipse.org/downloads/packages/eclipse-ide-java-ee-developers/galileor" target="_blank" title="Eclipse Download: Galileor">Eclipse inklusive WTP</a>, Maven (<a href="http://m2eclipse.sonatype.org/" target="_blank" title="Sonatype: Maven Eclipse Plugin">m2eclipse</a>)</li>
<li>Beim m2eclipse-Plugin &#8220;<strong>Maven integration for WTP</strong>&#8221; in Eclipse nachinstallieren, falls nicht vorhanden</li>
</ul>
<p><strong>Vorbereitung:</strong></p>
<ol>
<li>In Eclipse ein dynamische Webprojekt erstellen</li>
<li>Tomcat 6 als Server in Eclipse einrichten</li>
<li>Dem Projekt &#8220;Maven Nature&#8221; hinzufügen. Zur Zeit ist das Projekt ein reines Webprojekt ohne Maven Eigenschaften. Durch Rechte-Maustaste auf das Projekt und dann <em>Maven > Enable Dependency Management</em> wird Maven-Funktionalität für das Projekt hinzugefügt</li>
<li>Maven erwartet eine andere Ordner-Struktur als in dem WTP-Webprojekt. Als erstes muss der Source-Ordner angepasst werden. Hierfür müssen mind. folgender Ordner erstellt werden: src/main/java. Diesen muss man in Eclipse dann auch als Source-Ordner konfigurieren (Java Build Path)</li>
<li>Der WebContent-Ordner wird von Maven mit der WTP-Integration genutzt. Hier ist keine Veränderung/Anpassung notwendig</li>
<li>Die existierende pom.xml muss entsprechende Einträge erweitert werden. Für JSF 2 könnte das wie folgt aussehen:
<pre class="brush: xml">
&lt;project xmlns=&amp;quot;http://maven.apache.org/POM/4.0.0&amp;quot; xmlns:xsi=&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot; xsi:schemaLocation=&amp;quot;http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd&amp;quot;&gt;
  &lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;
  &lt;groupId&gt;jsf2test&lt;/groupId&gt;
  &lt;artifactId&gt;jsf2test&lt;/artifactId&gt;
  &lt;version&gt;0.0.1-SNAPSHOT&lt;/version&gt;

  &lt;properties&gt;
  	&lt;version.jsf2&gt;2.0.0-b16&lt;/version.jsf2&gt;
  	&lt;version.junit&gt;4.4&lt;/version.junit&gt;
  	&lt;version.jstl&gt;1.2&lt;/version.jstl&gt;
  	&lt;version.servlet&gt;2.5&lt;/version.servlet&gt;
  	&lt;version.log4j&gt;1.2.14&lt;/version.log4j&gt;
  &lt;/properties&gt;

  &lt;repositories&gt;
  	&lt;repository&gt;
		&lt;id&gt;maven2-repository.dev.java.net&lt;/id&gt;
		&lt;name&gt;Java.net Repository for Maven&lt;/name&gt;
		&lt;url&gt;http://download.java.net/maven/2/&lt;/url&gt;
		&lt;layout&gt;default&lt;/layout&gt;
	&lt;/repository&gt;
  &lt;/repositories&gt;

  &lt;build&gt;
    &lt;finalName&gt;jsf2test&lt;/finalName&gt;
    &lt;plugins&gt;
	    &lt;plugin&gt;
			&lt;artifactId&gt;maven-compiler-plugin&lt;/artifactId&gt;
			&lt;configuration&gt;
			&lt;source&gt;1.5&lt;/source&gt;
			&lt;target&gt;1.5&lt;/target&gt;
			&lt;/configuration&gt;
		&lt;/plugin&gt;

	    &lt;plugin&gt;
		  &lt;groupId&gt;org.mortbay.jetty&lt;/groupId&gt;
		  &lt;!-- jetty 7
		  &lt;artifactId&gt;jetty-maven-plugin&lt;/artifactId&gt;
		   --&gt;
		  &lt;artifactId&gt;maven-jetty-plugin&lt;/artifactId&gt;
		  &lt;version&gt;6.1.15&lt;/version&gt;
		  &lt;!--
		  &lt;configuration&gt;
		    &lt;scanIntervalSeconds&gt;10&lt;/scanIntervalSeconds&gt;
		  &lt;/configuration&gt;
		   --&gt;
		&lt;/plugin&gt;
    &lt;/plugins&gt;
  &lt;/build&gt;

   &lt;dependencies&gt;
   	&lt;!-- JSF2 --&gt;
	&lt;dependency&gt;
		&lt;groupId&gt;com.sun.faces&lt;/groupId&gt;
		&lt;artifactId&gt;jsf-api&lt;/artifactId&gt;
		&lt;version&gt;${version.jsf2}&lt;/version&gt;
	&lt;/dependency&gt;

	&lt;dependency&gt;
		&lt;groupId&gt;com.sun.faces&lt;/groupId&gt;
		&lt;artifactId&gt;jsf-impl&lt;/artifactId&gt;
		&lt;version&gt;${version.jsf2}&lt;/version&gt;
	&lt;/dependency&gt;

	&lt;dependency&gt;
      &lt;groupId&gt;javax.servlet&lt;/groupId&gt;
      &lt;artifactId&gt;jstl&lt;/artifactId&gt;
      &lt;version&gt;${version.jstl}&lt;/version&gt;
    &lt;/dependency&gt;

    &lt;dependency&gt;
      &lt;groupId&gt;javax.servlet&lt;/groupId&gt;
      &lt;artifactId&gt;servlet-api&lt;/artifactId&gt;
      &lt;version&gt;${version.servlet}&lt;/version&gt;
    &lt;/dependency&gt;

	&lt;!-- Misc --&gt;
    &lt;dependency&gt;
      &lt;groupId&gt;junit&lt;/groupId&gt;
      &lt;artifactId&gt;junit&lt;/artifactId&gt;
      &lt;version&gt;${version.junit}&lt;/version&gt;
      &lt;scope&gt;test&lt;/scope&gt;
    &lt;/dependency&gt;

    &lt;dependency&gt;
	    &lt;groupId&gt;log4j&lt;/groupId&gt;
	    &lt;artifactId&gt;log4j&lt;/artifactId&gt;
	    &lt;version&gt;${version.log4j}&lt;/version&gt;
	&lt;/dependency&gt;

  &lt;/dependencies&gt;
&lt;/project&gt;
</pre>
</li>
<li>Die Bibliotheken, welche Maven bereitstellt, müssen beim Deploy in WEB/lib kopiert werden. Die Nutzung der Maven Dependencies geschieht durch folgende Einstellung: In den Eigenschaften des Projekts muss unter <strong>Java EE Module Dependencies</strong> die <strong>Maven Dependencies</strong> ausgewählt werden.</li>
<li>Web.xml für JSF anpassen. Z.B. wie folgt:
<pre class="brush: xml">
&lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&gt;
&lt;web-app xmlns:xsi=&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot; xmlns=&amp;quot;http://java.sun.com/xml/ns/javaee&amp;quot; xmlns:web=&amp;quot;http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd&amp;quot; xsi:schemaLocation=&amp;quot;http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd&amp;quot; id=&amp;quot;WebApp_ID&amp;quot; version=&amp;quot;2.5&amp;quot;&gt;
  &lt;display-name&gt;dynWebTest&lt;/display-name&gt;

  &lt;servlet&gt;
    &lt;servlet-name&gt;Faces Servlet&lt;/servlet-name&gt;
    &lt;servlet-class&gt;javax.faces.webapp.FacesServlet&lt;/servlet-class&gt;
    &lt;load-on-startup&gt;1&lt;/load-on-startup&gt;
  &lt;/servlet&gt;

  &lt;servlet-mapping&gt;
    &lt;servlet-name&gt;Faces Servlet&lt;/servlet-name&gt;
    &lt;url-pattern&gt;*.xhtml&lt;/url-pattern&gt;
  &lt;/servlet-mapping&gt;

  &lt;!-- This parameter is also possible to set over JNDI --&gt;
  &lt;context-param&gt;
    &lt;param-name&gt;javax.faces.PROJECT_STAGE&lt;/param-name&gt;
    &lt;param-value&gt;Development&lt;/param-value&gt;
  &lt;/context-param&gt;

  &lt;welcome-file-list&gt;
    &lt;welcome-file&gt;index.html&lt;/welcome-file&gt;
    &lt;welcome-file&gt;index.xhtml&lt;/welcome-file&gt;
  &lt;/welcome-file-list&gt;
&lt;/web-app&gt;
</pre>
</li>
</ol>
<p>Nun steht das Grundgerüst bereit, um endlich mit JSF 2.0 anzufangen.<br />
Für diejenigen, die mit JSF 1.x schon gearbeitet haben, werden wohl die faces-config.xml vermissen. Korrekt. Ist gewollt. Ist nämlich die erste Verbesserung von JSF 2.0! Die faces-config.xml kann immer noch verwendet werden, aber vieles ist durch Annotations möglich und die Navigation ist einfacher/verständlicher geworden. Später mehr dazu.</p>
<p>Vielleicht noch ein paar Worte zur Beispielanwendung: Die Beispielanwendung beinhaltet eine Seite, mit einem Input-Feld und zwei Select-Boxen. Man stelle sich folgendes Szenario vor: Man möchte ein Registrierungs-Formular erstellen, in dem der Nutzer überprüfen kann, ob der Username noch vorhanden ist. Zusätzlich soll er das Land auswählen können, in dem er lebt.</p>
<p><strong> Controller:</strong><br />
Der Controller ist das ManagedBean, welches in den XHTML-Seiten verwendet wird und alle Anfragen verarbeitet.</p>
<pre class="brush: java">
@ManagedBean(name = &amp;quot;fc&amp;quot;)
@RequestScoped
public class FrontController {

	private Person person;

	private String country;

	private String continent;

	private Map&lt;String, String[]&gt; countries;

	@ManagedProperty(value = &amp;quot;#{authService}&amp;quot;)
	private AuthService authService;

	public void isUsernameValid() {

		if(authService.isUsernameValid(person.getUsername())) {

			output = &amp;quot;Username ist nocht nicht vorhanden&amp;quot;;
		} else {
			output = &amp;quot;Username ist schon vorhanden. Bitte einen anderen auswählen&amp;quot;;
		}
	}

        public String[] getCountries() {
		// deliver the countries to the actual continent
		return countries.get(continent);
	}
       /* further get/set-Methods */
}
</pre>
<p>Durch die Annotations wird JSF mitgeteilt, dass es sich bei der Klasse um ein managed bean mit dem Namen <strong>fc</strong> handelt (@ManagedBean) und die jeweils immer nur für ein Request gültig ist (@RequestScoped, <a href="https://javaserverfaces.dev.java.net/nonav/docs/2.0/managed-bean-javadocs/" target="_blank" title="API 2.0 - Managed Bean">weitere Scops sind vorhanden</a>). Früher hat man diese Einstellungen in faces-config.xml durchgeführt.<br />
Neu ist auch @ManagedProperty. Mittels dieser Annotation wird die Dependency Injection Funktionalität von JSF 2.0 verwendet. In FrontController#authService wird nun das passende Objekt mit dem managed bean namen &#8220;authService&#8221; injiziert.<br />
Hier sei anzumerken, dass JSF kein field access durchführt, sondern die getter/setter-Methoden verwendet um Properties zu setzen.</p>
<p>Die Domain-Klasse Person ist ein einfaches Bean bzw. POJO, und repräsentiert die einzugebenden Daten in dem Formular.</p>
<p>Zu dem Controller und Model Teil gehört noch die Präsentation und diese wird mittels <a href="https://facelets.dev.java.net/" target="_blank" title="Facelets">Facelets</a> durchgeführt. In JSF 2.0 ist Facelets die primäre Technologie zur <a href="https://javaserverfaces.dev.java.net/nonav/docs/2.0/javadocs/javax/faces/view/ViewDeclarationLanguage.html" target="_blank" title="ViewDeclarationLanguage API">Beschreibung des Views</a>. Man kann natürlich JSP nutzen, wenn man den Sprung nicht durchführen möchte. Aber die Vorteile liegen eher bei Facelets!</p>
<pre class="brush: xml">
&lt;!DOCTYPE html PUBLIC &amp;quot;-//W3C//DTD XHTML 1.0 Transitional//EN&amp;quot;
        &amp;quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&amp;quot;&gt;

&lt;html xmlns=&amp;quot;http://www.w3.org/1999/xhtml&amp;quot;
      xmlns:ui=&amp;quot;http://java.sun.com/jsf/facelets&amp;quot;
      xmlns:f=&amp;quot;http://java.sun.com/jsf/core&amp;quot;
      xmlns:h=&amp;quot;http://java.sun.com/jsf/html&amp;quot;&gt;

&lt;h:head&gt;
  &lt;title&gt;JSF Demo&lt;/title&gt;
&lt;/h:head&gt;
&lt;h:body&gt;
  &lt;h1&gt;Register&lt;/h1&gt;
  &lt;h:form&gt;

    &lt;h:inputText id=&amp;quot;name&amp;quot; value=&amp;quot;#{fc.person.username}&amp;quot;&gt;
    &lt;/h:inputText&gt;
    &lt;h:commandButton value=&amp;quot;Check username&amp;quot; action=&amp;quot;#{fc.isUsernameValid}&amp;quot;&gt;
    	&lt;f:ajax execute=&amp;quot;name&amp;quot; render=&amp;quot;outIsUserValid&amp;quot; /&gt;
    &lt;/h:commandButton&gt;
    &lt;h:outputText id=&amp;quot;outIsUserValid&amp;quot; value=&amp;quot;#{fc.output}&amp;quot; /&gt;
  &lt;/h:form&gt;
  &lt;br /&gt;

  &lt;h:form&gt;
                &lt;!-- First select box to select the continent.... --&gt;
  		&lt;h:selectOneMenu value=&amp;quot;#{fc.continent}&amp;quot;&gt;
  			&lt;f:selectItems value=&amp;quot;#{fc.continents}&amp;quot; /&gt;
  			&lt;f:ajax render=&amp;quot;countrylist&amp;quot; /&gt;
  		&lt;/h:selectOneMenu&gt;

                &lt;!-- ...and depending of the selected continent, contains this
                      second select box the countries
                --&gt;
  		&lt;h:selectOneMenu value=&amp;quot;#{fc.country}&amp;quot; id=&amp;quot;countrylist&amp;quot;&gt;
  			&lt;f:selectItems value=&amp;quot;#{fc.countries}&amp;quot; /&gt;
  		&lt;/h:selectOneMenu&gt;
  &lt;/h:form&gt;
&lt;/h:body&gt;
&lt;/html&gt;
</pre>
<p>Mittels Facelets ist die Beschreibung der Views reiner XML/XHTML.<br />
In dem ersten Formular ist das Input-Feld, in dem der Nutzer überprüfen kann, ob sein Username schon vergeben ist. Die Überprüfung wird mittels Ajax durchgeführt. Hierfür ist der neue <a href="https://javaserverfaces.dev.java.net/nonav/docs/2.0/pdldocs/facelets/f/ajax.html" target="_blank" title="JSF2 API: Ajax Tag">&lt;f:ajax&gt;-Tag</a> zuständig. Beim betätigen des Buttons wird ein Ajax-Request verschickt, dieser beinhaltet die Werte aus den Felder in dem <em>execute</em>-Attribute. In unserem Fall aus dem Feld mit der ID <em>name</em>. Die Antwort wird, wie in dem <em>render</em>-Attribute definiert, in ID <em>outIsUserValid</em> eingefügt. Auf dem Server wird zur Verarbeitung die Methode FrontController.isUsernameValid() aufgerufen. Während des Aufrus ist FrontController#person mit den aktuellen Werten (hier: username) gesetzt.</p>
<p>In dem zweiten Formular gibt es zwei Select-Boxen. In dem einen kann ein Kontinent ausgewählt werden. Resultierend dazu, wird in der zweiten eine Liste von Ländern angezeigt. Diese Länder-Liste wird durch Ajax ermittelt.<br />
In der ersten Liste ist wieder ein &lt;f:ajax&gt;-Tag zu finden. Bei dem 1. Beispiel wurde der Request verschickt, wenn der Nutzer den Button drückt. D.h. in der Javascript-Welt, beim Click-Event, wird der Request verschickt. Das &lt;f:ajax&gt;-Tag wählt immer das passende Event aus, abhängig von der Komponente, in dem es verwendet wird.<br />
Bei Listen horcht es auf ein OnChange-Event. Natürlich kann man ein anderes Event festlegen, dafür gibt es das <em>event</em>-Attribut.<br />
D.h. also, sobald in der ersten Liste die Auswahl verändert wird, wird die zweite Liste aktualisiert (durch render=&#8221;countrylist&#8221;). Auf dem Server wird FrontController.getCountries() aufgerufen. In dem Kontext ist FrontController#continent belegt, da der Nutzer eine Auswahl in der 1.Liste durchgeführt hat. FrontController.getCountries() liefert nun nur ein Array von Ländern zurück. Die korrekte Verschachtelung in HTML-Elemente (option-Tag) übernimmt JSF!</p>
<p><strong>Fazit:</strong></p>
<ul>
<li>Mittels JSF 2.0 hat man weniger Konfigurationsaufwand</li>
<li>Durch den Einsatz von Facelets macht das Erstellen der HTML-Seiten wieder Spass. Hier kann man die vorhandenen HTML-Templates fast unverändert übernehmen&#8230;</li>
<li>Unproblematischer Javascript/Ajax-Einsatz, ohne es wirklich zu merken!</li>
<li>DI ohne Spring!</li>
</ul>
<p>Also der erste Eindruck hat überzeugt. Wenn man JSF-Fan war, wird man JSF-Fan weiter bleiben. Wenn nicht, könnte man es jetzt bestimmt werden <img src='http://my.center-of.info/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://my.center-of.info/2009/08/27/tutorial-jsf2-beipielanwendung/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
