Jaka jest różnica między metodami getRequestURI i getPathInfo w HttpServletRequest?


143

Robię prosty, bardzo lekki kontroler przedni. Muszę dopasować ścieżki żądań do różnych programów obsługi (akcji), aby wybrać właściwy.

Na moim komputerze lokalnym HttpServletRequest.getPathInfo()i HttpServletRequest.getRequestURI()zwróć te same wyniki. Ale nie jestem pewien, co zwrócą w środowisku produkcyjnym.

Jaka jest więc różnica między tymi metodami i co powinienem wybrać?


1
Ta odpowiedź może być również przydatna.
BalusC,

@BalusC: dzięki, już korzystałem z kilku wskazówek z tej odpowiedzi.
Roman

To wyjaśnia różnicę za pomocą ładnego diagramu: agiletribe.wordpress.com/2016/02/23/…
AgilePro

Odpowiedzi:


77

getPathInfo()podaje dodatkowe informacje o ścieżce po URI, używane do uzyskania dostępu do twojego serwletu, gdzie as getRequestURI()podaje pełny URI.

Pomyślałbym, że będą inne, biorąc pod uwagę, że serwlet musi być przede wszystkim skonfigurowany z własnym wzorcem URI; Nie sądzę, żebym kiedykolwiek serwował serwlet z roota (/).

Na przykład, jeśli serwlet „Foo” jest odwzorowany na URI „/ foo”, pomyślałbym, że URI:

/foo/path/to/resource

Skutkowałoby:

RequestURI = /foo/path/to/resource

i

PathInfo = /path/to/resource

20
warto wspomnieć o zachowaniu dekodowania. getRequestURI () nie dekoduje łańcucha. Gdzie getPathInfo () dekoduje.
Kavindu Dodanduwa

1
W niektórych przypadkach getRequestURI()daje mi ciąg "/foo/path/to/resource"zgodnie z oczekiwaniami, ale getPathInfo()dla tego samego HttpServletRequestobiektu daje mi null. Co się dzieje na świecie? EDYCJA: poniżej odpowiada użytkownik „30thh”.
anddero

460

Umieszczę tutaj małą tabelę porównawczą (żeby gdzieś ją mieć):

Serwlet jest mapowany jako, /test%3F/*a aplikacja jest wdrażana w ramach /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

W powyższym przykładzie serwer działa na localhost:8480i nazwa 30thh.loczostała umieszczona w hostspliku OS .

Komentarze

  • „+” jest traktowane jako spacja tylko w ciągu zapytania

  • Kotwica „#a” nie jest przesyłana na serwer. Tylko przeglądarka może z nim współpracować.

  • Jeśli url-patternw mapowaniu serwletu nie kończy się na *(na przykład /testlub *.jsp), getPathInfo()zwraca null.

Jeśli używany jest Spring MVC

  • Metoda getPathInfo()zwraca null.

  • Metoda getServletPath()zwraca część między ścieżką kontekstu a identyfikatorem sesji. W powyższym przykładzie wartością będzie/test?/a?+b

  • Bądź ostrożny z URL zakodowane części @RequestMappingi @RequestParamwiosną. Jest wadliwy (aktualna wersja 3.2.4) i zwykle nie działa zgodnie z oczekiwaniami .


20
Drukuję twoją odpowiedź i umieszczam ją jako plakat w naszym biurze. To takie przydatne!
Ibrahim Arief

2
If the url-pattern in the servlet mapping does not end with * (for example /test or *.jsp), getPathInfo() returns null.znakomity.
Boris Treukhov

1
Uważam, że oba getRequestURI()i getRequestURL()powinny w tym przypadku zwrócić nierozszyfrowaną wartość jsessionid S%3F+ID. Przynajmniej działa na Tomcat / 8.5.6.
Gediminas Rimsa

30

Podzielmy pełny adres URL, który klient wpisałby w pasku adresu, aby dotrzeć do twojego serwletu:

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

Części to:

  1. schemat: http
  2. nazwa hosta: www.example.com
  3. Port: 80
  4. ścieżka kontekstowa: awesome-application
  5. ścieżka do serwletu: path/to/servlet
  6. informacje o ścieżce: path/info
  7. pytanie: a=1&b=2
  8. fragment: boo

Identyfikator URI żądania (zwracany przez getRequestURI ) odpowiada części 4, 5 i 6.

(nawiasem mówiąc, nawet jeśli o to nie prosisz, metoda getRequestURL dostarczy Ci części 1, 2, 3, 4, 5 i 6).

Teraz:

  • część 4 (ścieżka kontekstu) służy do wyboru konkretnej aplikacji spośród wielu innych aplikacji, które mogą być uruchomione na serwerze
  • część 5 (ścieżka do serwletu) służy do wybrania określonego serwletu spośród wielu innych serwletów, które mogą być zawarte w WARIANCJI aplikacji
  • część 6 (informacja o ścieżce) jest interpretowana przez logikę twojego serwletu (np. może wskazywać na jakiś zasób kontrolowany przez twój aplet).
  • część 7 (zapytanie) jest również udostępniana Twojemu serwletowi za pomocą metody getQueryString
  • część 8 (fragment) nie jest nawet wysyłana na serwer i jest istotna i znana tylko klientowi

Zawsze obowiązuje (z wyjątkiem różnic w kodowaniu adresów URL):

requestURI = contextPath + servletPath + pathInfo

Poniższy przykład ze specyfikacji Servlet 3.0 jest bardzo pomocny:


Uwaga: obraz poniżej, nie mam czasu na odtworzenie w HTML:

wprowadź opis obrazu tutaj


16

Rozważmy następującą konfigurację serwletu:

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

Teraz, kiedy trafię na adres URL http://localhost:8084/JSPTemp1/NewServlet/jhi, zostanie wywołany NewServlettak, jak jest mapowany za pomocą wzorca opisanego powyżej.

Tutaj:

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

Mamy takie:

  • getPathInfo()

    zwraca
    String, zdekodowany przez kontener WWW, określający dodatkowe informacje o ścieżce, które pojawiają się po ścieżce serwletu, ale przed ciągiem zapytania w adresie URL żądania; lub null, jeśli adres URL nie zawiera żadnych dodatkowych informacji o ścieżce

  • getRequestURI()

    zwraca
    ciąg zawierający część adresu URL od nazwy protokołu do ciągu zapytania

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.