Подтвердить что ты не робот

Java. Относительный путь к файлу в веб-приложении Java.

Я хочу прочитать файл из Java-приложения. Я не хочу давать абсолютный путь к файлу. Я просто хочу поместить файл в какой-нибудь каталог моего веб-приложения.

или

Он может быть помещен вместе с .war файлом (упакованное веб-приложение).

Каков относительный путь для файла. Я попробовал ./filename.csv, но это не сработало.

========

Обновление

========

Я поставлю файл WAR (упакованное веб-приложение) моему клиенту. Это веб-приложение прочитает файл (скажем SuppliedFile.csv), который будет скопирован клиентом на сервер. Таким образом, мне нужен механизм (который будет работать независимо от того, будет ли сервер приложений распаковывать WAR или нет), чтобы веб-приложение могло читать этот файл.

Примечание: Я не использую SuppliedFile.csv в сервлет... Я использую его в простом классе Java...

4b9b3361

Ответ 1

Вам действительно нужно загрузить его из файла? Если вы поместите его по своим классам (в WEB-INF/classes), вы можете получить InputStream к нему с помощью загрузчика классов:

InputStream csv = 
   SomeClassInTheSamePackage.class.getResourceAsStream("filename.csv");

Ответ 2

Вы можете просто получить доступ к предварительно заданному пути к файлу в системе. Это предпочтительнее, так как файлы, добавленные в каталог webapp, могут быть потеряны или Webapp не может быть распакован в зависимости от конфигурации системы.

На нашем сервере мы определяем системное свойство, установленное в JVM сервера приложений, которое указывает на "домашний каталог" для внешних данных приложения. Конечно, для этого требуется изменение конфигурации сервера приложений (-DAPP_HOME =... добавлено в JVM_OPTS при запуске), мы делаем это в основном для облегчения тестирования кода за пределами контекстного сервера приложений.

Вы можете так же легко получить путь из конфигурации сервлета:

<web-app>
<context-param>
    <param-name>MyAppHome</param-name>
    <param-value>/usr/share/myapp</param-value>
</context-param>
...
</web-app>

Затем извлеките этот путь и используйте его в качестве базового пути для чтения файла, предоставленного клиентом.

public class MyAppConfig implements ServletContextListener {

    // NOTE: static references are not a great idea, shown here for simplicity
    static File appHome;
    static File customerDataFile;

    public void contextInitialized(ServletContextEvent e) {

        appHome = new File(e.getServletContext().getInitParameter("MyAppHome"));
        File customerDataFile = new File(appHome, "SuppliedFile.csv");
    }
}

class DataProcessor {
    public void processData() {
        File dataFile = MyAppConfig.customerDataFile;
        // ...
    }
}

Как я уже упоминал, наиболее вероятная проблема, с которой вы столкнулись, - это ограничения безопасности. Ничто не гарантирует, что webapps может готовить любые файлы выше своего корня webapp. Но обычно существуют простые способы предоставления исключений для определенных путей к определенным веб-приложениям.

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

Ответ 3

Если у вас есть путь к этому файлу на веб-сервере, вы можете получить реальный путь в файловой системе сервера, используя ServletContext.getRealPath(). Обратите внимание, что в каждом контейнере не гарантируется работа (поскольку контейнер не требуется для распаковки WAR файла и хранения содержимого в файловой системе, тем не менее, большинство из них). И я думаю, что это не будет работать с файлами в /WEB -INF, поскольку у них нет виртуального пути.

Альтернативой будет использование ServletContext.getResource(), который возвращает URI. Этот URI может быть URL-адресом "file:", но для этого нет никакой гарантии.

Ответ 4

Многие популярные Java-приложения, в том числе Jenkins и Nexus, используйте этот механизм:

  • Необязательно проверить контекст сервлета-param/init-param. Это позволяет настраивать несколько экземпляров webapp для каждого контейнера сервлета, используя context.xml, который можно сделать, изменив WAR или изменив настройки сервера (в случае Tomcat).

  • Проверить переменную среды (используя System.getenv), если она установлена, затем используйте эту папку в качестве папки данных приложения. например Дженкинс использует JENKINS_HOME, а Nexus использует PLEXUS_NEXUS_WORK. Это позволяет гибкую конфигурацию без каких-либо изменений в WAR.

  • В противном случае используйте подпапку внутри домашней папки пользователя, например. $HOME/.yourapp. В коде Java это будет:

    final File appFolder = new File(System.getProperty("user.home"), ".yourapp");
    

Ответ 5

Альтернативой может быть использование ServletContext.getResource(), который возвращает URI. Этот URI может быть URL-адресом "file:", но для этого нет никакой гарантии.

Вам не нужно, чтобы это был файл:... URL. Вам просто нужно, чтобы это URL-адрес, который может использовать ваша JVM. читать - и это будет.

Ответ 6

есть другой способ, если вы используете контейнер Tomcat:

String textPath = "http://localhost:8080/NameOfWebapp/resources/images/file.txt";