Указание относительного пути к ресурсу через Spring XmlWebApplicationContext - PullRequest
1 голос
/ 14 июля 2009

Фактический вопрос: есть ли способ получить XmlWebApplicationContext для загрузки ресурсов, используя пути относительно расположения контекста? Для ясности предположим, что «местоположение контекста» - это местоположение первого файла, указанного с помощью метода setConfigLocation().

Подробное объяснение ниже:
Я использую Spring MVC на веб-уровне и Spring IOC на среднем уровне. Соответствующие контексты определены иерархически, как описано в Spring Documentation : веб-контент определен в my-servlet.xml, а службы и др. Определены в services.xml, который загружается через ContextLoaderListener. Средний уровень может быть развернут либо вместе с веб-уровнем (например, все это выполняется внутри ServletContainer), либо отдельно (в этом случае services.xml заменяется remote-services.xml, определяющим удаленные заглушки). Вся установка работает отлично, за исключением следующей проблемы:

У меня есть определенные ресурсы (дополнительные файлы XML, что у вас есть), расположенные в той же папке, что и services.xml, которые должны быть доступны указанным сервисам. Эти ресурсы указаны как зависимости в services.xml с использованием относительных путей. Когда средний уровень развернут автономно, он работает нормально, но не тогда, когда он развернут в контейнере сервлета. В последнем случае контекст среднего уровня создается как XmlWebApplicationContext, который загружает все ресурсы на основе корневого контекста сервлета, а это означает, что я должен префиксировать все с / WEB-INF / , чего я действительно хотел бы избежать. Использование PropertyPlaceholderConfigurer также представляет аналогичную проблему.

Я знаю, что могу несколько обойти это, загрузив ресурсы из classpath, но это тоже не идеально - для автономного развертывания это означает, что мне нужно добавить папку конфигурации в classpath, а для веб-развертывания это означает, что все должно быть скопировано в WEB -INF / классы.

Есть идеи?

Ответы [ 3 ]

3 голосов
/ 17 июля 2009

В итоге я расширил XmlWebApplicationContext Spring, чтобы разрешить относительные пути к ресурсам. Это делает то, что я хочу, то есть позволяет мне использовать один и тот же файл context.xml независимо от того, развернут ли он как часть веб-приложения или как отдельный.

Для всех интересующихся источник доступен ниже. Он публикуется с использованием лицензии 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 голос
/ 08 ноября 2010

Странно. Ваше решение не работает для меня. Вот мой:

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()
}
1 голос
/ 14 июля 2009

Согласен, это довольно раздражает. Я справляюсь с этим, выполняя то, что вы предлагаете, и помещает мой весенний конфиг в путь к классам, поэтому, несмотря на то, что я все еще использую импорт с полной квалификацией, они работают в любой среде.

Я не уверен, почему ваш конфиг classpath должен быть таким сложным. Файлы могут находиться прямо под вашей исходной папкой java вместе с java-файлами, поэтому они обрабатываются одинаково.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...