Issue
I wrote Front Controller Pattern and ran the test. Somehow request.getPathInfo() is returning null when it should return the path info.
1. HTML that calls servlet
<a href="tmp.do">Test link to invoke cool servlet</a>
2. Map the servlet in DD.
Anything that has .do extension (ex tmp.do) will invoke the servlet "Redirector"
<!-- SERVLET (centralized entry point) -->
<servlet>
<servlet-name>RedirectHandler</servlet-name>
<servlet-class>com.masatosan.redirector.Redirector</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>RedirectHandler</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
3. The servlet that takes request from *.do
public class Redirector extends HttpServlet {
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
//test - THIS RETURNS NULL!!!!
System.out.println(request.getPathInfo());
Action action = ActionFactory.getAction(request); //return action object based on request URL path
String view = action.execute(request, response); //action returns String (filename)
if(view.equals(request.getPathInfo().substring(1))) {
request.getRequestDispatcher("/WEB-INF/" + view + ".jsp").forward(request, response);
}
else {
response.sendRedirect(view);
}
}
catch(Exception e) {
throw new ServletException("Failed in service layer (ActionFactory)", e);
}
}
}//end class
The problem is that request.getPathInfo() returns null. Based on the Head First book,
The servlet life cycle moves from
"does not exist"
state to"initialized"
state (meaning ready to service client's request) beginning with its constructor. The init() always completes before the first call to service().
This tells me that somewhere between the constructor and init() method, the servlet is not-fully-grown servlet.
So, that means, by the time service() method is called, the servlet should be fully-grown servlet and request method should be able to call getPathInfo() and expect the valid value to return instead of null.
UDPATE
Very interesting. (http://forums.sun.com/thread.jspa?threadID=657991)
(HttpServletRequest - getPathInfo() )
If the URL is like below:
http://www.myserver.com/mycontext/myservlet/hello/test?paramName=value.
If you web.xml discribe the servlet pattern as /mycontext/* getPathInfo() will return myservlet/hello/test and getQueryString() will return paramName=value
(HttpServletRequest - getServletPath() )
If the URL is like below:
http://hostname.com:80/mywebapp/servlet/MyServlet/a/b;c=123?d=789
String servletPath = req.getServletPath();
It returns "/servlet/MyServlet"
Solution
@Vivien is correct. You'd like to use HttpServletRequest#getServletPath()
instead (sorry, I overlooked that bit while writing the answer which you undoubtely was reading, I've updated the answer).
To clarify: getPathInfo()
does not include servlet path as definied in web.xml
(only the path thereafter) and getServletPath()
basically returns only the servlet path as definied in web.xml
(and thus not the path thereafter). If the url pattern contains a wildcard, particularly that part is included.
Answered By - BalusC
Answer Checked By - Pedro (JavaFixing Volunteer)