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-name>jsp</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-name>jsp</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-name>My Hidden Page</servlet-name>
      <jsp-file>/mydir/foo.jsp</jsp-file>
  </servlet>

  <servlet-mapping>
      <servlet-name>My 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.


Reply via email to