151

The Method request.getRequestURI() returns URI with context path.

For example, if the base URL of an application is http://localhost:8080/myapp/ (i.e. the context path is myapp), and I call request.getRequestURI() for http://localhost:8080/myapp/secure/users, it will return /myapp/secure/users.

Is there any way we can get only this part /secure/users, i.e. the URI without context path?

reevesy
  • 3,452
  • 1
  • 26
  • 23
craftsman
  • 15,133
  • 17
  • 70
  • 86
  • 3
    possible duplicate of [What's the difference between getRequestURI and getPathInfo methods in HttpServletRequest?](http://stackoverflow.com/questions/4931323/whats-the-difference-between-getrequesturi-and-getpathinfo-methods-in-httpservl) – Leonel Jul 06 '12 at 18:16

7 Answers7

177

If you're inside a front contoller servlet which is mapped on a prefix pattern such as /foo/*, then you can just use HttpServletRequest#getPathInfo().

String pathInfo = request.getPathInfo();
// ...

Assuming that the servlet in your example is mapped on /secure/*, then this will return /users which would be the information of sole interest inside a typical front controller servlet.

If the servlet is however mapped on a suffix pattern such as *.foo (your URL examples however does not indicate that this is the case), or when you're actually inside a filter (when the to-be-invoked servlet is not necessarily determined yet, so getPathInfo() could return null), then your best bet is to substring the request URI yourself based on the context path's length using the usual String method:

HttpServletRequest request = (HttpServletRequest) req;
String path = request.getRequestURI().substring(request.getContextPath().length());
// ...
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • 3
    Is there a reason to use this instead of `getServletPath()`? I'm writing a filter and I noticed that `getPathInfo()` returns `null`, but `getServletPath()` returns the path minus the context (suitable for passing on to the request dispatcher). – Jason C Jun 25 '17 at 23:00
  • @JasonC: As answered, `getPathInfo()` returns null if front controller servlet is not mapped on a prefix pattern. – BalusC Jun 26 '17 at 05:41
  • Yeah. I meant: is there a reason you prefer getPathInfo over getServletPath? A lot of the other high scored answers here don't use getServletPath either, which is what's making me suspicious of it and why I'm wondering. I've got a servlet project I'm working on and I'm trying to polish off my skills bit. – Jason C Jun 26 '17 at 12:47
  • 1
    @JasonC: servlet path is subject to change when you have a servlet based MVC framework installed like JSF or Spring MVC. It will then represent the MVC framework's internal path (e.g. `/foo.xhtml` instead of `/foo.jsf`) and not the actual request URI (the one as enduser would see in browser's address bar). The original servlet path is in such case however resolveable as request attribute with key `RequestDispatcher.FORWARD_SERVLET_PATH`. In any way, the question explicitly asks for request URI (as in browser's address bar), so the answer is based on that. – BalusC Jun 26 '17 at 13:15
89
request.getRequestURI().substring(request.getContextPath().length())
fforw
  • 5,391
  • 1
  • 18
  • 17
  • 4
    +1 I think this is a better answer than getPathInfo due to the fact that getPathInfo can be null and other oddities. Various Spring code does getContextPath and removes it from the URI just as you have done instead of getPathInfo. – Adam Gent Jan 03 '12 at 14:23
40

With Spring you can do:

String path = new UrlPathHelper().getPathWithinApplication(request);
James
  • 11,654
  • 6
  • 52
  • 81
  • 1
    Of course it would make sense to keep an instance of the UrlPathHelper e.g. as a class member variable... – James Jul 31 '15 at 14:36
  • How can we get the actual request mapping url ? Please guide here: https://stackoverflow.com/questions/60446807/how-to-get-the-current-request-mapping-url-configured-at-controller-layer-when-r – PAA Feb 28 '20 at 07:47
15

getPathInfo() sometimes return null. In documentation HttpServletRequest

This method returns null if there was no extra path information.

I need get path to file without context path in Filter and getPathInfo() return me null. So I use another method: httpRequest.getServletPath()

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException
{
    HttpServletRequest httpRequest = (HttpServletRequest) request;
    HttpServletResponse httpResponse = (HttpServletResponse) response;

    String newPath = parsePathToFile(httpRequest.getServletPath());
    ...

}
lukastymo
  • 26,145
  • 14
  • 53
  • 66
9

If you use request.getPathInfo() inside a Filter, you always seem to get null (at least with jetty).

This terse invalid bug + response alludes to the issue I think:

https://issues.apache.org/bugzilla/show_bug.cgi?id=28323

I suspect it is related to the fact that filters run before the servlet gets the request. It may be a container bug, or expected behaviour that I haven't been able to identify.

The contextPath is available though, so fforws solution works even in filters. I don't like having to do it by hand, but the implementation is broken or

thetoolman
  • 2,144
  • 19
  • 11
5

A way to do this is to rest the servelet context path from request URI.

String p = request.getRequestURI();
String cp = getServletContext().getContextPath();

if (p.startsWith(cp)) {
  String.err.println(p.substring(cp.length());
}

Read here .

PeterMmm
  • 24,152
  • 13
  • 73
  • 111
-1

May be you can just use the split method to eliminate the '/myapp' for example:

string[] uris=request.getRequestURI().split("/");
string uri="/"+uri[1]+"/"+uris[2];
Colin
  • 551
  • 2
  • 10
  • 3
    This will cause problem if I deploy my application as root and its base URL becomes http://localhost:8080/. In this case request.getRequestURI() would return "/secure/user" and your split method will cause problem here. The code should not be dependent upon deployment. – craftsman Nov 25 '10 at 14:36