avril
2006
Voila, lors de mon stage toujours, j’ai été confronté à un léger problème : Récupérer l’url de la page courante.
Oui, ça parait simple comme ca, mais je vous assure que j’ai du chercher assez bien.
En fait, avec le framework Spring, le simple getRequestURL() des objets HttpServletRequest ne renvoit malheureusement pas la bonne adresse.
Un exemple, si vous avez un controlleur qui est associé à l’adresse http://localhost:8080/monapp/search.form, et que ce controlleur renvoit vers une vue WEB-INF/jsp/resultat.jsp, il y a des chances que le getRequestUrl() renvoie quelques chose dans le genre de http://localhost:8080/monapp/WEB-INF/jsp/resultat.jsp.
Pas cool !
Après pas mal de recherche, j’ai trouvé 2 manières de récupérer l’information correcte.
À la Spring
La première manière étant de rajouter un intercepteur au bean qui gère le mapping d’url dans Spring.
Cet intercepteur sera un des premiers à récupérer l’objet HttpServletRequest, et donc à ce moment la, ce dernier possèdera encore l’url correct, non modifiée par le système « interne » de Spring.
Dès lors, il suffit de récupérer l’information via la méthode getUrlRequest(), et de sauver celle ci dans un attribut à part.
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class UrlInterceptor extends HandlerInterceptorAdapter {
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String url = request.getRequestURL().toString();
request.setAttribute("urlBySpring", url);
return true;
}
}
Et dans la page JSP, il suffira de récupérer l’attribut pour connaitre l’url exact.
Mais il faut tout de même un brin de configuration au niveau du fichier Spring de la servlet.
<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="interceptors">
<list>
<ref local="urlInterceptor"/>
</list>
</property>
<property name="mappings">
<props>
<prop key="/hello.htm">mainController</prop>
</props>
</property>
</bean>
Au filtre !! Au filtre !
Une seconde manière est d’utiliser le mécanisme des filtres apparu avec les JSP 2 ( du moins je pense ).
En fait, c’est le même principe que les intercepteurs de Spring, sauf que c’est intégré à Java/Servlet directement.
Un filtre possède une méthode doFilter, et qui récupérer les objets ServletRequest et ServletResponse, ainsi que le « prochain » filtre ( un objet FilterChain )dans le chaine des filtres ( car il peut y avoir plusieurs filtres l’un après l’autre ).
Donc dans cette méthode, il faut absolument appeller la méthode doFilter de l’objet FilterChain, car il appellera soit le prochain filtre, soit simplement la servlet qui doit traiter les requêtes.
Sinon, au niveau pratique, le code est fort ressemblant à celui de l’intercepteur précedent :
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
public class UrlFilter implements Filter {
public void destroy() {
}
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
if (servletRequest instanceof HttpServletRequest) {
HttpServletRequest request = (HttpServletRequest) servletRequest;
request.setAttribute("urlByFilter", request.getRequestURL().toString());
}
filterChain.doFilter(servletRequest, servletResponse);
}
public void init(FilterConfig filterConfig) throws ServletException {
}
}
Ici aussi, il faut configurer un peu, le fichier web.xml dans ce cas ci :
<filter-name>urlFilter</filter-name>
<filter-class>be.hikage.test.UrlFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>urlFilter</filter-name>
<url-pattern>*.htm</url-pattern>
</filter-mapping>
Exemple d’utilisation
<html>
<head><title>Jsp</title></head>
<body>
<table border="1" >
<thead>
<th>Method</th>
<th>Value</th>
</thead>
<tr >
<td >getRequestUrl</td>
<td ><%= request.getRequestURL() %></td>
</tr>
<tr >
<td >Spring Interceptor</td>
<td >${urlBySpring}</td>
</tr>
<tr >
<td >Servlet Filter</td>
<td >${urlByFilter}</td>
</tr>
</table>
</body>
</html>
Ainsi que le résultat via une page http://localhost:8080/TestDWR/index.html :
getRequestUrl http://localhost:8080/TestURL/WEB-INF/jsp/resultat.jsp Spring Interceptor http://localhost:8080/TestURL/hello.htm Servlet Filter http://localhost:8080/TestURL/hello.htm
Voila, tout ça pour juste récupérer une url.. C’est bien mais pourquoi ?
En fait, dans mon cas, c’était simplement pour fournir un lien qui permet de changer la langue du site, tout en restant sur la meme page