# Probleme mit ServletRequest



## derSchmu (12. Nov 2008)

Hallo ihrs,

ich habe hier seit ein paar Tagen ein Problem mit einem Tool, dass ich auf der Arbeit unter Eclipse zum Laufen bringen soll. Das Tool ist ne WebApp mit jsf, hibernate und Co und ich moechte es lokal mit Tomcat 6.0.14 zum laufen kriegen.
Ich habe zwar schon bei einigen Projekten mitgewirkt, aber keins aufgesetzt, bzw. neu importiert, dennoch habe ich es nun im Moment ohne Fehler und fehlende Klassen zum laufen bekommen. Das einzige Problem was im Moment noch vorliegt folgendes:

Diese Anwendung wird durch eine andere aufgerufen (php WebApp erzeugt Popup mit url zu einer index.jsp auf localhost inkl einiger get-parameter). Im Debugger sehe ich dann auch, wie der Request im facesRedirectFilter seziert wird und dann die neue Adresse ausgelesen wird. Im weiteren Verlauf komm ich dann in die index.jsp. Dort wird unter anderem folgender Code ausgefuehrt:
Enumeration parameterList = request.getParameterNames();

Und an dieser Stelle stellen sich mir 2 Fragen:
Woher kommt das Objekt request?
Warum ist die Liste mit den Parameter leer, wobei ich doch vorher noch im Filter gesehen habe, dass die Url Parameter enthaelt?

Was noch zu der index.jsp zu sagen ist:
Von anderen Projekten, wo ich mitgewirkt habe, weiss ich, dass dort in den jsps eigentlich immer nur pseudohtml code enthalten war und jegliche datenaufbereitende Logik in Beans abgearbeitet wurde. In diesem Projekt aber enthalten die jsps mehr speziellen Java-Code, als es mir je untergekommen is und vor der o.g. Zuweisung stehen nur ein paar Import-Tags.

Waere nett, wenn mir da einer helfen koennte, vorher hat es das Project lokal noch auf einer Maschine mit myEclipse getan, geht hier aber aus Lizenzgruenden nicht...desweiteren fehlte beim Einrichten unter Eclipse immer die javax.servlet Bibliothek, die ich mit den ServerRuntimes vom Apachi innerhalb der servlet-API hinzugefuegt habe.


----------



## habeKA (12. Nov 2008)

Hm ohne Code / Fehlermedlung und so ist es nicht unbedingt leicht dir zu helfen  :wink: .
Aber ich werde es mal versuchen.

Also 



> Warum ist die Liste mit den Parameter leer, wobei ich doch vorher noch im Filter gesehen habe, dass die Url Parameter enthaelt?



Ich denk mal das die Parameter falsch übergeben werden. Wohin kann ich dir ohne code nicht sagen.



> In diesem Projekt aber enthalten die jsps mehr speziellen Java-Code, als es mir je untergekommen is und vor der o.g. Zuweisung stehen nur ein paar Import-Tags.


I

:noe:  Naja so ist das aber nicht sehr schön. Also ich bin der Auffasung das soviel wie möglich an Java-Code in die Beans oder Servlets  geschrieben werden und NICHT in die JSP. Also direckt den Typen der das Programmiert hat an hauen und  :noe:  sagen ^^



> Woher kommt das Objekt request?


ohne Code kA. Der kann da alles Requesten kA was da vorher alles schon abgelaufen ist.


Also wenn du Code Posten kannst wäre das hilfreicher für mich und warscheinlcih für die andern die dir hefen wollen hauch.


mfg habeKA


----------



## L (12. Nov 2008)

_http://www.exforsys.com/tutorials/jsp/jsp-request-object.html

Lesen..


----------



## derSchmu (12. Nov 2008)

Hallo nochmals und danke fuer den Link, nun weiss ich wenigstens, woher dieses ominoese request-objekt herkommt, genau um das handelt es sich bei unserem Projekt.
Was mich halt immer noch verwundert ist, dass diese Applikation vorher funktioniert hat, auf MyEclipse...mit Ganymede und Europa hat es aber so seine Probleme...
Bei meinem Kollegen kann ich wenigstens noch sehen, dass im QueryString vom Request die Parameter drinn haengen, aber mit getParameterNames bekomme ich definitiv eine leer Enumeration zurueck.

