Comment obtenir l'URI de la demande sans chemin de contexte?

127

La méthode request.getRequestURI () renvoie l'URI avec le chemin du contexte.

Par exemple, si l'URL de base d'une application est http://localhost:8080/myapp/(c'est-à-dire que le chemin du contexte est myapp ), et que j'appelle request.getRequestURI()pour http://localhost:8080/myapp/secure/users, elle reviendra /myapp/secure/users.

Existe-t-il un moyen d'obtenir uniquement cette partie /secure/users, c'est-à-dire l'URI sans chemin de contexte?

artisan
la source

Réponses:

158

Si vous êtes à l'intérieur d'un servlet de contrôleur frontal qui est mappé sur un modèle de préfixe, vous pouvez simplement utiliser HttpServletRequest#getPathInfo().

String pathInfo = request.getPathInfo();
// ...

En supposant que le servlet dans votre exemple est mappé /secure, alors cela retournera /usersce qui serait les informations d'intérêt unique dans un servlet de contrôleur frontal typique.

Si le servlet est cependant mappé sur un modèle de suffixe (vos exemples d'URL n'indiquent cependant pas que c'est le cas), ou lorsque vous êtes réellement à l'intérieur d'un filtre (lorsque le servlet à invoquer n'est pas encore nécessairement déterminé, donc getPathInfo()pourrait retourner null), alors votre meilleur pari est de sous-transmettre vous-même l'URI de la requête en fonction de la longueur du chemin de contexte en utilisant la Stringméthode habituelle :

HttpServletRequest request = (HttpServletRequest) req;
String path = request.getRequestURI().substring(request.getContextPath().length());
// ...
BalusC
la source
Y a-t-il une raison d'utiliser ceci au lieu de getServletPath()? J'écris un filtre et j'ai remarqué qu'il getPathInfo()retourne null, mais getServletPath()retourne le chemin moins le contexte (adapté pour passer au répartiteur de requêtes).
Jason C
@JasonC: Comme répondu, getPathInfo()renvoie null si le servlet du contrôleur frontal n'est pas mappé sur un modèle de préfixe.
BalusC
Ouais. Je voulais dire: y a-t-il une raison pour laquelle vous préférez getPathInfo à getServletPath? La plupart des autres réponses les mieux notées ici n'utilisent pas non plus getServletPath, ce qui me rend méfiant et pourquoi je me demande. J'ai un projet de servlet sur lequel je travaille et j'essaie de peaufiner mes compétences.
Jason C
1
@JasonC: le chemin du servlet est sujet à changement lorsque vous avez un framework MVC basé sur un servlet installé comme JSF ou Spring MVC. Il représentera alors le chemin interne du framework MVC (par exemple /foo.xhtmlau lieu de /foo.jsf) et non l'URI de la requête réelle (celui que l'utilisateur final verrait dans la barre d'adresse du navigateur). Dans ce cas, le chemin d'origine du servlet peut toutefois être résolu en tant qu'attribut de requête avec clé RequestDispatcher.FORWARD_SERVLET_PATH. De toute façon, la question demande explicitement l'URI de la demande (comme dans la barre d'adresse du navigateur), donc la réponse est basée sur cela.
BalusC
74
request.getRequestURI().substring(request.getContextPath().length())
fforw
la source
Impressionnant! Ceci est exactement ce que je cherchais.
artisan
4
+1 Je pense que c'est une meilleure réponse que getPathInfo en raison du fait que getPathInfo peut être nul et d'autres bizarreries. Divers code Spring fait getContextPath et le supprime de l'URI comme vous l'avez fait au lieu de getPathInfo.
Adam Gent
32

Avec Spring, vous pouvez faire:

String path = new UrlPathHelper().getPathWithinApplication(request);
James
la source
1
Bien sûr, il serait logique de conserver une instance de UrlPathHelper, par exemple en tant que variable de membre de classe ...
James
Comment pouvons-nous obtenir l'URL de mappage de la demande? Veuillez guider ici: stackoverflow.com/questions/60446807/…
Pra_A
14

getPathInfo () renvoie parfois null. Dans la documentation HttpServletRequest

Cette méthode renvoie null s'il n'y avait aucune information de chemin supplémentaire.

J'ai besoin d'obtenir le chemin du fichier sans chemin de contexte dans Filter et getPathInfo () me renvoie null. J'utilise donc une autre méthode: httpRequest.getServletPath ()

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException
{
    HttpServletRequest httpRequest = (HttpServletRequest) request;
    HttpServletResponse httpResponse = (HttpServletResponse) response;

    String newPath = parsePathToFile(httpRequest.getServletPath());
    ...

}
lukastymo
la source
8

Si vous utilisez request.getPathInfo () dans un filtre, vous semblez toujours obtenir null (au moins avec jetty).

Ce bug + réponse laconique non valide fait allusion au problème, je pense:

https://issues.apache.org/bugzilla/show_bug.cgi?id=28323

Je soupçonne que cela est lié au fait que les filtres s'exécutent avant que le servlet ne reçoive la demande. Il peut s'agir d'un bogue de conteneur ou d'un comportement attendu que je n'ai pas pu identifier.

Le contextPath est cependant disponible, donc la solution fforws fonctionne même dans les filtres. Je n'aime pas avoir à le faire à la main, mais l'implémentation est cassée ou

l'homme des outils
la source
5

Pour ce faire, vous pouvez supprimer le chemin du contexte du servelet de l'URI de la demande.

String p = request.getRequestURI();
String cp = getServletContext().getContextPath();

if (p.startsWith(cp)) {
  String.err.println(p.substring(cp.length());
}

Lisez ici .

PeterMmm
la source
-1

Peut-être que vous pouvez simplement utiliser la méthode split pour éliminer le '/ myapp' par exemple:

string[] uris=request.getRequestURI().split("/");
string uri="/"+uri[1]+"/"+uris[2];
Colin
la source
3
Cela posera un problème si je déploie mon application en tant que root et que son URL de base devient localhost: 8080 . Dans ce cas, request.getRequestURI () renverra "/ secure / user" et votre méthode de fractionnement posera problème ici. Le code ne doit pas dépendre du déploiement.
artisan