What's the difference between getRequestURI and getPathInfo methods in HttpServletRequest?

前端 未结 4 1565
礼貌的吻别
礼貌的吻别 2020-11-27 09:13

I\'m making a simple, very lightweight front-controller. I need to match request paths to different handlers (actions) in order to choose the correct one.

On my loca

相关标签:
4条回答
  • 2020-11-27 09:24

    getPathInfo() gives the extra path information after the URI, used to access your Servlet, where as getRequestURI() gives the complete URI.

    I would have thought they would be different, given a Servlet must be configured with its own URI pattern in the first place; I don't think I've ever served a Servlet from root (/).

    For example if Servlet 'Foo' is mapped to URI '/foo' then I would have thought the URI:

    /foo/path/to/resource
    

    Would result in:

    RequestURI = /foo/path/to/resource
    

    and

    PathInfo = /path/to/resource
    
    0 讨论(0)
  • 2020-11-27 09:29

    I will put a small comparison table here (just to have it somewhere):

    Servlet is mapped as /test%3F/* and the application is deployed under /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
    

    In the example above the server is running on the localhost:8480 and the name 30thh.loc was put into OS hosts file.

    Comments

    • "+" is handled as space only in the query string

    • Anchor "#a" is not transferred to the server. Only the browser can work with it.

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

    If Spring MVC is used

    • Method getPathInfo() returns null.

    • Method getServletPath() returns the part between the context path and the session ID. In the example above the value would be /test?/a?+b

    • Be careful with URL encoded parts of @RequestMapping and @RequestParam in Spring. It is buggy (current version 3.2.4) and is usually not working as expected.

    0 讨论(0)
  • 2020-11-27 09:39

    Let's break down the full URL that a client would type into their address bar to reach your servlet:

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

    The parts are:

    1. scheme: http
    2. hostname: www.example.com
    3. port: 80
    4. context path: awesome-application
    5. servlet path: path/to/servlet
    6. path info: path/info
    7. query: a=1&b=2
    8. fragment: boo

    The request URI (returned by getRequestURI) corresponds to parts 4, 5 and 6.

    (incidentally, even though you're not asking for this, the method getRequestURL would give you parts 1, 2, 3, 4, 5 and 6).

    Now:

    • part 4 (the context path) is used to select your particular application out of many other applications that may be running in the server
    • part 5 (the servlet path) is used to select a particular servlet out of many other servlets that may be bundled in your application's WAR
    • part 6 (the path info) is interpreted by your servlet's logic (e.g. it may point to some resource controlled by your servlet).
    • part 7 (the query) is also made available to your servlet using getQueryString
    • part 8 (the fragment) is not even sent to the server and is relevant and known only to the client

    The following always holds (except for URL encoding differences):

    requestURI = contextPath + servletPath + pathInfo
    

    The following example from the Servlet 3.0 specification is very helpful:


    Note: image follows, I don't have the time to recreate in HTML:

    0 讨论(0)
  • 2020-11-27 09:49

    Consider the following 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>
    

    Now, when I hit the URL http://localhost:8084/JSPTemp1/NewServlet/jhi, it will invoke NewServlet as it is mapped with the pattern described above.

    Here:

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

    We have those ones:

    • getPathInfo()

      returns
      a String, decoded by the web container, specifying extra path information that comes after the servlet path but before the query string in the request URL; or null if the URL does not have any extra path information

    • getRequestURI()

      returns
      a String containing the part of the URL from the protocol name up to the query string

    0 讨论(0)
提交回复
热议问题