# Servlet Mapping mit JSF



## hyperion (19. Apr 2011)

Hallo,

so nach langer Frustpause habe ich nun mal wieder versucht  an meinem JAVA Projekt weiter zu kommen. Und ich scheitere wieder an der selben Stelle. Ich bekomme einfach nicht diesen HTTP Error 404 weg. 
Ich denke das Hauptproblem liegt immer noch darin, dass mir der Java EE bereich immernoch wie ein Zauberkasten vorkommt. In JAVA SE war ich es gewohnt, dass ich alles nachverfolgen kann. In Java EE gibt es einen Server der entsprechend von Konfigurationsdateien reagiert. Leider basiert mein "Wissen" dazu nur auf Vermutungen. Ich äußere jetzt einfach mal meien Vermutungen und hoffe, dass ihr mich korrigiert wenn ich irgendwo falsch liege, damit dieser Zauberkasten sich für mich endlich mal auflöst.
Ich vermute mal es ist in den Server einprogrammiert, dass der Server im /WEB-INF/ Verzeichnis nach der web.xml Datei schaut. Das ist der zentrale Punkt für den Server, wo die Konfiguration enthalten sind oder Dateien angegeben sind die Konfigurationen enthalten.

Steht folgendes in der web.xml

```
<servlet>
        <servlet-name>Faces Servlet</servlet-name>
        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
</servlet>
```
sage ich dem Server, dass er ein Servlet der Klasse javax.faces.webapp.FacesServlet unter dem Namen Faces Servlet verwenden soll, welches der Server beim Starten anlegt.

Steht folgendes in der web.xml

