# servlet-mapping auf dynamische URLs



## Antoras (14. Dez 2009)

Hallo,

ich hab eine dynamisch URL mit der ein Servlet aufgerufen werden soll. Das Problem ist nur, dass das ganze in einer Endlosschleife endet, die mein Servlet immer und immer wieder aufruft. Wenn ich das Servlet direkt aufrufe funktioniert alles, mit einer URL-Erweiterung geht es aber nicht. Was stimmt daran nicht?

web.xml:
[XML]<servlet>
	<servlet-name>test</servlet-name>
	<servlet-class>de.example.web.DynamicUrlTest</servlet-class>
</servlet>
<servlet-mapping>
	<servlet-name>test</servlet-name>
	<url-pattern>/test/*</url-pattern>
</servlet-mapping>[/XML]

Servlet:

```
public class DynamicUrlTest extends HttpServlet {
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		req.setAttribute("test", "es geht");
		RequestDispatcher r = req.getRequestDispatcher("test.jsp");
		r.forward(req, resp);	
	}
}
```

JSP:

```
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<body>
	<c:out value="${test}" default="es geht nicht" /><br />
	<a href="test/test">link</a>
</body>
</html>
```


----------



## mvitz (15. Dez 2009)

Irgendwie hast du dich ein bisschen unklar ausgedrückt.

Was genau machst du und was genau möchtest du damit erreichen?

Evtl. solltest du anstelle von r.forward(...) lieber r.include(...) nutzen?


----------



## Antoras (15. Dez 2009)

Ich möchte erreichen, dass beim Aufruf des url-paths 
	
	
	
	





```
/test
```
 und auch aller untergeordneten searchpaths immer nur das Servlet 
	
	
	
	





```
DynamicUrlTest
```
 aufgerufen wird. Grund: Die Pfade existieren nicht und deren Inhalte müssen erst aus der DB geladen werden. Dazu muss ich aber dem Server sagen, welches Servlet er aufrufen soll wenn ein solcher Pfad eingegeben werden soll.

Dies wollte ich mit dem url-pattern 
	
	
	
	





```
/test/*
```
 erreichen.

Und noch was zum Unterschied zwischen include() und forward(): Wenn ich nur ein Servlet habe, das den Request verarbeitet (das JSP-generierte mal ausgenommen), dann macht es doch eigentlich keinen Unterschied welche Methode ich nutze, oder? Das ist doch nur wichtig wenn ich selbst mehrere Servlets aufrufe?


----------



## musiKk (15. Dez 2009)

Das Problem ist doch vielleicht, dass Du z. B. den Pfad [c]/test/gibts/nicht[/c] aufrufst und Dein Servlet macht daraus [c]/test/gibts/test.jsp[/c] (wobei ich mir da nicht sicher bin) und nochmal und nochmal. Ich habe das jetzt nicht im Kopf, wie das mit absoluten und relativen Angaben aussieht, aber hilft es vielleicht, wenn der Pfad nicht [c]test.jsp[/c], sondern [c]/test.jsp[/c] ist oder so?


----------



## Antoras (15. Dez 2009)

Ja, das Servlet ruft sich selbst immer und immer wieder auf, das hab ich auch schon festgestellt. Ich hab nur keine Ahnung warum es das macht. :bahnhof:
Wo soll ich den Pfad ändern? In der web.xml muss sowieso immer ein Slash vor der URL stehen. Und in der JSP darf kein Slash vor dem Link stehen, sonst würde ja auf das ROOT-Directory zugegriffen werden. Dann müsste ich den kompletten absoluten Pfad setzen - und das ergibt das gleiche Ergebnis.


----------



## mvitz (15. Dez 2009)

du solltest einfach auf musiKk hören...


```
...
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException,
            IOException {
        req.setAttribute("test", "es geht");
        RequestDispatcher r = req.getRequestDispatcher("/test.jsp");
        r.forward(req, resp);
    }
...
```

funktioniert bei mir einwandfrei ohne Rekursion.


----------



## Antoras (16. Dez 2009)

Ach verdammt, da steht ja nochmal was. Hab ich total übersehen. 

Ok, jetzt funktioniert es. Danke euch beiden.


----------



## Antoras (16. Dez 2009)

Ok, das geht doch noch nicht so wie ich mir das vorgestellt hatte:

Wenn ich Ressourcen zu meiner JSP hinzufügen möchte (z.B. CSS-Stylesheets) funktioniert das nur für den Pfad 
	
	
	
	





```
test
```
, nicht aber für 
	
	
	
	





```
test/test
```
. Wenn ich die Ressourcen von 
	
	
	
	





```
test/test
```
 aus laden möchte, dann lädt der Server nur eine weitere tiefere Ebene (also 
	
	
	
	





```
test/test/test
```
). 
Die URLs im HTML-Quelltext bleiben aber die gleichen (
	
	
	
	





```
test/test
```
). Wie kann ich diese andauernde Rekursion verhindern?


----------



## maki (16. Dez 2009)

> Wie kann ich diese andauernde Rekursion verhindern?


Wähle mal einen anderen Namen als "test" für alles mögliche 
testLink, testMapping, etc. pp.


----------



## mvitz (16. Dez 2009)

Oder setze den Link über c:url z.B. so:

```
...
<link rel="stylesheet" type="text/css" href="<c:url value="/test.css" />" />
...
```

Damit wird daraus immer:


```
...
<link rel="stylesheet" type="text/css" href="http://[server]/[context]/test.css" />
...
```

Dein CSS darf sich in dem Fall aber auf keinen Fall im Ordner "test" befinden.


----------



## Antoras (16. Dez 2009)

maki hat gesagt.:


> Wähle mal einen anderen Namen als "test" für alles mögliche
> testLink, testMapping, etc. pp.


Ok, werd mir Mühe geben.



mvitz hat gesagt.:


> Oder setze den Link über c:url z.B. so:
> 
> ```
> ...
> ...


Das hat super funktioniert. Danke dir. 

Jetzt hab ich nur noch ein Problem: Jedes Mal wenn ich von 
	
	
	
	





```
test/dynTest
```
 aus das Servlet aufrufe, wird die dynamische URL an den Pfad gehängt. D.h. den nächsten Pfad den ich bekommen würde, wäre 
	
	
	
	





```
test/test/dynTest
```
 usw. Wie kann ich verhindern, dass jedes Mal noch mal der url-path des Servlets zur URL hinzugefügt wird?


----------



## mvitz (16. Dez 2009)

Wenn du den <a> link auf deiner JSP Seite meinst, dann auch über <c:url>


----------



## Antoras (16. Dez 2009)

Hm, das hatte ich vorhin probiert, aber da hat das nichts gebracht. Muss ich wohl was falsch gemacht haben. :bahnhof:

Aber so wie es aussieht läuft das jetzt alles so wie ich mir das vorgestellt habe. Nochmal vielen vielen Dank an alle!

Ach ja, etwas nebensächliches: Um nochmal auf ne Frage von mir von weiter vorne zurück zu kommen:


> Und noch was zum Unterschied zwischen include() und forward(): Wenn ich nur ein Servlet habe, das den Request verarbeitet (das JSP-generierte mal ausgenommen), dann macht es doch eigentlich keinen Unterschied welche Methode ich nutze, oder? Das ist doch nur wichtig wenn ich selbst mehrere Servlets aufrufe?


----------



## mvitz (16. Dez 2009)

Also ich habe bisher immer forward benutzt. Evtl. hast du bei dem <c:url> das Value nicht mit einem beginnenden / angegeben?


----------



## Antoras (16. Dez 2009)

Das Vergessene Slashzeichen kann der Fehler gewesen sein, aber ka. Jetzt geht es auf jeden Fall und das ist die Hauprsache.


----------



## Antoras (18. Dez 2009)

Mir ist jetzt doch noch ein Fehler aufgefallen:

Vom Servlet möchte ich gern mit der Methode 
	
	
	
	





```
getRequestURI()
```
 an den Pfad kommen, damit ich den dazu gehörenden Content laden kann. Das Problem ist nur, dass mir die Methode einen falschen Pfad zurückgibt. Wenn ich in den Browser die URL 
	
	
	
	





```
server.de/test/dyn
```
 eingebe gibt mir die Methode 
	
	
	
	





```
/test/test
```
 zurück, also zwei Mal den Pfad auf den das Servlet gemapped ist.

Ich hab mir zu Testzwecken ein kleines Codebeispiel gebaut, bei dem ich kurioserweise den richtigen Pfad zurück gegeben bekomme. In meinem Webprojekt funktioniert es hingegen nicht und ich kann nicht erkennen was ich dort falsch gemacht hab. Kann sich jemand vorstellen woran dieses Problem liegen könnte?


----------



## mvitz (18. Dez 2009)

Ich habe das beim letzten mal mit:


```
request.getPathInfo();
```

gemacht.

Siehe auch: /trunk/src/java/de/hsnr/va/mm/mvc/DispatcherServlet.java - de.hsnr.va.mm - Trac


----------



## Antoras (19. Dez 2009)

Bei der Methode hatte ich zuerst das gleiche Problem, dass der Pfad, mit dem ich das Servlet aufrufe, nicht korrekt zurückgegeben wurde. Ich hab den Fehler jetzt aber gefunden:

Ich hab ein POST-Formular, das mein Servlet aufruft. Dabei hatte ich nicht bedacht, dass der Aufruf des Servlets ja auch über eine dynamische URL erfolgen muss. Hab jetzt also an den action-value den dynamisch generierten Pfad angehängt und jetzt gehts. 

Hoffe, dass das jetzt das vorerst letzte Problem war.

mfg
Antoras


----------

