How to map non-jsp URL to a JSP?

2001-07-27 Thread Randall Parker


Looking at web.xml its easy to see how all .jsp files can be mapped to the JSP servlet:
  servlet-mapping
servlet-namejsp/servlet-name
url-pattern*.jsp/url-pattern
  /servlet-mapping

This relies on two things:
   1) The *.JSP suffix to specify that its a JSP.
   2) I presume that the prefix after the last forward slash of the path must be the 
particular JSP 
name to pass to the jsp servlet as a sort of argument.

Okay, but is it possible to map a particular arbitrary existing .html path to a JSP 
and have that 
JSP name not be directly from that path?

I'd like to do something like:

  servlet-mapping
servlet-namejsp/servlet-name
url-pattern/dataview/latest/*.html/url-pattern
  /servlet-mapping

I would expect that to take:
   /dataview/latest/forecast.html
and translate it to tell the jsp servlet to invoke:
   forecast.jsp 

But I'd really like to hide the real JSP names. For instance, make
   /dataview/latest/forecast.html
 map to a jsp that is
   LatestForecast.jsp

Does anyone have an example of how this is done? I've read thru the Sun servlet specs 
2.2 and 
2.3 and they don't really say that much about the nuances of doing things in web.xml. 
Even 2.3 
spec's chapter 11 doesn't say much. 







Re: How to map non-jsp URL to a JSP?

2001-07-27 Thread Craig R. McClanahan



On Fri, 27 Jul 2001, Randall Parker wrote:

 
 Looking at web.xml its easy to see how all .jsp files can be mapped to the JSP 
servlet:
   servlet-mapping
 servlet-namejsp/servlet-name
 url-pattern*.jsp/url-pattern
   /servlet-mapping
 
 This relies on two things:
1) The *.JSP suffix to specify that its a JSP.

That is the default (at least in Tomcat).  There is not necessarily any
such thing as the JSP servlet on other servlet containers.

2) I presume that the prefix after the last forward slash of the path must be the 
particular JSP 
 name to pass to the jsp servlet as a sort of argument.

That rule is part of the servlet spec's definition of valid syntax for url
patterns.

What actually happens in Tomcat (with standard mappings) is
this.  Consider a request to:

  http://localhost:8080/myapp/mydir/foo.jsp

When Tomcat processes this, it will see that it's mapped to the JSP
servlet.  Then, it will arrange that the request.getServletPath() method
returns /mydir/foo.jsp -- which is used by the JSP servlet to know what
real JSP page should be executed.  The original request has not been
rewritten in any way.

 
 Okay, but is it possible to map a particular arbitrary existing .html
 path to a JSP and have that JSP name not be directly from that path?
 
 I'd like to do something like:
 
   servlet-mapping
 servlet-namejsp/servlet-name
 url-pattern/dataview/latest/*.html/url-pattern
   /servlet-mapping
 

That's not a valid url pattern -- you can say either
/dataview/latest/* or *.html but not both.

 I would expect that to take:
/dataview/latest/forecast.html
 and translate it to tell the jsp servlet to invoke:
forecast.jsp 
 

Is that what you really want to do, or do you want to treat
forecast.html as a JSP page in spite of the fact that it has an HTML
extension?  That's what a URL mapping of *.html would do -- it would
tell Tomcat to treat all *.html pages as if they were really JSPs.
Note that the request URL is never actually changed.  All we're changing
is which servlet will respond to it (the JSP servlet instead of the
default file-serving servlet).

To do the rewrite, trick, one approach would be to run Tomcat behind
Apache and use the MOD_REWRITE module to actually modify the request
URL.  Apache would convert a URL like

  http://localhost:8080/myapp/mydir/foo.html

into

  http://localhost:8080/myapp/mydir/foo.jsp

before handing the request to Tomcat.  This can get really tricky to
set up and maintain, and rather hard for app developers to remember.  My
personal view is that it's not worth the effort.

 But I'd really like to hide the real JSP names. For instance, make
/dataview/latest/forecast.html
  map to a jsp that is
LatestForecast.jsp
 
 Does anyone have an example of how this is done? I've read thru the
 Sun servlet specs 2.2 and 2.3 and they don't really say that much
 about the nuances of doing things in web.xml. Even 2.3 spec's chapter
 11 doesn't say much.
 
 

Another approach to name hiding, although more tedious to configure if you
have lots of pages, is to take advantage of the jsp-file element in a
servlet definition.  Consider the following web.xml excerpts:

  servlet
  servlet-nameMy Hidden Page/servlet-name
  jsp-file/mydir/foo.jsp/jsp-file
  /servlet

  servlet-mapping
  servlet-nameMy Hidden Page/servlet-name
  url-pattern/hidden/url-pattern
  /servlet-mapping

Now, a request to:

  http://localhost:8080/myapp/hidden

will execute the /mydir/foo.jsp page, with nobody being the wiser.

Servlet mappings like this can be very useful in separating the logical
name of a function (for example, /listCustomers) from the physical name
of the servlet or JSP page that implements that function.  In fact, if you
do your form submits to logical names like /listCustomers, you can even
change the servlet or page that implements it, without having to change
the input form.

Model 2 (i.e. MVC) based application architectures also rely on this
approach to reduce the coupling between the business logic layer and the
presentation layer.  For example, check out the Struts Framework:

  http://jakarta.apache.org/struts

Craig McClanahan

PS:  A complete different way to hide the JSP extensions is to run your
application inside a frameset with only a single frame (or in a pop-up
window that has no location bar).  Then, the user never sees the actual
URLs -- which have no real significance anyway in a web app.  This
approach also reduces the likelihood that users will try to bookmark pages
in the middle of an app and return out of sequence.