tags:

views:

121

answers:

3

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?

+1  A: 

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!

Tim Büthe
+1  A: 

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.

Nick Holt
One of us got the question wrong I think. I understand it like this: He wants to render URLs in a HTML page that point to a servlet with the name "S2". He needs to read the mapping for S2, because it can be anything, for example "/something/*".
Tim Büthe
Yeah, looks like it :-z To avoid hard coding a URL I'd use a servlet properties file that would specify the URL (or part of it) but I suspect the hard-coding route would work in this case.
Nick Holt
+1  A: 

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.

Brian Agnew
I ended up doing this with a similar problem. Agreed that it's hokey, but the only servlet-standards-complaint way I've found so far. I don't understand why they didn't make the servlet-mapping information part of the standard ServletConfig or ServletContext, since the web.xml format is part of the same standard.
jdmichal