Quelle est la différence entre les méthodes getRequestURI et getPathInfo dans HttpServletRequest?

143

Je fabrique un contrôleur frontal simple et très léger. J'ai besoin de faire correspondre les chemins de requête à différents gestionnaires (actions) afin de choisir le bon.

Sur ma machine locale HttpServletRequest.getPathInfo()et HttpServletRequest.getRequestURI()renvoyer les mêmes résultats. Mais je ne suis pas sûr de ce qu'ils reviendront dans l'environnement de production.

Alors, quelle est la différence entre ces méthodes et que dois-je choisir?

romain
la source
1
Cette réponse peut également vous être utile.
BalusC
@BalusC: merci, j'ai déjà utilisé quelques astuces de cette réponse.
Roman
Cela explique la différence avec un joli diagramme: agiletribe.wordpress.com/2016/02/23/…
AgilePro

Réponses:

77

getPathInfo()donne les informations de chemin supplémentaires après l'URI, utilisées pour accéder à votre servlet, où as getRequestURI()donne l'URI complet.

J'aurais pensé qu'ils seraient différents, étant donné qu'un servlet doit être configuré avec son propre modèle d'URI en premier lieu; Je ne pense pas avoir déjà servi un servlet à partir de la racine (/).

Par exemple, si le servlet 'Foo' est mappé à l'URI '/ foo', j'aurais pensé que l'URI:

/foo/path/to/resource

Se traduirait par:

RequestURI = /foo/path/to/resource

et

PathInfo = /path/to/resource
cheval de Troie
la source
20
il convient de mentionner le comportement de décodage. getRequestURI () ne décode pas la chaîne. Où getPathInfo () décode.
Kavindu Dodanduwa
1
Dans certains cas, getRequestURI()me donne la chaîne "/foo/path/to/resource"comme prévu, mais getPathInfo()pour le même HttpServletRequestobjet me donne null. Que se passe-t-il dans le monde? EDIT: Il est répondu ci-dessous par l'utilisateur "30thh".
anddero
460

Je vais mettre un petit tableau de comparaison ici (juste pour l'avoir quelque part):

Le servlet est mappé en tant que /test%3F/*et l'application est déployée sous /app.

http://30thh.loc:8480/app/test%3F/a%3F+b;jsessionid=S%3F+ID?p+1=c+d&p+2=e+f#a

Method              URL-Decoded Result           
----------------------------------------------------
getContextPath()        no      /app
getLocalAddr()                  127.0.0.1
getLocalName()                  30thh.loc
getLocalPort()                  8480
getMethod()                     GET
getPathInfo()           yes     /a?+b
getProtocol()                   HTTP/1.1
getQueryString()        no      p+1=c+d&p+2=e+f
getRequestedSessionId() no      S%3F+ID
getRequestURI()         no      /app/test%3F/a%3F+b;jsessionid=S+ID
getRequestURL()         no      http://30thh.loc:8480/app/test%3F/a%3F+b;jsessionid=S+ID
getScheme()                     http
getServerName()                 30thh.loc
getServerPort()                 8480
getServletPath()        yes     /test?
getParameterNames()     yes     [p 2, p 1]
getParameter("p 1")     yes     c d

Dans l'exemple ci-dessus, le serveur s'exécute sur le localhost:8480et le nom a 30thh.locété mis dans le hostsfichier OS .

commentaires

  • "+" est traité comme un espace uniquement dans la chaîne de requête

  • L'ancre "#a" n'est pas transférée vers le serveur. Seul le navigateur peut fonctionner avec.

  • Si le url-patternmappage du servlet ne se termine pas par *(par exemple /testou *.jsp), getPathInfo()renvoie null.

Si Spring MVC est utilisé

  • La méthode getPathInfo()retourne null.

  • La méthode getServletPath()renvoie la partie entre le chemin de contexte et l'ID de session. Dans l'exemple ci-dessus, la valeur serait/test?/a?+b

  • Soyez prudent avec les parties encodées en URL de @RequestMappinget @RequestParamdans Spring. Il est bogué (version actuelle 3.2.4) et ne fonctionne généralement pas comme prévu .

30ème
la source
20
J'imprime votre réponse et je la mets en affiche sur notre bureau. Voilà à quel point c'est utile!
Ibrahim Arief
2
If the url-pattern in the servlet mapping does not end with * (for example /test or *.jsp), getPathInfo() returns null.brillant.
Boris Treukhov
1
Je crois que les deux getRequestURI()et getRequestURL()devrait retourner jsessionid non décodé, dans ce cas S%3F+ID. Du moins, c'est le cas sur Tomcat / 8.5.6.
Gediminas Rimsa
30

Décomposons l'URL complète qu'un client taperait dans sa barre d'adresse pour atteindre votre servlet:

http://www.example.com:80/awesome-application/path/to/servlet/path/info?a=1&b=2#boo

Les pièces sont:

  1. schème: http
  2. nom d'hôte: www.example.com
  3. Port: 80
  4. chemin de contexte: awesome-application
  5. chemin du servlet: path/to/servlet
  6. info de chemin: path/info
  7. requete: a=1&b=2
  8. fragment: boo

L'URI de la requête (retourné par getRequestURI ) correspond aux parties 4, 5 et 6.

(d'ailleurs, même si vous ne le demandez pas, la méthode getRequestURL vous donnera les parties 1, 2, 3, 4, 5 et 6).

Maintenant:

  • la partie 4 (le chemin du contexte) est utilisée pour sélectionner votre application particulière parmi de nombreuses autres applications qui peuvent être exécutées sur le serveur
  • la partie 5 (le chemin du servlet) est utilisée pour sélectionner un servlet particulier parmi de nombreux autres servlets qui peuvent être regroupés dans le WAR de votre application
  • la partie 6 (les informations de chemin) est interprétée par la logique de votre servlet (par exemple, elle peut pointer vers une ressource contrôlée par votre servlet).
  • la partie 7 (la requête) est également mise à disposition de votre servlet en utilisant getQueryString
  • la partie 8 (le fragment) n'est même pas envoyée au serveur et n'est pertinente et connue que du client

Ce qui suit est toujours valable (sauf pour les différences de codage d'URL):

requestURI = contextPath + servletPath + pathInfo

L'exemple suivant de la spécification Servlet 3.0 est très utile:


Remarque: l' image suit, je n'ai pas le temps de recréer en HTML:

entrez la description de l'image ici

Marcus Junius Brutus
la source
16

Considérez la configuration de servlet suivante:

   <servlet>
        <servlet-name>NewServlet</servlet-name>
        <servlet-class>NewServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>NewServlet</servlet-name>
        <url-pattern>/NewServlet/*</url-pattern>
    </servlet-mapping>

Maintenant, lorsque j'atteins l'URL http://localhost:8084/JSPTemp1/NewServlet/jhi, elle sera appelée NewServlettelle qu'elle est mappée avec le modèle décrit ci-dessus.

Ici:

getRequestURI() =  /JSPTemp1/NewServlet/jhi
getPathInfo() = /jhi

Nous avons ceux-là:

  • getPathInfo()

    renvoie
    une chaîne, décodée par le conteneur Web, en spécifiant des informations de chemin supplémentaires qui viennent après le chemin du servlet mais avant la chaîne de requête dans l'URL de la requête; ou null si l'URL ne contient aucune information de chemin supplémentaire

  • getRequestURI()

    renvoie
    une chaîne contenant la partie de l'URL du nom du protocole jusqu'à la chaîne de requête

Jigar Joshi
la source