web-dev-qa-db-fra.com

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

Je fabrique un contrôleur frontal simple et très léger. Je dois faire correspondre les chemins de demande à différents gestionnaires (actions) afin de choisir celui qui convient.

Sur mon ordinateur local HttpServletRequest.getPathInfo() et HttpServletRequest.getRequestURI() renvoient les mêmes résultats. Mais je ne suis pas sûr de ce qu'ils vont retourner dans l'environnement de production.

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

130
Roman

getPathInfo() donne les informations de chemin supplémentaires après l'URI, utilisé pour accéder à votre servlet, tandis que 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é sur l'URI '/ foo', j'aurais alors pensé que l'URI:

/foo/path/to/resource

Aboutirait à:

RequestURI = /foo/path/to/resource

et

PathInfo = /path/to/resource
71
trojanfoe

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:8480 et le nom 30thh.loc a été placé dans le fichier OS hosts.

Commentaires

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

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

  • Si le url-pattern du mappage de servlet ne se termine pas par * (par exemple /test ou *.jsp), getPathInfo() renvoie null.

Si Spring MVC est utilisé

  • La méthode getPathInfo() renvoie null.

  • La méthode getServletPath() renvoie la partie située 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 de @RequestMapping et @RequestParam au printemps. Il est bogué (version actuelle 3.2.4) et est généralement ne fonctionne pas comme prév .

416
30thh

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éma: http
  2. nom d'hôte: www.example.com
  3. port: 80
  4. chemin de contexte: awesome-application
  5. chemin de servlet: path/to/servlet
  6. chemin info: path/info
  7. requête: a=1&b=2
  8. fragment: boo

L'URI de la demande (renvoyé par getRequestURI ) correspond aux parties 4, 5 et 6.

(incidemment, même si vous ne le demandez pas, la méthode getRequestURL vous donnerait 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 pouvant être exécutées sur le serveur
  • la partie 5 (chemin de la servlet) est utilisée pour sélectionner un servlet particulier parmi de nombreux autres servlets pouvant être regroupés dans le fichier 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 sur une ressource contrôlée par votre servlet).
  • la partie 7 (la requête) est également mise à la disposition de votre servlet à l'aide de 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 tiré de Servlet 3.0 specification est très utile:


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

enter image description here

21

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 je frappe l'URL http://localhost:8084/JSPTemp1/NewServlet/jhi, il invoquera NewServlet car il est mappé avec le modèle décrit ci-dessus.

Ici:

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

Nous avons ceux-là:

  • getPathInfo()

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

  • getRequestURI()

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

16
Jigar Joshi