Was Code angeht, was soll ich euch da schicken, weiss ja nicht wo der durchgeht folgendes kann ich aber schon mal zeigen, wo ich aber kaum glaube, dass euch das weiterhilft:

Auszug aus der index.jsp:

```
<%@ page import="java.util.*"%>
<%@ page import="java.security.*"%>
<%@ page import="java.math.*"%>
<%@ page import="java.text.*"%>
<%@ page import="javax.faces.*"%>
<%@page import="javax.faces.context.FacesContext"%>
<%@page import="javax.faces.el.ValueBinding"%>

		<%
		
			String keyVal = "";
			String userIDVal = "";
			Enumeration parameterList = request.getpgetParameterValues();
...
```
Auszug aus der FacesRedirectFilter Klasse:

```
public void doFilter(ServletRequest req,
                       ServletResponse res,
                       FilterChain chain)
      throws ServletException, IOException {
    HttpServletRequest request = (HttpServletRequest)req;
    Enumeration names = request.getParameterNames();
    HttpServletResponse response = (HttpServletResponse)res;
    String uri = request.getRequestURI();
    if (uri.endsWith(".jsp")) {
      int length = uri.length();
      String newAddress =
        uri.substring(0, length-3) + EXTENSION;
      //System.out.println("Redirecting to " + newAddress);
      response.sendRedirect(newAddress);
    } else {  // Address ended in "/"
      //System.out.println("Redirecting to index.faces");
      response.sendRedirect("index.faces");
    }
  }
```

Wenn ihr noch Infos ueber die Konfiguration des Projektes wissen wollt, dann muesstet ihr mir schon genau sagen, was genau ihr benoetigt, ich kann zwar Programmieren in Java, habe aber von Aufsetzen von Projekten kaum ne Ahnung. Mich ueberrascht es auch bei jedem neuen Versuch mit diesem Projekt, was ein anderer Server und eine andere Entwicklungsumgebungen einen solch grossen Einfluss auf eine Applikation ausueben kann.

Was ich im Grunde noch zu dem Projekt sagen kann ist folgendes:
Um alle Compilefehler loszuwerden habe ich als Libraries im BuildPath noch das WebApps hinzugefuegt und ein User library, welches alle vom TomcatServer beinhaltet. Ansonsten habe ich nichts am Tool veraendert...angeblich lief das so vorher einwandfreid unter MyEclipse...ja nee is klar...

[Edit]

Achja noch eine Frage nebenbei....
sobald ich ins lib-Verzeichnis die javax.servlet.jsp (egal welche Version) einfuege, taucht beim Serverstarten folgendes auf:


```
INFO: validateJarFile(C:\Users\eedmarth\workspace123\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\NCD_PRIM\WEB-INF\lib\javax.servlet_2.4.0.v200706111738.jar) - jar not loaded. See Servlet Spec 2.3, section 9.7.2. Offending class: javax/servlet/Servlet.class
```

Die ist zwar nicht noetig, war aber vorher schon in diesem Projekt vorhanden...gibts da irgendeinen Sinn dahinter?! Soweit ich gegooglet hab, sollte man dafuer die servlet-api aus dem Tomcat-Verzeichnis nehmen...


----------



## HLX (13. Nov 2008)

derSchmu hat gesagt.:
			
		

