I have two servlets (S1 and S2). S1 renders a HTML-Page which acces S2 via an URL (img src="URL"). I know the servlet name of S2, but not the URL. The URL is configured in the web.xml of course, but how can I access that from S1?
I would guess, that most implementations of the ServletConfig hold that mapping informations (org.apache.catalina.core.StandardWrapper does), but since the ServletConfig-Interface don't provides a getter, you'll have to do some tricks to get it and would bind your application to a specific implementation or application server.
Maybe you just read it from the web.xml. Just select all "servlet-mapping" Elements with the given "servlet-name" and read the "url-pattern". Since this is in the spec, that should work on ever app server out there.
EDIT:
Here is the dirty example. Getting the URL mappings using refelction:
@Override
public void init(ServletConfig config) throws ServletException {
super.init(config);
try {
Class<?> clazz = config.getClass();
Field configField = clazz.getDeclaredField("config");
configField.setAccessible(true);
StandardWrapper standardWrapper = (StandardWrapper) configField.get(config);
clazz = standardWrapper.getClass();
Field mappingsField = clazz.getDeclaredField("mappings");
mappingsField.setAccessible(true);
List<?> mappings = (List<?>) mappingsField.get(standardWrapper);
System.out.println(mappings);
}catch (Exception e) {
logger.error("", e);
}
}
That works in my JSF, Tomcat environment. The config Object is "org.apache.catalina.core.StandardWrapperFacade" and has a field called "config" which hold a "org.apache.catalina.core.StandardWrapper", which has a field called "mappings".
But as I said, this is a dirty hack!
Use:
HttpServletResponse.encodeURL(String)
Which in your case should be something like this:
response.encodeURL("/S2");
This method will take care of any URL re-writing that needs to take place to maintain session state and I think will prepend the necessary path info to the URL.
I use JSTL these days so this I'm a little rusty on that last point but if the path info isn't prepended you can get it from the request and add it yourself.
Perhaps you should supply the URL of the second servlet to the first as a servlet parameter. I realise this means encoding the URL twice in the web.xml (which I really abhor), but to avoid problems you can always build the web.xml as part of your build, and populate from a properties file.
A little bit nasty and fiddly, I appreciate, but in the absence of any cross-container API solution, perhaps it's the most pragmatic solution.