Was ist der Unterschied zwischen den Methoden getRequestURI und getPathInfo in HttpServletRequest?

143

Ich mache einen einfachen, sehr leichten Front-Controller. Ich muss Anforderungspfade mit verschiedenen Handlern (Aktionen) abgleichen, um den richtigen auszuwählen.

Auf meinem lokalen Computer HttpServletRequest.getPathInfo()und HttpServletRequest.getRequestURI()geben Sie die gleichen Ergebnisse zurück. Ich bin mir jedoch nicht sicher, was sie in der Produktionsumgebung zurückgeben werden.

Also, was ist der Unterschied zwischen diesen Methoden und was soll ich wählen?

römisch
quelle
1
Sie können feststellen , diese Antwort nützlich als auch.
BalusC
@ BalusC: Danke, ich habe bereits einige Tipps aus dieser Antwort verwendet.
Roman
Dies erklärt den Unterschied mit einem schönen Diagramm: agiletribe.wordpress.com/2016/02/23/…
AgilePro

Antworten:

77

getPathInfo()gibt die zusätzlichen Pfadinformationen nach dem URI an, die für den Zugriff auf Ihr Servlet verwendet werden, wobei as getRequestURI()den vollständigen URI angibt.

Ich hätte gedacht, dass sie anders sein würden, da ein Servlet zunächst mit einem eigenen URI-Muster konfiguriert werden muss. Ich glaube nicht, dass ich jemals ein Servlet von root (/) serviert habe.

Wenn beispielsweise das Servlet 'Foo' dem URI '/ foo' zugeordnet ist, hätte ich den URI gedacht:

/foo/path/to/resource

Würde ergeben zu:

RequestURI = /foo/path/to/resource

und

PathInfo = /path/to/resource
Trojaner
quelle
20
Erwähnenswert über das Dekodierungsverhalten. getRequestURI () dekodiert den String nicht. Wo getPathInfo () dekodiert.
Kavindu Dodanduwa
1
In einigen Fällen getRequestURI()gibt mir die Zeichenfolge "/foo/path/to/resource"wie erwartet, aber getPathInfo()für das gleiche HttpServletRequestObjekt gibt mir null. Was in aller Welt ist los? EDIT: Es wird unten vom Benutzer "30thh" beantwortet.
Anddero
460

Ich werde hier eine kleine Vergleichstabelle einfügen (nur um sie irgendwo zu haben):

Servlet wird zugeordnet /test%3F/*und die Anwendung wird unter bereitgestellt /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

Im obigen Beispiel läuft der Server auf dem localhost:8480und der Name 30thh.locwurde in die Betriebssystemdatei hostseingefügt.

Bemerkungen

  • "+" wird nur in der Abfragezeichenfolge als Leerzeichen behandelt

  • Der Anker "#a" wird nicht auf den Server übertragen. Nur der Browser kann damit arbeiten.

  • Wenn die url-patternZuordnung im Servlet nicht mit *(zum Beispiel /testoder *.jsp) endet , wird getPathInfo()zurückgegeben null.

Wenn Spring MVC verwendet wird

  • Methode gibt getPathInfo()zurück null.

  • Die Methode getServletPath()gibt den Teil zwischen dem Kontextpfad und der Sitzungs-ID zurück. Im obigen Beispiel wäre der Wert/test?/a?+b

  • Seien Sie vorsichtig mit URL-codierten Teilen von @RequestMappingund @RequestParamim Frühjahr. Es ist fehlerhaft (aktuelle Version 3.2.4) und funktioniert normalerweise nicht wie erwartet .

30thh
quelle
20
Ich drucke Ihre Antwort aus und hänge sie als Poster in unser Büro. So nützlich ist es!
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
Ich glaube beides getRequestURI()und getRequestURL()sollte in diesem Fall nicht entschlüsselte jsessionid zurückgeben S%3F+ID. Zumindest bei Tomcat / 8.5.6.
Gediminas Rimsa
29

Lassen Sie uns die vollständige URL aufschlüsseln, die ein Client in seine Adressleiste eingeben würde, um Ihr Servlet zu erreichen:

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

Die Teile sind:

  1. planen: http
  2. Hostname: www.example.com
  3. Hafen: 80
  4. Kontextpfad: awesome-application
  5. Servlet-Pfad: path/to/servlet
  6. Pfadinfo: path/info
  7. Abfrage: a=1&b=2
  8. Fragment: boo

Der Anforderungs-URI (von getRequestURI zurückgegeben ) entspricht den Teilen 4, 5 und 6.

( Übrigens , obwohl Sie nicht danach fragen, würde die Methode getRequestURL Ihnen die Teile 1, 2, 3, 4, 5 und 6 geben).

Jetzt:

  • Teil 4 (der Kontextpfad) wird verwendet, um Ihre bestimmte Anwendung aus vielen anderen Anwendungen auszuwählen, die möglicherweise auf dem Server ausgeführt werden
  • Teil 5 (der Servlet-Pfad) wird verwendet, um ein bestimmtes Servlet aus vielen anderen Servlets auszuwählen, die möglicherweise im WAR Ihrer Anwendung enthalten sind
  • Teil 6 (die Pfadinformationen) wird von der Logik Ihres Servlets interpretiert (z. B. kann er auf eine von Ihrem Servlet gesteuerte Ressource verweisen).
  • Teil 7 (die Abfrage) wird Ihrem Servlet auch mit getQueryString zur Verfügung gestellt
  • Teil 8 (das Fragment) wird nicht einmal an den Server gesendet und ist relevant und nur dem Client bekannt

Folgendes gilt immer (mit Ausnahme der Unterschiede bei der URL-Codierung):

requestURI = contextPath + servletPath + pathInfo

Das folgende Beispiel aus der Servlet 3.0-Spezifikation ist sehr hilfreich:


Hinweis: Das Bild folgt, ich habe keine Zeit, es in HTML neu zu erstellen:

Geben Sie hier die Bildbeschreibung ein

Marcus Junius Brutus
quelle
16

Betrachten Sie das folgende Servlet conf:

   <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>

Wenn ich jetzt auf die URL drücke http://localhost:8084/JSPTemp1/NewServlet/jhi, wird sie aufgerufen, NewServletwenn sie dem oben beschriebenen Muster zugeordnet wird.

Hier:

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

Wir haben diese:

  • getPathInfo()

    Gibt
    eine Zeichenfolge zurück, die vom Webcontainer dekodiert wird und zusätzliche Pfadinformationen angibt, die nach dem Servlet-Pfad, jedoch vor der Abfragezeichenfolge in der Anforderungs-URL stehen. oder null, wenn die URL keine zusätzlichen Pfadinformationen enthält

  • getRequestURI()

    Gibt
    eine Zeichenfolge zurück, die den Teil der URL vom Protokollnamen bis zur Abfragezeichenfolge enthält

Jigar Joshi
quelle