通过Spring XmlWebApplicationContext指定相对资源路径

时间:2009-07-14 03:35:37

标签: java spring spring-mvc

实际问题是:有没有办法让XmlWebApplicationContext使用相对于上下文位置的路径加载资源?为清楚起见,我们假设“上下文位置”是通过setConfigLocation()方法指定的第一个文件的位置。

详细说明如下:
我在Web层使用Spring MVC,在中间层使用Spring IOC。适当的上下文按层次结构定义,如Spring Documentation中所述:在my-servlet.xml中定义了web内容,在services.xml中定义了通过ContextLoaderListener加载的服务等。中间层可以与Web层一起部署(例如,整个操作在ServletContainer中运行)或单独部署(在这种情况下services.xmlremote-services.xml替换为定义远程存根)。除以下问题外,整个设置工作正常:

我有一些资源(其他XML文件,你有什么)与services.xml所需的文件夹相同,需要所述服务才能访问。使用相对路径将这些资源指定为services.xml中的依赖项。独立部署中间层时可以正常工作,但在部署在servlet容器中时则不行。在后一种情况下,中间层上下文被实例化为XmlWebApplicationContext,它根据servlet上下文根加载所有资源,这意味着我必须用 / WEB-INF / 作为前缀,我真的很喜欢避免。使用PropertyPlaceholderConfigurer也会出现类似的问题。

我知道我可以通过从类路径加载资源来解决这个问题,但这也不理想 - 对于独立部署,这意味着我需要将配置文件夹添加到类路径中,对于Web部署,这意味着必须在WEB下复制所有内容-INF /类。

有什么想法吗?

3 个答案:

答案 0 :(得分:3)

我最终扩展了Spring的XmlWebApplicationContext以允许相对资源路径。这就是我想要的,这使我可以使用相同的context.xml文件,无论它是作为Web应用程序的一部分还是独立部署。

对于任何感兴趣的人来源如下。它是使用SOV(Stack Overflow Voting)许可证发布的:-)这意味着只要你赞成这个答案,你就可以自由地用它做任何事情: - )

import java.io.IOException;

import org.springframework.core.io.Resource;
import org.springframework.util.StringUtils;
import org.springframework.web.context.support.XmlWebApplicationContext;

/**
 * Extends Spring's default web application context to allow relative
 * resource paths. Resources without explicitly specified URL protocol
 * and / or leading slash are loaded relative to the first location
 * from getConfigLocations().
 */

public class SpringApplicationContext extends XmlWebApplicationContext {

  @Override
  protected Resource getResourceByPath(String path) {
    path = StringUtils.cleanPath(path);
    if (path.startsWith("/") || (path.indexOf(':')>0)) {
      return super.getResourceByPath(path);
    }
    try {
      return super.getResourceByPath(getConfigLocations()[0])
        .createRelative(path);
    } catch (IOException E) {
      // failed to create relative resource - default to standard implementation
      return super.getResourceByPath(path);
    }
  } // getResourceByPath()
}

答案 1 :(得分:1)

我同意这很烦人。我通过做你的建议来解决这个问题,这就是把我的spring配置放在类路径上,所以即使我仍然使用完全限定的导入,它们也可以在任何环境下工作。

我不确定为什么你的classpath配置需要那么复杂。这些文件可以放在java源文件夹和java文件旁边,因此它们的处理方式相同。

答案 2 :(得分:1)

奇怪。您的解决方案对我不起作用。这是我的:

package dmp.springframework.web.context;

import java.io.IOException;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.util.StringUtils;
import org.springframework.web.context.support.XmlWebApplicationContext;

public class RelativeResourceXmlWebApplicationContext extends XmlWebApplicationContext {

    @Override
    protected Resource getResourceByPath(String path) {
        path = StringUtils.cleanPath(path);
        if (path.startsWith("/") || (path.contains(":"))) {
            return super.getResourceByPath(path);
        }
        try {
            String newFilename = super.getResourceByPath(getConfigLocations()[0]).getFile().getParentFile().getAbsolutePath();
            newFilename = newFilename + "/" + path;
            return new FileSystemResource(newFilename);
        } catch (IOException E) {
            // failed to create relative resource - default to standard implementation
            return super.getResourceByPath(path);
        }
    } // getResourceByPath()
}