Стандартный класс java.net.URL
и стандартные обработчики различных префиксов URL в Java, к сожалению, не достаточно подходят для обеспечения доступа ко всем низкоуровневым ресурсам. Например, не существует стандартизированной реализации URL
, которую можно использовать для получения доступа к ресурсу, который нужно получить из пути классов или относительно ServletContext
. Хотя можно зарегистрировать новые обработчики для специализированных префиксов URL
(аналогично существующим обработчикам для таких префиксов, как http:
), это обычно довольно сложно, а интерфейсу URL
все еще не будет хватает некоторых желательных функций, таких как метод проверки существования ресурса, на который указывают.
Интерфейс Resource
Интерфейс Resource
фреймворка Spring, расположенный в пакете org.springframework.core.io.
предназначен для абстрагирования доступа к низкоуровневым ресурсам. В следующем листинге кратко представлен интерфейс Resource
. Более подробную информацию см. в javadoc по Resource
.
public interface Resource extends InputStreamSource {
boolean exists();
boolean isReadable();
boolean isOpen();
boolean isFile();
URL getURL() throws IOException;
URI getURI() throws IOException;
File getFile() throws IOException;
ReadableByteChannel readableChannel() throws IOException;
long contentLength() throws IOException;
long lastModified() throws IOException;
Resource createRelative(String relativePath) throws IOException;
String getFilename();
String getDescription();
}
Как видно из определения интерфейса Resource
, он расширяет интерфейс InputStreamSource
. В следующем листинге показано определение интерфейса InputStreamSource
:
public interface InputStreamSource {
InputStream getInputStream() throws IOException;
}
Некоторыми из наиболее важных методов интерфейса Resource
являются:
-
getInputStream()
: Находит и открывает ресурс, возвращаяInputStream
для считывания из ресурса. Предполагается, что каждый вызов возвращает новыйInputStream
. Ответственность за закрытие потока лежит на вызывающем коде. -
exists()
: Возвращает булево значениеboolean
, указывающее, существует ли данный ресурс в физической форме. -
isOpen()
: Возвращает булево значениеboolean
, указывающее, представляет ли данный ресурс дескриптор (хэндл) с открытым потоком. Еслиtrue
, тоInputStream
не может быть считан несколько раз и должен быть считан только единожды, а затем закрыт, чтобы избежать утечки ресурсов. Возвращаетfalse
для всех стандартных реализаций ресурсов, за исключениемInputStreamResource
. -
getDescription()
: Возвращает описание для этого ресурса, которое будет использоваться для вывода ошибок при работе с ресурсом. Часто это полностью уточненное имя файла или фактический URL ресурса.
Другие методы позволяют получить фактический URL
или объект File
, представляющий ресурс (если базовая реализация совместима и поддерживает эту функциональность).
Некоторые реализации интерфейса Resource
также реализуют расширенный интерфейс WritableResource
для ресурса, который поддерживает запись в него.
Сам Spring широко использует абстракцию Resource
в качестве типа аргумента во многих сигнатурах методов, когда требуется какой-либо ресурс. Другие методы в некоторых API-интерфейсах Spring (например, конструкторы различных реализаций ApplicationContext
) принимают String
, которая без дополнений или в простом виде используется для создания Resource
, соответствующего данной реализации контекста, или при помощи специальных префиксов на пути к String
позволяет вызывающему коду задать создание и использование конкретной реализации Resource
.
Хотя интерфейс Resource
часто используется в Spring и самим Spring, на самом деле его очень удобно использовать в качестве общего служебного класса в собственном коде для получения доступа к ресурсам, даже если ваш код не знает о других частях Spring и не реализует их. Хотя это и привязывает ваш код к Spring, на самом деле такого рода привязка осуществляет только с этим небольшим набором служебных классов, который служит более функциональной заменой URL
и может считаться эквивалентным любой другой библиотеке, которую вы бы использовали для этой цели.
Resource
не заменяет функциональность. По мере возможности она оборачивается. Например, UrlResource
оборачивает URL и использует обернутый URL
для выполнения своей задачи.Встроенные реализации Resource
Spring включает в себя несколько встроенных реализаций Resource
:
-
UrlResource
-
ClassPathResource
-
FileSystemResource
-
PathResource
-
ServletContextResource
-
InputStreamResource
-
ByteArrayResource
Полный список реализаций Resource
, доступных в Spring, можно найти в разделе "Все известные реализации классов" в javadoc по Resource
.
UrlResource
UrlResource
оборачивает java.net.URL
и может быть использован для получения доступа к любому объекту, доступ к которому в обычных обеспечивается с помощью URL, например, к файлам, целевому элементу HTTPS, целевому элементу FTP и другому. Все URL-адреса имеют стандартизированное String
представление, поэтому для обозначения одного типа URL-адреса от другого используются соответствующие стандартизированные префиксы. К ним относятся file:
для доступа к путям файловой системы, https:
для доступа к ресурсам по протоколу HTTPS, ftp:
для доступа к ресурсам по протоколу FTP и другие.
UrlResource
создается кодом Java путем явного использования конструктора UrlResource
, но зачастую создается и неявно, если вызывать метод API-интерфейса, который принимает аргумент String
, предназначенный для представления пути. В последнем случае PropertyEditor
класса JavaBeans в конечном итоге решает, какой тип Resource
создать. Если строка пути содержит известный (имеется в виду редактору свойств) префикс (например, classpath:
), то создается соответствующий специализированный Resource
для этого префикса. Однако, если он не распознает префикс, он принимает строку за стандартную строку URL и создает UrlResource
.
ClassPathResource
Этот класс представляет ресурс, который нужно получить из classpath. Для загрузки ресурсов используется либо загрузчик контекстных классов потока, либо данный загрузчик классов, либо данный класс.
Эта реализация Resource
поддерживает разрешение как java.io.File
, если ресурс пути классов находится в файловой системе, но не для ресурсов classpath, которые находятся в jar и не были развернуты (движком сервлета или какой-либо другой средой) в файловую систему. Чтобы решить эту проблему, различные реализации Resource
всегда имеют поддержку выполнения разрешения в виде java.net.URL
.
ClassPathResource
создается в коде Java с помощью конструктора ClassPathResource
, но зачастую создается и неявно, если вызывать метод API-интерфейса, который принимает аргумент String
, предназначенный для представления пути. Для последнего случая PropertyEditor
класса JavaBeans распознает специальный префикс classpath:
в строке пути и в этом случае создает ClassPathResource
.
FileSystemResource
Это реализация Resource
, предназначенная для дескрипторов экземпляров класса java.io.File
. Он также поддерживает обработку java.nio.file.Path
, применяя стандартные для Spring преобразования путей на основе строк, но выполняя все операции через API-интерфейс java.nio.file.Files
. Для чистой поддержки на основе java.nio.path.Path
используйте вместо этого PathResource
. FileSystemResource
поддерживает разрешение и в виде File
, и в виде URL
.
PathResource
Это реализация интерфейса Resource
, предназначенная для дескрипторов java.nio.file.Path
, выполняющая все операции и преобразования через API-интерфейс Path
. Данная реализация поддерживает разрешение как File
и как URL
, а также реализует расширенный интерфейс WritableResource
. PathResource
фактически является чистой альтернативой FileSystemResource
, основанной на java.nio.path.Path
, с иной логикой работы createRelative
.
ServletContextResource
Это реализация Resource
для ресурсов ServletContext
, которая интерпретирует относительные пути в корневом каталоге соответствующего веб-приложения.
Она всегда поддерживает потоковый доступ и доступ по URL, но также предоставляет доступ по java.io.File
только в том случае, если архив веб-приложения развернут, а ресурс физически находится в файловой системе. Будет ли он развернут в файловой системе, будет ли он доступен непосредственно из JAR или откуда-то еще, например, из базы данных (что вполне возможно), на самом деле зависит от контейнера сервлетов.
InputStreamResource
InputStreamResource
– это реализация Resource
для данного InputStream
. Её следует использовать только в том случае, если не применима конкретная реализация Resource
. В частности, отдавайте предпочтение ByteArrayResource
или любой из реализаций Resource
, основанных на файлах, где это возможно.
В отличие от других реализаций Resource
, это дескриптор для уже открытого ресурса. Поэтому он возвращает true
из функции isOpen()
. Не используйте её, если вам необходимо где-то хранить дескриптор ресурса или если вам нужно считать поток несколько раз.
ByteArrayResource
Это реализация Resource
, предназначенная для заданного байтового массива. Создает ByteArrayInputStream
для заданного байтового массива.
Она полезна для загрузки содержимого из любого заданного байтового массива без необходимости использования одноразового InputStreamResource
.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