3

I made a filter to capture HttpServletRequest sevlet path from all requests

@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain filterChain) throws IOException, ServletException {

    HttpServletRequest request = (HttpServletRequest)req;
    HttpServletResponse response = (HttpServletResponse)res;

    // debug to see the output
    String path = request.getServletPath();

    filterChain.doFilter(request, response);
}

There is a URL in jsp that has no controller or view mapped to it

<div>
    <spring:url value="/app" var="app_url" htmlEscape="true"/>
    <a href="${app_url}"><spring:message code="label_3rd_app" /></a>
</div>

However, when click on the url while debugging on the filter, I see request.getServletPath() value from two request:

/null
/null/app

My question is why request.getServletPath() never returns /app instead?

Dreamer
  • 7,333
  • 24
  • 99
  • 179

3 Answers3

8

You're getting null because

request.getServletPath();

is for Servlets, and you're doing it inside a Filter. To get it in a Filter you have to manually build it like this:

HttpServletRequest request = (HttpServletRequest) req;
String path = request.getRequestURI().substring(request.getContextPath().length());

more info why:

How to get request URI without context path?

Jonathan Laliberte
  • 2,672
  • 4
  • 19
  • 44
  • This is not an equivalent solution. getServletPath() returns the uri-decoded path "/servlet path/foo", while getRequestURI() returns an uri-encoded path "/context/servlet%20path/foo". – Sven Döring Jul 22 '19 at 13:59
1

Mr. Lalibertes solution is not working correctly as the result of getRequestURI is uri-encoded and getServletPath is not.

Better use Springs UrlPathHelper for getting the servlet path in such situations.

new org.springframework.web.util.UrlPathHelper().getPathWithinApplication(servletRequest);

This method delivers the uri-decoded servlet path as getServletPath would have - if it would'nt be null.

Sven Döring
  • 3,927
  • 2
  • 14
  • 17
1

For people coming to this question just because your context path was null (like me): I was calling request.getContextPath() in a background thread.

The request then became 'out of scope', if I understand this bug report discussion correctly: https://bugs.eclipse.org/bugs/show_bug.cgi?id=401768

Also, I know I'm not supposed to use normal threads in servlet environments, but use Executor instead. But the problem would probably remain: https://developer.jboss.org/thread/232135.

Solution was to extract all needed info from the request before handing off to background thread.

Reto Höhener
  • 5,419
  • 4
  • 39
  • 79