Доступ к файлу из Classpath в приложении Spring

Доступ к файлу из Classpath в приложении Spring

1. Вступление

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

Дальнейшее чтение:

Руководство по ResourceBundle

Всегда сложно поддерживать и расширять многоязычные приложения. В этой статье рассказывается, как использовать ResourceBundle, чтобы справиться с разновидностями, которые возникают, когда вам необходимо предоставить один и тот же контент для разных культур.

Read more

Загрузить ресурс как строку весной

Узнайте, как внедрить содержимое файла ресурсов в наши bean-компоненты в виде строки, с классом Spring Resource, что очень легко.

Read more

2. ИспользуяResource

СинтерфейсResource помогает абстрагироваться от доступа к ресурсам низкого уровня. Фактически, он поддерживает обработку всех видов файловых ресурсов единообразным способом.

Начнем с рассмотрения различных методов получения экземпляраResource.

2.1. Вручную

Для доступа к ресурсу из пути к классам мы можем просто использоватьClassPathResource:

public Resource loadEmployees() {
    return new ClassPathResource("data/employees.dat");
}

По умолчаниюClassPathResource удаляет некоторый шаблон для выбора между загрузчиком классов контекста потока и системным загрузчиком классов по умолчанию.

Тем не менее, мы также можем указать загрузчик классов для использования либо непосредственно:

return new ClassPathResource("data/employees.dat", this.getClass().getClassLoader());

Или косвенно через указанный класс:

return new ClassPathResource(
  "data/employees.dat",
  Employee.class.getClassLoader());

Обратите внимание, что изResource мы можем легко перейти к стандартным представлениям Java, таким какInputStream orFile.

Еще одна вещь, на которую следует обратить внимание, это то, что описанный выше метод работает только для абсолютных путей. Если вы хотите указать относительный путь, вы можете передать второй аргументclass. Путь будет относительно этого класса:

new ClassPathResource("../../../data/employees.dat", Example.class).getFile();

Указанный выше путь к файлу относится к классуExample.

2.2. Используя@Value

Мы также можем ввестиResource с@Value:

@Value("classpath:data/resource-data.txt")
Resource resourceFile;

И@Value поддерживает и другие префиксы, напримерfile: иurl:.

2.3. Использование ResourceLoader

Или, если мы хотим лениво загрузить наш ресурс, мы можем использоватьResourceLoader:

@Autowired
ResourceLoader resourceLoader;

Затем мы получаем наш ресурс с помощьюgetResource:

public Resource loadEmployees() {
    return resourceLoader.getResource(
      "classpath:data/employees.dat");
}

Также обратите внимание, чтоResourceLoader реализуется всеми конкретнымиApplicationContexts, что означает, что мы также можем просто зависеть отApplicationContext if, который лучше подходит для нашей ситуации:

ApplicationContext context;

public Resource loadEmployees() {
    return context.getResource("classpath:data/employees.dat");
}

3. ИспользуяResourceUtils

В качестве предостережения, есть еще один способ получения ресурсов в Spring, ноResourceUtils Javadoc ясно указывает на то, что класс предназначен в основном для внутреннего использования.

Если мы видим, что использованиеResourceUtils искажает наш код:

public File loadEmployeesWithSpringInternalClass()
  throws FileNotFoundException {
    return ResourceUtils.getFile(
      "classpath:data/employees.dat");
}

Мы должны внимательно рассмотреть обоснование какit’s probably better to use one of the standard approaches above.

4. Чтение данных ресурса

Когда у нас естьResource, it, нам легко читать его содержимое. Как мы уже обсуждали, мы можем легко получить ссылкуFile илиInputStream изResource.

Представим, что у нас есть следующий файлdata/employees.dat в пути к классам:

Joe Employee,Jan Employee,James T. Employee

4.1. Чтение вFile

Теперь мы можем прочитать его содержимое, вызвавgetFile:

@Test
public void whenResourceAsFile_thenReadSuccessful()
  throws IOException {

    File resource = new ClassPathResource(
      "data/employees.dat").getFile();
    String employees = new String(
      Files.readAllBytes(resource.toPath()));
    assertEquals(
      "Joe Employee,Jan Employee,James T. Employee",
      employees);
}

Хотя заметим, что этот подходexpects the resource to be present in the filesystem and not within a jar file.

4.2. Чтение какInputStream

Предположим, однако, что наш ресурсis внутри банки.

Затем мы можем вместо этого читатьResource какInputStream:

@Test
public void whenResourceAsStream_thenReadSuccessful()
  throws IOException {
    InputStream resource = new ClassPathResource(
      "data/employees.dat").getInputStream();
    try ( BufferedReader reader = new BufferedReader(
      new InputStreamReader(resource)) ) {
        String employees = reader.lines()
          .collect(Collectors.joining("\n"));

        assertEquals("Joe Employee,Jan Employee,James T. Employee", employees);
    }
}

5. Заключение

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

И, как всегда, я опубликовал все эти примерыover on GitHub.