> Auszug aus der index.jsp:
> 
> ```
> ...
> ...


Tippfehler, oder steht das tatsächlich so in der JSP-Datei?




			
				derSchmu hat gesagt.:
			
		

> Was ich im Grunde noch zu dem Projekt sagen kann ist folgendes:
> Um alle Compilefehler loszuwerden habe ich als Libraries im BuildPath noch das WebApps hinzugefuegt und ein User library, welches alle vom TomcatServer beinhaltet. Ansonsten habe ich nichts am Tool veraendert...angeblich lief das so vorher einwandfreid unter MyEclipse...ja nee is klar...


Die Konfiguration von Eclipse-WTP-Projekten ist nicht sonderlich kompliziert. Bibliotheken (JARs) werden auf zwei verschiedenen Wegen zur Verfügung gestellt. Entweder kopierst du sie ins Verzeichnis WEB-INF\lib-Verzeichnis deiner Anwendung, oder du fügst sie über die Projekteinstellungen hinzu. Hierbei mit rechter Maustaste aufs Projekt --> Properties --> J2EE Module Dependencies --> Add JARs... (oder Add External JARs).



			
				derSchmu hat gesagt.:
			
		

> Achja noch eine Frage nebenbei....
> sobald ich ins lib-Verzeichnis die javax.servlet.jsp (egal welche Version) einfuege, taucht beim Serverstarten folgendes auf:
> 
> 
> ...


Offensichtlich versuchst du hier etwas was der Servlet-Spezifikation 2.4 zugeordnet ist, einem Tomcat hinzuzufügen, der die Servlet-Spezifikation 2.3 implementiert. Die einzelnen Tomcat-Versionen implementieren bestimmte Servlet-Spezifikationen. Deine Anwendung und die Bibliotheken sollten konsistent dazu sein.


----------



## derSchmu (13. Nov 2008)

Hio nochmals,

als das mit der Tomcat Spezifikation versteh ich, muss ich halt die 2.3er hinzufuegen...ok
Das mit den Project properties und den preferences von Eclipse ist auch klar...soweit ist ja auch alles konfiguriert...

und das mit der JSP - Datei...ja das steht alles so in der index.jsp ....dese laesst sich auch prima im Debugger durchgehen...ich bin sowas auch nicht gewohnt...normalerweise steht ja in den jsps nur htmlkrams drinn mit verweisen zu den objekten aus der bean...(ok hier und da hab ich schon mal boolsche ausdruecke in referenzen gesehen, aber mehr nicht)

hier jedenfalls existiert eine index.jsp , die folgenden code beinhaltet:


```
<%@ page import="java.util.*"%>
<%@ page import="java.security.*"%>
<%@ page import="java.math.*"%>
<%@ page import="java.text.*"%>
<%@ page import="javax.faces.*"%>
<%@page import="javax.faces.context.FacesContext"%>
<%@page import="javax.faces.el.ValueBinding"%>

		<%
		
			String keyVal = "";
			String userIDVal = "";
			Enumeration parameterList = request.getParameterNames();
			ValueBinding appScope = FacesContext.getCurrentInstance().getApplication().createValueBinding("#{apllicationSettings.apllicationScope}");
			ValueBinding appVer = FacesContext.getCurrentInstance().getApplication().createValueBinding("#{apllicationSettings.apllicationVersion}");
			
			ValueBinding userid = FacesContext.getCurrentInstance().getApplication().createValueBinding("#{primUser.userId}");
			
			//true if "key" found
			Boolean key = false;
			
			//true if "userid" found

			Boolean userID = false;

			while (parameterList.hasMoreElements()) {
				//read out all post values
				
				//contains the parameter name
				String sName = parameterList.nextElement().toString();
				
				//contains the parameter value
				String[] sMultiple = request.getParameterValues(sName);

				//if the postarray contains the value key
				
				if (sName.equals("key")) {
					key = true;
					keyVal = sMultiple[0];
				}
				//if the postarray contains the value userid
				if (sName.equals("userid")) {
				
					userID = true;
					userIDVal = sMultiple[0];
					userid.setValue(FacesContext.getCurrentInstance(), sMultiple[0]);
					//if the user already has a session enter the tool
					if(session.getAttribute("userID") == userIDVal){
						response.sendRedirect("login_racf.faces");
					}
				}
				if (sName.equals("stat")) {
					appScope.setValue(FacesContext.getCurrentInstance(), sMultiple[0].toUpperCase());
					session.setAttribute("applStat", sMultiple[0]);
				}
				if (sName.equals("ver")) {
					appVer.setValue(FacesContext.getCurrentInstance(), sMultiple[0].toUpperCase());
					session.setAttribute("applVer", sMultiple[0]);
				}
			}
			//if the key and the userid where posted enter the if statement
			if (key && userID) {

				//Get actual Date
				Date time = new Date();
				
				//Date formater to get the same date format as  on PHP site.
				SimpleDateFormat formater = new SimpleDateFormat(
						"dd/MM/yyyy/hh/");

				//Build string for the actual time
				//String contains dd/mm/yyyy/hh/userid
				String keyString1 = "NCD-PRIM-SEC-STRING-" + (formater.format(time)).toString()
						+ userIDVal;
				

				//check for actual hour
				MessageDigest m = MessageDigest.getInstance("MD5");
				m.update(keyString1.getBytes(), 0, keyString1.length());
				String jValue1 = new BigInteger(1, m.digest()).toString(16);
	
				if (keyVal.equals(jValue1) || keyVal.equals("0"+jValue1)) {
					//if the values are the same, set the session attributer "userid"
					session.setAttribute("userID", userIDVal);
					response.sendRedirect("login_racf.faces");
				} else {
					//else redirect to the error page
					response.sendRedirect("failure_login.faces");
				}
			} else {
				response.sendRedirect("failure_login.faces");
			}
		%>
