您的位置:首页 > 移动开发 > WebAPP

WebAppRootListener使用的过程中遇到的问题

2017-02-28 13:54 253 查看
首先,先简述一下遇到的问题,在程序中看到了这样的一段代码:

String cmsRoot = System.getProperty(rootKey);


查看了一下api是这样描述的:获取用指定键描述的系统属性

百度了一下,是这样子的:

Java.versionJava
运行时环境版本
java.vendor
Java
运行时环境供应商
java.vendor.url
Java
供应商的 URL
java.home
Java
安装目录
java.vm.specification.version
Java
虚拟机规范版本
java.vm.specification.vendor
Java
虚拟机规范供应商
java.vm.specification.name
Java
虚拟机规范名称
java.vm.version
Java
虚拟机实现版本
java.vm.vendor
Java
虚拟机实现供应商
java.vm.name
Java
虚拟机实现名称
java.specification.version
Java
运行时环境规范版本
java.specification.vendor
Java
运行时环境规范供应商
java.specification.name
Java
运行时环境规范名称
java.class.version
Java
类格式版本号
java.class.path
Java
类路径
java.library.path
加载库时搜索的路径列表
java.io.tmpdir
默认的临时文件路径
java.compiler
要使用的 JIT 编译器的名称
java.ext.dirs
一个或多个扩展目录的路径
os.name
操作系统的名称
os.arch
操作系统的架构
os.version
操作系统的版本
file.separator
文件分隔符(在 UNIX 系统中是“/”)
path.separator
路径分隔符(在 UNIX 系统中是“:”)
line.separator
行分隔符(在 UNIX 系统中是“/n”)
user.name
用户的账户名称
user.home
用户的主目录
user.dir
用户的当前工作目录
根本没有我在代码中见到的这个key,然后我就在整个系统中搜这个key值,发现在web.xml中有这个key值,所以肯定是这样影响的了,如下所示:

<!-- 以Listener方式启动spring -->
<listener>
<listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>
</listener>

<context-param>
<param-name>webAppRootKey</param-name>
<param-value>shishuo.cms.root</param-value>
</context-param>

<listener>
<listener-class>org.springframework.web.util.WebAppRootListener</listener-class>
</listener>

但是好久不用了,忘记了context-param和listener之间的关系了,所以先复习一下web.xml中的context-param:

context-param用来声明应用范围(整个WEB项目)内的上下文初始化参数,这个怎么来理解呢,其实可以根据上面这个WebAppRootListener来理解,使用Eclipse打开WebAppRootListener的源码,如图:

public class WebAppRootListener implements ServletContextListener {

public void contextInitialized(ServletContextEvent event) {
WebUtils.setWebAppRootSystemProperty(event.getServletContext());
}

public void contextDestroyed(ServletContextEvent event) {
WebUtils.removeWebAppRootSystemProperty(event.getServletContext());
}

}

contextInitialized方法是实现接口ServletContextListener中的方法,通过名称我们可以很容易理解这是一个初始化的方法,打开WebUtils.setWebAppRootSystemProperty方法,如下所示:

public static void setWebAppRootSystemProperty(ServletContext servletContext) throws IllegalStateException {
Assert.notNull(servletContext, "ServletContext must not be null");
String root = servletContext.getRealPath("/");
if (root == null) {
throw new IllegalStateException(
"Cannot set web app root system property when WAR file is not expanded");
}
String param = servletContext.getInitParameter(WEB_APP_ROOT_KEY_PARAM);
String key = (param != null ? param : DEFAULT_WEB_APP_ROOT_KEY);
String oldValue = System.getProperty(key);
if (oldValue != null && !StringUtils.pathEquals(oldValue, root)) {
throw new IllegalStateException(
"Web app root system property already set to different value: '" +
key + "' = [" + oldValue + "] instead of [" + root + "] - " +
"Choose unique values for the 'webAppRootKey' context-param in your web.xml files!");
}
System.setProperty(key, root);
servletContext.log("Set web app root system property: '" + key + "' = [" + root + "]");
}

这个类和方法是Spring中web包中封装好的,所以应该是很靠谱的方法和类了,关键是这句话String param = servletContext.getInitParameter(WEB_APP_ROOT_KEY_PARAM);那么WEB_APP_ROOT_KEY_PARAM又等于什么呢,如下:

public static final String WEB_APP_ROOT_KEY_PARAM = "webAppRootKey";

原来就是我们在context-param中配置的值,这是怎么回事呢?
因为web.xml在加载的时候会按照

context-param >> listener  >> fileter  >> servlet

这个顺序来加载,所以context-param加载之后,就会保存在ServletContext的实例对象中了,getInitParameter方法可以获取到其中的值,

System.setProperty(key, root);

经过一系列的判断,最终把这里的值当作key来保存应用的路径
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: