How do I add aliases to a Servlet Context in java?

I have a servlet running under Tomcat. I need to serve some files, I guess we can call them semi-static (which change occasionally … they are updated by another part of the app) from an external (to the WEB-APP) directory. I have managed to do this by adding the following to my context.xml in the META-INF directory

						<Context aliases="/working_dir=c:/apache_tomcat_working_dir" ></Context>
			

This works fine, in my HTML I refer to the file as

						<img src="/myWebbApp/working_dir/fixpermin_zoom.png">
			

and in my web.xml inside WEB-INF I let the default server handle png files as follows

						<!-- use default for static serving of png's, js and css, also ico --><servlet-mapping>    <servlet-name>default</servlet-name>    <url-pattern>*.png</url-pattern></servlet-mapping>
			

So this works fine. But I want to set the external directory from inside java code, not by editing the context.xml file.

Now in the init() method of the servlet I can get the ServletContext.

						    ServletContext sc =  getServletContext();
			

If I examine this variable sc in the debugger, I can see the alias string several levels deep, see the attached image. How can I get at this alias string programatically? I have checked the ServletContext docs, but i can't find it very helpful. Any help much appreciated.

debug view of serveletcontext

share|improve this question
feedback

2 Answers

As you can see in your debugger, your context is Tomcat's Context Object org.apache.catalina.core.StandardContext

You can try following steps in Tomcat 6 and below:

						    StandardEngine engine = (StandardEngine) ServerFactory.getServer().findService("Catalina").getContainer();    StandardContext context = (StandardContext) engine.findChild(engine.getDefaultHost()).findChild(getServletContext().getContextPath());    Mapper mapper = context.getMapper();
			

Now you can add Host alias using addHostAlias(String HostName, String alias) method of the Mapper class.

						    mapper.addHostAlias(engine.getDefaultHost(), "myAlias");
			

Here is the code snippet for Tomcat 7:

						    MBeanServer mBeanServer = MBeanServerFactory.findMBeanServer(null).get(0);    ObjectName name = new ObjectName("Catalina", "type", "Server");    Server server = (Server) mBeanServer.getAttribute(name, "managedResource");    StandardEngine engine = (StandardEngine) server.findService("Catalina").getContainer();    StandardContext context = (StandardContext) engine.findChild(engine.getDefaultHost()).findChild(getServletContext().getContextPath());    Mapper mapper = context.getMapper();    mapper.addHostAlias(engine.getDefaultHost(), "myAlias");
			

If there is no host in the mapper, please try below:

						    MBeanServer mBeanServer = MBeanServerFactory.findMBeanServer(null).get(0);    ObjectName name = new ObjectName("Catalina", "type", "Server");    Server server = (Server) mBeanServer.getAttribute(name, "managedResource");    StandardEngine engine = (StandardEngine) server.findService("Catalina").getContainer();    StandardContext context = (StandardContext) engine.findChild(engine.getDefaultHost()).findChild(getServletContext().getContextPath());    Mapper mapper = context.getMapper();    //just a clean up step(remove the host)    mapper.removeHost(engine.getDefaultHost());    //add the host back with all required aliases     mapper.addHost(engine.getDefaultHost(), new String[]{"myAlias"}, engine.getDefaultHost());
			

Hope this helps!

share|improve this answer
thanks for the answer, but this does not work for me on Tomcat 7. I have checked in the debugger and the aliases section stays the same after the addHostAlias call. BTW where did you find this info? Is there a good tutorial on the Tomcat server internals, or are you browsing Tomcats source javadoc or what?Paulus Oct 4 '12 at 10:19
This is working code. Please try the last section in my updated answer.Yogendra Singh Oct 4 '12 at 12:09
Thanks again, but this still does not work. Where are you calling this snippet of code? Inside the servlet Init() function? How do you know that this works? can you see the change in the context aliases member in the debugger? Does the server find the files you are serving up? I have put dummy names into my aliases in my context.xml file, then the alias I try adding by your method:a) dont show up in the debugger, and b) the servelet fails to serve the static files from my working dirPaulus Oct 4 '12 at 13:05
Yes. I am using Tamcat 7.0.30 and calling this code snippet on doGet method of my test servlet. In my debugger, before this code snippet is executed, I can see there is no alias assigned(in my case, there was no host either). After the execution, I can see that host is added with given aliases.Yogendra Singh Oct 4 '12 at 13:16
feedback

I found another method StandardContext.setAliases. Find below the full working code snippet for Tomcat 7.0.30.

						        MBeanServer mBeanServer = MBeanServerFactory.findMBeanServer(null).get(0);        
			
			ObjectName name = new ObjectName("Catalina", "type", "Server");        
			
			Server server = (Server) mBeanServer.getAttribute(name, "managedResource");        
			
			StandardEngine engine = (StandardEngine) server.findService("Catalina").getContainer();        
			
			StandardContext context = (StandardContext) engine.findChild(engine.getDefaultHost()).findChild(getServletContext().getContextPath());       
			
			 context.setAliases("myAlias");        
			
			//infact aliases should be proper e.g. below         
			
			//context.setAliases("/aliasPath1=docBase1,/aliasPath2=docBase2");        
			
			Mapper mapper = context.getMapper();        
			
			mapper.removeHost(engine.getDefaultHost());        
			
			mapper.addHost(engine.getDefaultHost(), new String[]{"myAlias"}, engine.getDefaultHost());       
			
			 mapper.addHostAlias(engine.getDefaultHost(), "myAlias");       
			
			 //infact aliases should be proper e.g. below         
			
			//mapper.addHostAlias(engine.getDefaultHost(), "/aliasPath1=docBase1,/aliasPath2=docBase2");
			

Please find my debugger screenshots below:

Before the code snippet execution:enter image description hereenter image description here

After the code snippet execution:enter image description hereenter image description here

Hope this is more helpful.

share|improve this answer
Hi Yogendra, thanks that function context.SetAliases(… does definitely change the aliases that I see in the debugger. However my servlet is still not serving up the static files from my aliased directory. I have the same alias string that previously worked for me in the context.xml file. I presume that the lines of code referring to mapper are now no longer necessary? Where are you finding the info or docs for this? Thanks againPaulus Oct 4 '12 at 16:29
Primarily I referred Javadocs. This is what it says: "Set the current alias configuration. The list of aliases should be of the form "/aliasPath1=docBase1,/aliasPath2=docBase2" where aliasPathN must include a leading '/' and docBaseN must be an absolute path to either a .war file or a directory."Yogendra Singh Oct 4 '12 at 17:06
feedback