```

was ich halt an dieser Stelle noch dazu sagen kann...die parameterliste ist leer, daher geht er nicht die parameter durch und springt letztendlich auf die 'fehler-seite'...die frage ist, warum ist die liste leer,da beim redirectfilter im request-objekt noch die parameter enthalten sind?!


----------



## HLX (14. Nov 2008)

Du machst im RedirectFilter ein response.sendRedirect(). Dabei wird ein neuer Request erzeugt. Die alten Request-Parameter dürften damit hinfällig sein. Du könntest versuchen deinen Request per RequestDispatcher und der Methode findForward weiterzuleiten. Dabei wird der gleiche Request an eine andere Adresse umgeleitet.


----------



## derSchmu (17. Nov 2008)

hio...das mit dem request hab ich mir gedacht...aber nun die frage zu deinem vorschlag, wie sieht sowas aus und wie binde ich das ein? kommt dann die weiterleitung in den filter rein...auch wenn der fehlerhaft ist, so in etwa?:

```
public void doFilter(ServletRequest req,
                       ServletResponse res,
                       FilterChain chain)
      throws ServletException, IOException {
    HttpServletRequest request = (HttpServletRequest)req;
    HttpServletResponse response = (HttpServletResponse)res;
    String uri = request.getRequestURI();
    if (uri.endsWith(".jsp")) {
      int length = uri.length();
      String newAddress =
        uri.substring(0, length-3) + EXTENSION;
      //System.out.println("Redirecting to " + newAddress);
      RequestDispatcher rqDispatcher= req.getRequestDispatcher(newAddress);
      rqDispatcher.forward(req,res);
      //response.sendRedirect(newAddress);
    } else {  // Address ended in "/"
      //System.out.println("Redirecting to index.faces");
      //response.sendRedirect("index.faces");
      RequestDispatcher rqDispatcher= request.getRequestDispatcher("index.faces");
      rqDispatcher.forward(request,response);
    }
  }
