H
Henry Townsend
I have a fairly complex question directed at the experts out there (but
then what question isn't .
Briefly, my webapp implements a set of commands such that
http://myserver/myapp/foo corresponds to the "foo" command and will
be passed to a servlet called FooServlet. This naming convention
is strict; thus it's always possible to infer the name of the servlet
from the URL. I want to make this app user-extensible, meaning that any
user can write a BarServlet.java, compile it and install it, and voila -
a new "bar" command exists.
The above isn't hard. The problem is that adding a new servlet means
modifying the deployment descriptor. In normal usage this requires
adding <servlet-name> and <servlet-mapping> elements to web.xml for each
new servlet. This part is hard to document and explain for users, it
doesn't play well with upgrades, and it requires restarting Tomcat for
each web.xml mod. So I've set out to try to find a way around this; I
want a way for people to simply drop a BarServlet.class file into the
right directory and have a "bar" command be available from that moment
without any need to change web.xml.
The first thing I did was write a FrontDoorServlet and configure web.xml
to send all URLs matching /myapp/* to it. This can then parse the URL to
figure out what servlet to forward to. Unfortunately this doesn't help
because the getRequestDispatcher() method only works for servlets which
already have <servlet-name> and <servlet-mapping> in web.xml, so it's no
help. Meanwhile getNamedDispatcher() looks up the servlet by
<servlet-name>. So by using getNamedDispatcher() I can avoid the need
for <servlet-mapping> but not for <servlet-name>.
Next I figured I'd look into the reflection API since it will always be
true that for command "foo" I need to invoke FooServlet.doGet(). And in
fact I was able to get a reflection-based FrontDoorServlet working as
specified and I thought I was out of the woods ... unfortunately when
getServletContext() is called from the reflection-invoked servlet it
always returns null. Apparently the context is lost in the transition
from FrontDoorServlet to FooServlet.
So now I'm out of ideas. Has anyone else solved this problem? Or any
offhand thoughts pointing to a possible solution? Is there perhaps an
API for dynamically "installing" servlet names just as if they were read
from web.xml?
Thanks,
Henry Townsend
then what question isn't .
Briefly, my webapp implements a set of commands such that
http://myserver/myapp/foo corresponds to the "foo" command and will
be passed to a servlet called FooServlet. This naming convention
is strict; thus it's always possible to infer the name of the servlet
from the URL. I want to make this app user-extensible, meaning that any
user can write a BarServlet.java, compile it and install it, and voila -
a new "bar" command exists.
The above isn't hard. The problem is that adding a new servlet means
modifying the deployment descriptor. In normal usage this requires
adding <servlet-name> and <servlet-mapping> elements to web.xml for each
new servlet. This part is hard to document and explain for users, it
doesn't play well with upgrades, and it requires restarting Tomcat for
each web.xml mod. So I've set out to try to find a way around this; I
want a way for people to simply drop a BarServlet.class file into the
right directory and have a "bar" command be available from that moment
without any need to change web.xml.
The first thing I did was write a FrontDoorServlet and configure web.xml
to send all URLs matching /myapp/* to it. This can then parse the URL to
figure out what servlet to forward to. Unfortunately this doesn't help
because the getRequestDispatcher() method only works for servlets which
already have <servlet-name> and <servlet-mapping> in web.xml, so it's no
help. Meanwhile getNamedDispatcher() looks up the servlet by
<servlet-name>. So by using getNamedDispatcher() I can avoid the need
for <servlet-mapping> but not for <servlet-name>.
Next I figured I'd look into the reflection API since it will always be
true that for command "foo" I need to invoke FooServlet.doGet(). And in
fact I was able to get a reflection-based FrontDoorServlet working as
specified and I thought I was out of the woods ... unfortunately when
getServletContext() is called from the reflection-invoked servlet it
always returns null. Apparently the context is lost in the transition
from FrontDoorServlet to FooServlet.
So now I'm out of ideas. Has anyone else solved this problem? Or any
offhand thoughts pointing to a possible solution? Is there perhaps an
API for dynamically "installing" servlet names just as if they were read
from web.xml?
Thanks,
Henry Townsend