This will be implementation dependent, but since many implementation use Jasper, it may well be more portable than you think. Of course, portability may not be an issue.
But the simple case is that you take the full qualified class name of "this" from within the JSP, and from that you can derive the path name. Each JSP is compiled in to a Servlet, and they each need their own unique class.
For example, in Glassfish, which uses Jasper from Tomcat/Apache:
I have a simple jsp, root.jsp:
<html>
<body>
<% out.println(this.getClass()); %>
</body>
</html>
It is in the root level of the WAR. When I run it, I get this:
class org.apache.jsp.root_jsp
When I created the directory d
, and copied the root.jsp
in to it, and executed it, I got:
class org.apache.jsp.d.root_jsp
So, you can see, that the class name for /root.jsp
is org.apache.jsp.root_jsp
. And for /d/root.jsp
, it's org.apache.jsp.d.root_jsp
.
If you remove org.apache.jsp
from the class name, convert any remaining "." to "/", and the "_" to a "." you will get:
/root.jsp
/d/root.jsp
Which effectively gets you what you want.
If you overwrite a JSP at runtime, then it'll start sticking _1 and _2 to the end, so you'll have to account for that.
But play around with this, and it should work for you, and get you where you're going.
Just keep in mind, it's not portable, it clearly works in anything with Jasper (Tomcat, TomEE, Jetty, Glassfish), but I can't say about WebLogic or WebSphere.
But, it might. The container has to map the JSP file to a class somehow, and this is an intuitive way of doing it.
So, try it and see if you can get it to work with your container.