```


----------



## HLX (17. Nov 2008)

Ich ziehe normalerweise eine derartige Weiterleitung nur im Fehlerfall vor. Um ein zentrales Servlet oder eine zentrale JSP-Seite anzusprechen kann man auch das Servlet-Mapping in der web.xml verwenden. Mir fällt allerdings auch nichts ein, was prinzipiell gegen deine Variante sprechen würde.


----------



## derSchmu (17. Nov 2008)

hmm...um es mal so zu sagen...

es handelt sich hier nicht um MEINE variante...ich habe dieses projekt vorgelegt bekommen und soll es warten und ggf auch neue funktionen hinzufuegen. dafuer reichen meine java, jsf, odbc etc -kenntnisse voellig aus. nur blick ich das einrichten nich...bzw, den jsfkrams beim einrichten..ich weiss nicht mal, was dieser filter macht...und ob meine aenderung sinnvoll ist...ich weiss nur, dass beim entwickler, der fuer den ganzen kram hier verantwortlich war, alles unter myeclipse lief, auch diese weiterleitung. nun auf einmal, beim neu einrichten, leitet der nicht weiter, weil er die parameter nicht finden kann...

ich weiss, das sind recht duerftige informationen, mit denen man nich wirklich viel anfangen kann...aber so langsam hab ich hier die schnauze voll...ich sitz schon seit 2 wochen an dem problemCHen, was nun wirklich nich schwer zu loesen sein kann...aber das eclipse (europe) hier mackt auch nur rum...entweder kommt ne exception beim debuggen, dann auf einmal kann es strings nicht auslesen...dann noch dieses nervige hier:

Nov 17, 2008 2:57:21 PM org.apache.catalina.core.StandardContext reload
INFO: Reloading this Context has started

bei meinem alten eclipse (ganymede) lief der text einfach die konsole runter und blieb bis zum naechsten request stehen und hier immer dieses daemliche reload, wozu ich noch nix vernuenftiges bei google gefunden habe...

[edit]

also irgendwas muss hier total falsch eingerichtet sein...je nach dem ob ich debugge oder nicht und wo ich die breakpoints hinsetze, kommen absolut unterschiedliche exceptions, die ich ueberhaupt nich nachvollziehen kann...
daher hier mal mein setup

eclipse europa 3.3.2
apache tomcat 6.0.18
Dynamic Web Module 2.4
Java 6.0
Java Server Faces 1.1
...also alles moegliche eigentlich auf dem neuesten Stand...nebenbei noch die Fehlermeldungen/Warnungen inner Konsole

INFO: validateJarFile(C:\Users\eedmarth\workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\NCD_PRIM\WEB-INF\lib\javax.servlet.jar) - jar not loaded. See Servlet Spec 2.3, section 9.7.2. Offending class: javax/servlet/Servlet.class
log4j:WARN No appenders could be found for logger (org.apache.myfaces.webapp.StartupServletContextListener).


----------



## HLX (17. Nov 2008)

derSchmu hat gesagt.:
			
		

> hmm...um es mal so zu sagen...
> 
> es handelt sich hier nicht um MEINE variante...ich habe dieses projekt vorgelegt bekommen und soll es warten und ggf auch neue funktionen hinzufuegen. dafuer reichen meine java, jsf, odbc etc -kenntnisse voellig aus. nur blick ich das einrichten nich...bzw, den jsfkrams beim einrichten..ich weiss nicht mal, was dieser filter macht...und ob meine aenderung sinnvoll ist...ich weiss nur, dass beim entwickler, der fuer den ganzen kram hier verantwortlich war, alles unter myeclipse lief, auch diese weiterleitung. nun auf einmal, beim neu einrichten, leitet der nicht weiter, weil er die parameter nicht finden kann...


läuft es jetzt mit dem RequestDispatcher?




			
				derSchmu hat gesagt.:
			
		

> ...dann noch dieses nervige hier:
> 
> Nov 17, 2008 2:57:21 PM org.apache.catalina.core.StandardContext reload
> INFO: Reloading this Context has started


In deinem Eclipse-Workspace sollte sich ein automatisch angelegtes Projekt namens "Servers" befinden. Hier findest du die Konfiguration deiner "Eclipse-Tomcat-Instanz" unter "Tomcat vX.Y Server at localhost-config".

Öffne hier die Datei "server.xml" und scrolle nach ganz unten. In der Zeile

```
<Context docBase="MeinWebProjekt" path="/MeinWebProjekt" reloadable="true"...
```
findest du deinen Anwendungskontext. Setzte reloadable auf false.




			
				derSchmu hat gesagt.:
			
		

> eclipse europa 3.3.2
> apache tomcat 6.0.18
> Dynamic Web Module 2.4
> Java 6.0
> ...


Wenn du Dynamic Web Module 2.4 verwendest, darfst du kein javax.servlet.jar mit der Servlet Spec 2.3 verwenden.


----------



## derSchmu (18. Nov 2008)

hallo und danke nochmal fuer die antwort,

das mit dem reloadable hab ich doch glatt vergessen...stuemmt

nun das mit dem servlet hab ich nun auch behoben, in dem ich die jar aus dem libverzeichnis entfernt hat, nun wird, so denke ich, die aus den server runtime libray benutzt...

was die weiterleitung angeht,

nach der Methode vom Vorgaenger leitet der prima weiter, scheint aber dabei, wie schon gesagt wurde, den request zu verhunzen  und hat somit die Parameter nicht mehr.

Wenn ich directForward benutze (mit uri = /<project-dir>/index.jsp )

sieht der Code in der facesRedirectFilter Klasse wie folgt aus...

```
if (uri.endsWith(".jsp")) {
      int length = uri.length();
      String newAddress = uri.substring(10 , length);
      RequestDispatcher rqDispatcher= req.getRequestDispatcher(newAddress);
      rqDispatcher.forward(req,res);
    }