```
<servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>*.jsf</url-pattern>
        <url-pattern>/WEB-INF/jsf/*</url-pattern>
</servlet-mapping>
```
sage ich dem Server, dass er für alle Anfrage die an ihn kommen, die dem Pattern *.jsf oder /WEB-INF/jsf/* genügen, an das Servlet mit dem namen Faces Servlet übergeben werden. Das Servlet der Klasse javax.faces.webapp.FacesServlet enthält Methoden die der Server dazu verwendet, aus einer XHTML-Datei eine JSF-Datei zu erzeuge, also aus dem Code eine HTML-Ausgabe zu erzeugen.

Steht folgendes in der web.xml

```
<context-param>
        <param-name>javax.faces.CONFIG_FILES</param-name>
        <param-value>/WEB-INF/faces-config.xml</param-value>
</context-param>
```
sage ich dem Server, dass das Konfigurationfile für JSF unter /WEB-INF/faces-config.xml zu finden ist. was javax.faces.CONFIG_FILES bedeuten soll ist mir ein Rätsel. Meines Wissens nach werden Klassen mit der Kamelschrift geschrieben. Reine Großschreibung kenne ich nur von Konstanten. Ist das eine Klasse und wenn ja was macht diese? Wenn nein, was ist das?

Steht folgendes in der web.xml

```
<welcome-file-list>
        <welcome-file>index.jsf</welcome-file>
</welcome-file-list>
```
sage ich dem Server, dass er beim Start index.jsf aufrufen soll. 

Steht in der /WEB-INF/faces-config.xml folgendes

```
<navigation-rule>
		<from-view-id>/index.xhtml</from-view-id>
		<navigation-case>
			<from-outcome>login</from-outcome>
			<to-view-id>/WEB-INF/jsf/login.jsf</to-view-id>
		</navigation-case>
                <navigation-case>
			<from-outcome>register</from-outcome>
			<to-view-id>/WEB-INF/jsf/register.jsf</to-view-id>
		</navigation-case>
</navigation-rule>  
<navigation-rule>
		<from-view-id>/login.xhtml</from-view-id>
		<navigation-case>
			<from-outcome>register</from-outcome>
			<to-view-id>/WEB-INF/jsf/register.jsf</to-view-id>
		</navigation-case>
		<navigation-case>
			<from-outcome>success</from-outcome>
			<to-view-id>/WEB-INF/jsf/home.jsf</to-view-id>
		</navigation-case>
		<navigation-case>
			<from-outcome>failure</from-outcome>
			<to-view-id>/WEB-INF/jsf/login.jsf</to-view-id>
		</navigation-case>
</navigation-rule>
```
sage ich dem Server zum Beispiel, dass wenn aus der Seite index.xhtml register rauskommt er /WEB-INF/jsf/register.jsf aufrufen soll.
Ich würde nun gerne kurz meinen aktuellen Versuch durchspielen und sagen woran es scheitert.
Also ich rufe http://localhost:8080/WebApplication1/ auf.
Der Server schaut nun in die web.xml und stellt fest, dass keine konkrete Seite angegeben wurde und deshalb das welcom-file geladen wird. Es wird also index.jsf aufgerufen. 
Der Server schaut jetzt wieder in die web.xml und stellt fest, dass index.jsf zum pattern *.jsf passt. Er übergibt also den Aufruf an das Faces Servlet. 
Das Faces Servlet schaut nun ob eine Datei Namens index.xhtml vorhanden ist und erzeugt daraus index.jsf und schickt diese an mich.
Ich klicke dort auf den Loginbutton, welcher im action-Attribut "login" enthält. Dadurch wird login an den Server übertragen. 
Der Server schaut nun wieder in /WEB-INF/faces-config.xml nach ob da etwas steht, was mit der Ausgabe login von index.xhtml passieren soll. Dort steht, dass /WEB-INF/jsf/login.jsf aufgerufen werden soll. Das passiert dann auch. 
Der Server schaut jetzt wieder in die web.xml und stellt fest, dass /WEB-INF/jsf/login.jsf zum pattern *.jsf passt(oder auch zu dem anderen pattern). Er übergibt also den Aufruf an das Faces Servlet. 
Das Faces Servlet schaut nun ob eine Datei Namens /WEB-INF/jsf/login.xhtml vorhanden ist und erzeugt daraus login.jsf und schickt diese an mich.
Bis hier funktioniert noch alles. Ich weiß nicht ob das wirklich alles so passiert wie ichs hier beschrieben habe, aber ich bekomme login.jsf noch zu sehen.
Ich klicke nun auf den Link Registrieren, welcher im outcome-Attribut (action gibt es bei link nicht) register enthält. Dadurch wird register an den Server übertragen.
Der Server schaut nun wieder in /WEB-INF/faces-config.xml nach ob da etwas steht, was mit der Ausgabe register von login.xhtml passieren soll. Dort steht, dass /WEB-INF/jsf/register.jsf aufgerufen werden soll.
Der Server schaut jetzt wieder in die web.xml und stellt fest, dass /WEB-INF/jsf/register.jsf zum pattern *.jsf passt(oder auch zu dem anderen pattern). Er übergibt also den Aufruf an das Faces Servlet. 
Das Faces Servlet schaut nun ob eine Datei Namens /WEB-INF/jsf/register.xhtml vorhanden ist und erzeugt daraus register.jsf und schickt diese an mich.
Leider bekomme ich hier nur HTTP Error 404 und ich kann mir einfach nicht erklären warum. Ich komme hier auch einfach nicht weiter. Weder durch das Internet noch durch das bloße durchprobieren von Möglichkeiten.

Gruß hyperion


----------



## Fantasma (21. Apr 2011)

Vorweg... ich bin noch neuer als Du in der Materie.

Aber zwei Sachen die mir aufgefallen sind:

- "<url-pattern>/WEB-INF/jsf/*</url-pattern>"
In den ganzen Beispielen im Netz habe ich noch nie gesehen, dass WEB-INF im pattern matching angegeben war.
Die Pfade sollen sich ja immer auf Root beziehen. Das könnte ein Grund sein.

- <servlet-name>Faces Servlet</servlet-name>
Ich kann wieder nur von Beispielen im Netz reden aber ich hab hier auch noch nie einen Servlet Namen mit
Leerzeichen gesehen. Vielleicht macht das auch Probleme?

Wie gesagt ich hab keine große Ahnung aber das ist mir halt aufgefallen.
Vielleicht kannst du ja weiter recherchieren 

Viel Glück


----------



## mvitz (21. Apr 2011)

Kurz dazu: Leerzeichen im Servlet Namen waren bei mir bisher nie ein Problem (d.h. nicht dass das in jedem Container funktioniert ^^).

Das Mapping ist natürlich quatsch. Das würde ich mal raus nehmen.


----------



## hyperion (21. Apr 2011)

Hallo,

ok. So natürlich ist das nicht, dass das Quatsch ist, deshalb frage ich noch kurz nach. Warum ist das Quatsch?

Gruß hyperion


----------



## mvitz (21. Apr 2011)

1. Wozu brauchst du das 2te Mapping denn noch? Du verlinkst doch eh alles auf .jsf und dann brauchst du das nicht.

2. WEB-INF suggeriert, dass du damit irgendwie auf den Ablageort deiner Views verweisen möchtest, aber URL Patterns sind halt nur für die Aufrufer deiner Seite. Dabei nimmt der Ordner WEB-INF sowieso eine Sonderstellung ein, da alles was hier liegt NICHT direkt von außen zugreifbar ist.


----------



## hyperion (21. Apr 2011)

Zu 1.: Ich habe doch die Wahl bei Links oder Buttons, entweder eine URL oder einen Wert auszugeben. Ich habe mich für den Wert entschieden und welche Seite aufgerufen wird dann im Mapping entschieden. Würde ich das 2. Mapping jetzt entfernen und bei login.xhtml auf registrieren klicken, wie soll dann entschieden werden welche Seite aufgerufen werden soll?

Zu 2.: Ja, ich hab alle Views bis auf Index.xhtml im WEB-INF Ordner, um zu verhindern, dass jemand den Code sehen kann. Die Views sollten auch nicht mit einer URL aufgerufen werden. Im Mapping ist ja auch ein relatives Verzeichnis angegeben und keine Url. Dachte ich zumindest.

Gruß hyperion


----------



## maki (21. Apr 2011)

Vielleciht hilft ja das hier: 5 steps to add facelets in a JSF application  Hobione's Weblog


----------



## Fantasma (22. Apr 2011)

Hallo Mvitz:
vielleicht bringe ich auch was durcheinander aber ich bilde mir ein dass ich mal ein Poblem mit Tomcat hatte als im browser die Leerzeichen entfernt wurden.

Ich hab auch ein kleines servlet mapping Problem aber ich wollte es hier nicth mit reinposten.
Kannst Du mir vielleicht einen Tipp geben?
http://www.java-forum.org/web-tier/116977-servlet-mapping.html


----------



## mvitz (22. Apr 2011)

Naja, das Leerzeichen ist ja nicht im Mapping, sondern als Name für ein Mapping, das macht schon einen Unterschied.


----------

