Apa perbedaan antara metode getRequestURI dan getPathInfo di HttpServletRequest?


143

Saya membuat front-controller yang sederhana dan sangat ringan. Saya perlu mencocokkan jalur permintaan ke penangan yang berbeda (tindakan) untuk memilih yang benar.

Di mesin lokal saya HttpServletRequest.getPathInfo()dan HttpServletRequest.getRequestURI()kembalikan hasil yang sama. Tetapi saya tidak yakin apa yang akan mereka kembalikan di lingkungan produksi.

Jadi, apa perbedaan antara metode ini dan apa yang harus saya pilih?


1
Anda mungkin menemukan jawaban ini berguna juga.
BalusC

@ BalusC: terima kasih, saya sudah menggunakan beberapa tips dari jawaban itu.
Roman

Ini menjelaskan perbedaannya dengan diagram yang bagus: agiletribe.wordpress.com/2016/02/23/...
AgilePro

Jawaban:


77

getPathInfo()memberikan informasi jalur tambahan setelah URI, digunakan untuk mengakses Servlet Anda, di mana juga getRequestURI()memberikan URI lengkap.

Saya akan berpikir mereka akan berbeda, mengingat Servlet harus dikonfigurasi dengan pola URI sendiri di tempat pertama; Saya tidak berpikir saya pernah melayani Servlet dari root (/).

Sebagai contoh jika Servlet 'Foo' dipetakan ke URI '/ foo' maka saya akan berpikir URI:

/foo/path/to/resource

Akan menghasilkan:

RequestURI = /foo/path/to/resource

dan

PathInfo = /path/to/resource

20
layak disebutkan tentang perilaku decoding. getRequestURI () tidak men-decode string. Di mana getPathInfo () melakukan decode.
Kavindu Dodanduwa

1
Dalam beberapa kasus getRequestURI()memberi saya string "/foo/path/to/resource"seperti yang diharapkan, tetapi getPathInfo()untuk HttpServletRequestobjek yang sama memberi saya null. Apa yang sedang terjadi? EDIT: Dijawab di bawah oleh pengguna "30thh".
anddero

460

Saya akan meletakkan tabel perbandingan kecil di sini (hanya untuk memilikinya di suatu tempat):

Servlet dipetakan sebagai /test%3F/*dan aplikasi ditempatkan di bawah /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

Pada contoh di atas server berjalan pada localhost:8480dan nama 30thh.locitu dimasukkan ke hostsfile OS .

Komentar

  • "+" ditangani sebagai ruang hanya dalam string kueri

  • Jangkar "#a" tidak ditransfer ke server. Hanya peramban yang dapat bekerja dengannya.

  • Jika url-patterndalam pemetaan servlet tidak diakhiri dengan *(misalnya /testatau *.jsp), getPathInfo()kembali null.

Jika Spring MVC digunakan

  • Metode getPathInfo()kembali null.

  • Metode getServletPath()mengembalikan bagian antara jalur konteks dan ID sesi. Dalam contoh di atas nilainya akan/test?/a?+b

  • Hati-hati dengan URL yang dikodekan pada @RequestMappingdan @RequestParamdi Musim Semi. Ini buggy (versi saat ini 3.2.4) dan biasanya tidak berfungsi seperti yang diharapkan .


20
Saya mencetak jawaban Anda dan memasangnya sebagai poster di kantor kami. Itu sangat berguna!
Ibrahim Arief

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

1
Saya percaya keduanya getRequestURI()dan getRequestURL()harus mengembalikan jsessionid yang tidak diterjemahkan, dalam hal ini S%3F+ID. Setidaknya itu pada Tomcat / 8.5.6.
Gediminas Rimsa

29

Mari kita uraikan URL lengkap yang akan diketik klien ke bilah alamat untuk mencapai servlet Anda:

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

Bagian-bagiannya adalah:

  1. skema: http
  2. nama host: www.example.com
  3. Pelabuhan: 80
  4. jalur konteks: awesome-application
  5. jalur servlet: path/to/servlet
  6. info jalur: path/info
  7. pertanyaan: a=1&b=2
  8. pecahan: boo

Permintaan URI (dikembalikan oleh getRequestURI ) sesuai dengan bagian 4, 5 dan 6.

(kebetulan, meskipun Anda tidak meminta ini, metode getRequestURL akan memberi Anda bagian 1, 2, 3, 4, 5 dan 6).

Sekarang:

  • bagian 4 (jalur konteks) digunakan untuk memilih aplikasi khusus Anda dari banyak aplikasi lain yang mungkin berjalan di server
  • bagian 5 (jalur servlet) digunakan untuk memilih servlet tertentu dari banyak servlet lain yang mungkin dibundel dalam PERANG aplikasi Anda
  • bagian 6 (info jalur) ditafsirkan oleh logika servlet Anda (misalnya, mungkin menunjuk ke beberapa sumber daya yang dikendalikan oleh servlet Anda).
  • bagian 7 (permintaan) juga tersedia untuk servlet Anda menggunakan getQueryString
  • bagian 8 (fragmen) bahkan tidak dikirim ke server dan relevan dan hanya diketahui oleh klien

Berikut ini selalu berlaku (kecuali untuk perbedaan penyandian URL):

requestURI = contextPath + servletPath + pathInfo

Contoh berikut dari spesifikasi Servlet 3.0 sangat membantu:


Catatan: gambar berikut, saya tidak punya waktu untuk membuat ulang dalam HTML:

masukkan deskripsi gambar di sini


16

Pertimbangkan servlet conf berikut:

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

Sekarang, ketika saya menekan URL http://localhost:8084/JSPTemp1/NewServlet/jhi, URL akan dipanggil NewServletkarena dipetakan dengan pola yang dijelaskan di atas.

Sini:

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

Kami punya yang:

  • getPathInfo()

    mengembalikan
    sebuah String, diterjemahkan oleh wadah web, menentukan informasi jalur tambahan yang datang setelah jalur servlet tetapi sebelum string kueri di URL permintaan; atau null jika URL tidak memiliki informasi jalur tambahan

  • getRequestURI()

    mengembalikan
    sebuah String yang berisi bagian dari URL dari nama protokol hingga string kueri

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.