Had a bit of a disappointment this week, while working (from my hotel room) on Tapestry.
I've been blissfully unaware of some limitations of the URL mappings for servlets in the web.xml file. Tapestry has always had a single, simple mapping, typically to /app
and everything else went into query parameters. That's changing for 3.1 and now I'm seeing some limitations in what I can do.
I'd like to support some mappings, such as /Home.direct/border.link
. That is, the direct service, the Home page, and the component border.link.
Alas, this can't be done. The web.xml mapping <url-pattern>*.direct</url-pattern>
will not match the above path. You'd think it would (and set the path info to /border.link
) but it simply doesn't match at all.
Give how rich Apache mod_rewrite is (despite the limitation of being written in C), you'd think there would be more flexibility for matching paths to servlets in the Servlet API. I haven't read the 2.4 specs yet, do they address this? Regardless, Tapestry has an explicit goal to stay compatible with Servlet API 2.2. I suspect this can be overcome as well with container specific extensions, but that's another thing to avoid since it always leaves some people out in the cold.
One possibility is that I'll support pattern of /direct
and create a URL like /direct/Home/border.link
, but given that the page name may itself have slashes (i.e., admin/AdminMenu
or some such), this introduces unwanted ambiguities.
Alternately, map /Home
and use a URL of /Home/direct/border.link
... but suddenly, we start having a mapping for each page in the application!
In fact, I wish there was some delegate functionality in the servlet API, where application code could take over the identification of servlets for incoming paths. This would allow much richer paths. Alternately, it would be nice if the information provided in web.xml could be augmented, from Servlet.init(ServletContext)
with additional information provided by the application. This would allow us to not repeat ourselves, by having Tapestry provide mappings based on the available EngineServiceEncoder mappings.
I have no taste for bureaucracy, but I may yet need to find a place on the Servlet API expert group.
4 comments:
Howard -- yup. I often wonder who those people are in the JSRs coming up with such lame specs.
The work-around is to use a Filter-based approach, map it to /*, and then provide your own mapping file that the filter reads and determines what to do. This is how SiteMesh works.
Patrick is write, but that would require you to use Servlet 2.3 as a minimum. You could integrate something like the UrlRewriteFilter to get the functionality you're looking for. I would vote for dropping 2.2 support since Filters make developing webapps so much easier.
Besides, if you manage to get on the Expert Group and get this changed - then you'll have to require Servlet 2.5 (or whatever version they change it in). It would be nice to have Ant-style pattern matching in the <url-pattern> element.
Mikael: *.direct/* is not allowed. Servlet spec has very limited allowed patterns ... one asterisk per customer.
I couldn't agree more about servlet mappings. Having used regular expressions on a daily basis for nearly fifteen years, I fully expected there to be much more flexibility. Of course, it is always easier to point out someone else’s mistakes after the fact.
Anyway, I saw the comment about UrlRewriteFilter and thought I should put in my two cents. Recently I had the pleasure of using the filter in question for a customer project. While it certainly was not very intuitive at first and a little temperamental, the filter worked great, is very fast and a real life saver. The little usability features, like auto configuration file reloading, were icing on the cake. Hats off to Paul Tuckey for his hard work and generosity.
Post a Comment