Sự khác biệt giữa các phương thức getRequestURI và getPathInfo trong HttpServletRequest là gì?


143

Tôi đang làm một bộ điều khiển phía trước rất đơn giản. Tôi cần khớp các đường dẫn yêu cầu với các trình xử lý (hành động) khác nhau để chọn đúng đường dẫn.

Trên máy cục bộ của tôi HttpServletRequest.getPathInfo()HttpServletRequest.getRequestURI()trả lại kết quả tương tự. Nhưng tôi không chắc họ sẽ trở lại điều gì trong môi trường sản xuất.

Vậy, sự khác biệt giữa các phương pháp này và tôi nên chọn cái gì?


1
Bạn có thể thấy câu trả lời này cũng hữu ích.
BalusC

@BalusC: cảm ơn, tôi đã sử dụng một số mẹo từ câu trả lời đó.
La Mã

Điều này giải thích sự khác biệt với một sơ đồ đẹp: ag xuất sắc.wordpress.com / 2016/02/23 / từ
AgilePro

Câu trả lời:


77

getPathInfo()cung cấp thông tin đường dẫn bổ sung sau URI, được sử dụng để truy cập Servlet của bạn, trong đó getRequestURI()cung cấp URI hoàn chỉnh.

Tôi đã nghĩ rằng chúng sẽ khác nhau, do một Servlet phải được cấu hình với mẫu URI của chính nó ở vị trí đầu tiên; Tôi không nghĩ rằng tôi đã từng phục vụ một Servlet từ root (/).

Ví dụ: nếu Servlet 'Foo' được ánh xạ tới URI '/ foo' thì tôi đã nghĩ URI:

/foo/path/to/resource

Sẽ dẫn đến:

RequestURI = /foo/path/to/resource

PathInfo = /path/to/resource

20
đáng nói về hành vi giải mã. getRequestURI () không giải mã được chuỗi. Trường hợp getPathInfo () không giải mã được.
Kavindu Dodanduwa

1
Trong một số trường hợp getRequestURI()cung cấp cho tôi chuỗi "/foo/path/to/resource"như mong đợi, nhưng getPathInfo()đối với cùng một HttpServletRequestđối tượng mang lại cho tôi null. Có gì trên thế giới đang diễn ra? EDIT: Nó được trả lời dưới đây bởi người dùng "30thh".
anddero

460

Tôi sẽ đặt một bảng so sánh nhỏ ở đây (chỉ để có nó ở đâu đó):

Servlet được ánh xạ /test%3F/*và ứng dụng được triển khai theo /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

Trong ví dụ trên, máy chủ đang chạy localhost:8480và tên 30thh.locđược đặt vào hoststệp OS .

Bình luận

  • "+" được xử lý dưới dạng không gian chỉ trong chuỗi truy vấn

  • Neo "#a" không được chuyển đến máy chủ. Chỉ trình duyệt có thể làm việc với nó.

  • Nếu url-patternánh xạ trong servlet không kết thúc bằng *(ví dụ /testhoặc *.jsp), getPathInfo()trả về null.

Nếu Spring MVC được sử dụng

  • Phương thức getPathInfo()trả về null.

  • Phương thức getServletPath()trả về phần giữa đường dẫn ngữ cảnh và ID phiên. Trong ví dụ trên, giá trị sẽ là/test?/a?+b

  • Hãy cẩn thận với các phần được mã hóa URL trong @RequestMapping@RequestParamtrong Spring. Đây là lỗi (phiên bản hiện tại 3.2.4) và thường không hoạt động như mong đợi .


20
Tôi đang in câu trả lời của bạn và đưa nó lên như một poster trên văn phòng của chúng tôi. Đó là cách hữu ích!
Ibrahim Arief

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

1
Tôi tin rằng cả hai getRequestURI()getRequestURL()nên trả lại jsessionid không giải mã, trong trường hợp này S%3F+ID. Ít nhất là nó trên Tomcat / 8.5.6.
Gediminas Rimsa

29

Hãy chia nhỏ URL đầy đủ mà khách hàng sẽ nhập vào thanh địa chỉ của họ để truy cập servlet của bạn:

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

Các phần là:

  1. kế hoạch: http
  2. tên máy chủ: www.example.com
  3. Hải cảng: 80
  4. đường dẫn ngữ cảnh: awesome-application
  5. đường dẫn của servlet: path/to/servlet
  6. thông tin đường dẫn: path/info
  7. truy vấn: a=1&b=2
  8. miếng: boo

URI yêu cầu (được trả về bởi getRequestURI ) tương ứng với các phần 4, 5 và 6.

(tình cờ, mặc dù bạn không yêu cầu điều này, phương thức getRequestURL sẽ cung cấp cho bạn các phần 1, 2, 3, 4, 5 và 6).

Hiện nay:

  • phần 4 (đường dẫn ngữ cảnh) được sử dụng để chọn ứng dụng cụ thể của bạn trong số nhiều ứng dụng khác có thể đang chạy trên máy chủ
  • phần 5 (đường dẫn servlet) được sử dụng để chọn một servlet cụ thể trong số nhiều servlet khác có thể được gói trong WAR của ứng dụng của bạn
  • phần 6 (thông tin đường dẫn) được diễn giải bằng logic của servlet của bạn (ví dụ: nó có thể trỏ đến một số tài nguyên được điều khiển bởi servlet của bạn).
  • phần 7 (truy vấn) cũng được cung cấp cho servlet của bạn bằng cách sử dụng getQueryString
  • phần 8 (đoạn) thậm chí không được gửi đến máy chủ và chỉ liên quan và chỉ được biết đến với máy khách

Phần sau luôn giữ (ngoại trừ sự khác biệt về mã hóa URL):

requestURI = contextPath + servletPath + pathInfo

Ví dụ sau từ đặc tả Servlet 3.0 rất hữu ích:


Lưu ý: hình ảnh theo sau, tôi không có thời gian để tạo lại trong HTML:

nhập mô tả hình ảnh ở đây


16

Hãy xem xét các conflet sau:

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

Bây giờ, khi tôi nhấn URL http://localhost:8084/JSPTemp1/NewServlet/jhi, nó sẽ gọi NewServletkhi nó được ánh xạ với mẫu được mô tả ở trên.

Đây:

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

Chúng tôi có những cái đó:

  • getPathInfo()

    trả về
    một Chuỗi, được giải mã bởi bộ chứa web, chỉ định thông tin đường dẫn bổ sung đi sau đường dẫn servlet nhưng trước chuỗi truy vấn trong URL yêu cầu; hoặc null nếu URL không có thêm thông tin đường dẫn

  • getRequestURI()

    trả về
    một chuỗi chứa một phần của URL từ tên giao thức cho đến chuỗi truy vấn

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.