我已经在使用Tomcat下运行的servlet。 我要为一些文件,我想我们可以称他们为半静态的(这改变偶尔......他们是由应用程序的另一部分更新)从外部(到WEB-APP)的目录。 我已设法通过添加以下到我的context.xml中的META-INF目录下做到这一点
<Context aliases="/working_dir=c:/apache_tomcat_working_dir" ></Context>
这工作得很好,在我的HTML我指的是文件
<img src="/myWebbApp/working_dir/fixpermin_zoom.png">
在我的WEB-INF web.xml中我让默认的服务器处理PNG文件如下
<!-- 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>
因此,这正常工作。 但我想,而不是通过编辑context.xml文件来设置从Java代码中的外部目录。
现在在init()
在servlet的方法,我可以得到ServletContext中。
ServletContext sc = getServletContext();
如果我检查这个变量sc
在调试器,我可以看到别名串几个层次深,见附件图像。 我怎样才能得到这个别名串编程? 我检查了ServletContext的文档,但我不能找到它非常有帮助。 任何帮助非常赞赏。
serveletcontext的调试视图http://choicecomp.com/javadebugging/jdebug2.png
Answer 1:
正如你可以在你的调试器看,你的上下文是Tomcat的语境对象org.apache.catalina.core.StandardContext
你可以尝试以下到Tomcat 6和下面的步骤:
StandardEngine engine = (StandardEngine) ServerFactory.getServer().findService("Catalina").getContainer();
StandardContext context = (StandardContext) engine.findChild(engine.getDefaultHost()).findChild(getServletContext().getContextPath());
Mapper mapper = context.getMapper();
现在,您可以使用添加主机别名addHostAlias(String HostName, String alias)
的映射类的方法。
mapper.addHostAlias(engine.getDefaultHost(), "myAlias");
这里是为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");
如果在映射器没有主机,请尝试以下:
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());
希望这可以帮助!
Answer 2:
我发现了另一个方法StandardContext.setAliases
。 下文中找到完整的工作代码段为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");
请在下面找到我的调试器的截图:
该代码段执行前:
代码片段执行后:
希望这是更有帮助。
Answer 3:
这是我工作的代码,这取决于不同的操作系统动态设置Tomcat7背景别名。 当然,你可以改善它
public class ContextListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
ServletContext context = sce.getServletContext();
// tomcat 7.x
try {
MBeanServer mBeanServer = MBeanServerFactory.findMBeanServer(null).get(0);
ObjectName name = new ObjectName("Catalina", "type", "Server");
Object server = mBeanServer.getAttribute(name, "managedResource");
Object service = server.getClass().getMethod("findService", String.class).invoke(server, "Catalina"); //StandardService[Catalina]
Object connectors = service.getClass().getMethod("findConnectors").invoke(service);
Object engine = service.getClass().getMethod("getContainer").invoke(service); //StandardEngine[Catalina]
Object host = Array.get(engine.getClass().getMethod("findChildren").invoke(engine), 0); //StandardHost[Catalina]
Object stdContext = Array.get(host.getClass().getMethod("findChildren").invoke(host), 0); //StandardContext[Catalina]
Object mapper = stdContext.getClass().getMethod("getMapper").invoke(stdContext);
//just a clean up step(remove the host)
Field f1 = mapper.getClass().getDeclaredField("context");
f1.setAccessible(true);
Object ct = f1.get(mapper);
Field f2 = ct.getClass().getDeclaredField("resources");
f2.setAccessible(true);
Object rs = f2.get(ct);
Field f3 = rs.getClass().getDeclaredField("dirContext");
f3.setAccessible(true);
Object dc = f3.get(rs);
mapper.getClass().getMethod("removeHost",String.class).invoke(mapper, host.getClass().getMethod("getName").invoke(host));
//add the host back with all required aliases
switch (OsCheck.getOperatingSystemType()) {
case Windows:
dc.getClass().getMethod("setAliases",String.class).invoke(dc,"/img/avatars=" + winAvatarAlias);
break;
default:
dc.getClass().getMethod("setAliases",String.class).invoke(dc,"/img/avatars=" + linuxAvatarAlias);
break;
}
String ports = "";
for (Object o :(Object[]) connectors ) {
ports = ports + (Integer)o.getClass().getMethod("getPort").invoke(o) + " ";
}
log.info("Tomcat 7.x detected, service {}, engine {}, host {}, stdContext {}, server port: {}",
service.getClass().getMethod("getName").invoke(service),
engine.getClass().getMethod("getName").invoke(engine),
host.getClass().getMethod("getName").invoke(host),
stdContext.getClass().getMethod("getDisplayName").invoke(stdContext),
ports);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Answer 4:
基于庆的做法,这里是一个上下文侦听器,对于嵌入式行家的Tomcat(v.7.0.62)的作品。
请注意区别(“雄猫”,而不是“卡特琳娜”,并没有findService(“卡塔利娜”)),因此,该方法适用于嵌入式的Tomcat。 相较于庆和,我用普通的方法,而不是反射来获得BaseDirContext对象。
最后,你要注意,你需要调用setAliases()的BaseDirContext对象上,而不是StandardContext对象! 在内部,StandardContext的setAliases()仅仅是一个二传手,而BaseDirContext的setAliases()做了很多其他的东西,让本已运行Tomcat确实注册新的别名。
import org.apache.catalina.Container;
import org.apache.catalina.Server;
import org.apache.catalina.Service;
import org.apache.catalina.core.StandardContext;
import org.apache.catalina.core.StandardEngine;
import org.apache.log4j.Logger;
import org.apache.naming.resources.BaseDirContext;
import org.apache.naming.resources.ProxyDirContext;
import javax.management.MBeanServer;
import javax.management.MBeanServerFactory;
import javax.management.ObjectName;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
public class AliasesContextListener implements ServletContextListener {
private static Logger log = Logger.getLogger(AliasesContextListener.class);
@Override
public void contextInitialized(ServletContextEvent sce) {
try {
String aliases = "/foo=C:\\bar";
//get current tomcat server, engine and context objects
MBeanServer mBeanServer = MBeanServerFactory.findMBeanServer(null).get(0);
ObjectName name = new ObjectName("Tomcat", "type", "Server");
Server server = (Server) mBeanServer.getAttribute(name, "managedResource");
Service[] services = server.findServices();
StandardEngine engine = (StandardEngine) services[0].getContainer();
Container defaultHostContainer = engine.findChild(engine.getDefaultHost());
ServletContext servletContext = sce.getServletContext();
StandardContext standardContext = (StandardContext) defaultHostContainer.findChild(servletContext.getContextPath());
ProxyDirContext proxyDirContext = (ProxyDirContext) standardContext.getResources();
BaseDirContext baseDirContext = (BaseDirContext) proxyDirContext.getDirContext();
//modify the aliases entry
baseDirContext.setAliases(aliases);
} catch (Exception e) {
log.error("error while setting aliases in context listener", e);
}
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
//not implemented
}
}
文章来源: How do I add aliases to a Servlet Context in java?