```

Dann leitet der auch schoen auf die index.jsp weiter und fuehrt dort in folgenden Zeilen zu einer NullPointerException:


```
Enumeration parameterList = request.getParameterNames();
String keyVal = "";
String userIDVal = "";
ValueBinding appScope = FacesContext.getCurrentInstance().getApplication().createValueBinding("#{apllicationSettings.apllicationScope}");
ValueBinding appVer = FacesContext.getCurrentInstance().getApplication().createValueBinding("#{apllicationSettings.apllicationVersion}");
```

Soweit ich es sehe, ist nun FacesContext.getCurrentInstance() == null, was nur an der Veraenderung im Filter liegen kann, vorher hat er ja da noch was gefunden...

...wie ihr wohl seht, hab ich so gut wie keinen Schimmer von der Arbeitsweise der Java Server Faces...ansonsten wuesste ich wahrscheinlich schon, warum das sich nun so verhaelt....


----------



## HLX (18. Nov 2008)

derSchmu hat gesagt.:
			
		

> Soweit ich es sehe, ist nun FacesContext.getCurrentInstance() == null, was nur an der Veraenderung im Filter liegen kann, vorher hat er ja da noch was gefunden...



Soweit ich weiß, muss vor dem Zugriff auf den FacesContext erstmal das FacesServlet angesprochen worden sein. Besser wäre es also wenn du alles über das FacesServlet abwickelst und ggf. die Weiterleitung auch über JSF machst. Falls das nicht geht, müsstest du in der doFilter()-Methode VOR deiner Weiterleitung "chain.doFilter()" aufrufen, damit erst der Servlet-Code ausgeführt wird und anschließend die Weiterleitung erfolgt.


----------



## derSchmu (18. Nov 2008)

ahja...und wie wuede eine abwicklung uebers facesServlet inkl die Weiterleitung ueber JSF aussehen...ich habe gerade so nen groben ueberblick ueber den jsf lifecycle, weiss aber absolut nicht, von wo aus dieser filter aufgerufen wird und was ich daran aendern kann...


----------



## HLX (19. Nov 2008)

derSchmu hat gesagt.:
			
		

> ahja...und wie wuede eine abwicklung uebers facesServlet inkl die Weiterleitung ueber JSF aussehen...


Wie eine HTTP-Anfrage in JSF behandelt wird findest du sicher in einem JSF-Tutorial...



			
				derSchmu hat gesagt.:
			
		

> ich habe gerade so nen groben ueberblick ueber den jsf lifecycle, weiss aber absolut nicht, von wo aus dieser filter aufgerufen wird und was ich daran aendern kann...


Bei deinem Filter handelt es sich offensichtlich um einen ServletFilter. Das ist nichts JSF-spezifisches (und gehört eigentlich auch zu den allgemeinen Java-Web-Grundlagen). Ein ServletFilter liegt im Prinzip zwischen Benutzer und Servlet und ermöglicht eine Vor- und Nachbehandlung zum Servlet.

Mehr dazu hier:
www.jsptutorial.org/content/filter


----------

