El La clase estándar java.net.URL y los controladores estándar para los diversos prefijos de URL en Java desafortunadamente no son lo suficientemente buenos para proporcionar acceso a todos los recursos de bajo nivel. Por ejemplo, no existe una implementación URL estandarizada que pueda usarse para acceder a un recurso que deba obtenerse del classpath o relativo al ServletContext. Aunque es posible registrar nuevos controladores para prefijos URL especializados (similar a los controladores existentes para prefijos como http:), esto suele ser bastante difícil y el A la interfaz URL > todavía le faltarán algunas características deseables, como un método para verificar la existencia de un recurso señalado.

La interfaz Resource

La Resource Interface del marco Spring, ubicada en el paquete org.springframework.core.io. está destinada a abstraer el acceso a recursos de bajo nivel. La siguiente lista presenta brevemente la interfaz Resource. Para obtener más información, consulte el javadoc en Recurso.


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();
}

Como puede ver en la definición de la interfaz Resource, extiende el InputStreamSource interfaz. El siguiente listado muestra la definición de la interfaz InputStreamSource:


public interface InputStreamSource {
    InputStream getInputStream() throws IOException;
}

Algunos de los métodos más importantes de la interfaz Resource son:

  • getInputStream(): busca y abre un recurso, devolviendo un InputStream para leer del recurso. Se espera que cada llamada devuelva un nuevo InputStream. Es responsabilidad del código de llamada cerrar la transmisión.

  • exists(): devuelve un valor booleano que indica si la secuencia existe el recurso dado en forma física.

  • isOpen(): devuelve un valor booleano que indica si el El recurso dado representa un identificador (identificador) con una secuencia abierta. Si true, entonces InputStream no se puede leer varias veces y debe leerse solo una vez y luego cerrarse para evitar fugas de recursos. Devuelve false para todas las implementaciones de recursos estándar excepto InputStreamResource.

  • getDescription() : Devuelve una descripción para este recurso, que se utilizará para mostrar errores al trabajar con el recurso. Suele ser el nombre de archivo completo o la URL real del recurso.

Otros métodos obtienen la URL o el File archivo real. Representa un recurso (si la implementación base es compatible y admite esta funcionalidad).

Algunas implementaciones de la interfaz Resource también implementan la interfaz extendida WritableResource para un recurso que admita la escritura en él.

Spring hace un uso extensivo de la abstracción Resource como tipo de argumento en muchas firmas de métodos cuando se requiere algún recurso. Otros métodos en algunas API de Spring (por ejemplo, los constructores de varias implementaciones ApplicationContext) aceptan una String que se usa, sin agregar o sin agregar, para crear un Recurso correspondiente a una implementación de contexto determinada, o mediante el uso de prefijos especiales en la ruta a String permite llamar al código para especificar la creación y el uso de una implementación de Resource específica.

Aunque la interfaz Resource se usa a menudo en Spring y por el propio Spring, en realidad es muy conveniente usarla como una clase de utilidad general en su propio código para acceder a recursos, incluso si su código No conoce otras partes de Spring y no implementa las suyas. Si bien esto vincula su código a Spring, en realidad solo realiza este tipo de vinculación con este pequeño conjunto de clases de utilidad que sirve como un reemplazo más funcional para URL y puede considerarse equivalente a cualquier otra biblioteca que usaría para este objetivo.

La abstracción Resource no reemplaza la funcionalidad. Siempre que puede, se da vuelta. Por ejemplo, UrlResource envuelve una URL y utiliza la URL envuelta para realizar su tarea.

Implementaciones integradas de Resource

Spring incluye varias implementaciones integradas de Resource:

  • UrlResource

  • ClassPathResource

  • FileSystemResource

  • PathResource

  • ServletContextResource

  • InputStreamResource

  • ByteArrayResource

Lista completa de Las implementaciones Resource disponibles en Spring se pueden encontrar en la sección "Todas las implementaciones de clases conocidas" del javadoc en Recurso.

UrlResource

UrlResource envuelve java.net.URL y se puede utilizar para acceder a cualquier objeto al que normalmente se accedería mediante una URL, como archivos, HTTPS. objetivo, objetivo FTP y otros. Todas las URL tienen una representación String estandarizada, por lo que se utilizan prefijos estandarizados apropiados para distinguir un tipo de URL de otro. Estos incluyen file: para acceder a las rutas del sistema de archivos, https: para acceder a recursos a través de HTTPS, ftp: para acceder a recursos a través del protocolo FTP y otros.

UrlResource se crea mediante código Java utilizando explícitamente el constructor UrlResource, pero a menudo se crea implícitamente llamando a un método API que toma un argumentoString para representar una ruta. En el último caso, el PropertyEditor de la clase JavaBeans decide en última instancia qué tipo de Resource crear. Si la cadena de ruta contiene un prefijo conocido (es decir, para el editor de propiedades) (por ejemplo, classpath:), entonces se crea un Recurso especializado correspondiente para este prefijo. Sin embargo, si no reconoce el prefijo, asume que la cadena es una cadena URL estándar y crea un UrlResource.

ClassPathResource

Esta clase representa el recurso que se recuperará del classpath. Para cargar recursos, se utiliza el cargador de clases de contexto del subproceso, este cargador de clases o esta clase.

Esta implementación de Resource admite la resolución como java.io.File si el recurso classpath está en el sistema de archivos, pero no para los recursos classpath que están en un jar y no han sido implementados (por el motor de servlet o algún otro entorno) en el sistema de archivos. Para resolver este problema, varias implementaciones de Resource siempre admiten la ejecución de permisos en forma de java.net.URL.

ClassPathResource se crea en código Java utilizando el constructor ClassPathResource, pero a menudo se crea implícitamente llamando a un método API que toma un argumento String para representar la ruta. Para el último caso, la clase PropertyEditor de JavaBeans reconoce el prefijo especial classpath: en la cadena de ruta y en este caso crea un ClassPathResource.

FileSystemResource

Esta es una implementación de Resource para identificadores de instancias de java.io.File clase. También admite el procesamiento de java.nio.file.Path, utilizando las transformaciones de ruta estándar basadas en cadenas de Spring, pero realizando todas las operaciones a través de la API java.nio.file.Files. Para soporte puro basado en java.nio.path.Path, use PathResource en su lugar. FileSystemResource admite resolución File y URL.

PathResource

Esta es una implementación de la interfaz Resource dirigida a los identificadores java.nio.file.Path, realizando todas las operaciones y conversiones a través de la Path API. Esta implementación admite la resolución como File y como URL, y también implementa la interfaz extendida WritableResource. PathResource es en realidad una alternativa pura a FileSystemResource, basada en java.nio.path.Path, con una lógica diferente de createRelative .

ServletContextResource

Esta es una implementación de Resource para recursos ServletContext que interpreta rutas relativas en el directorio raíz de la aplicación web correspondiente.

Siempre admite streaming y acceso URL, pero también proporciona acceso a través de java.io.File solo si el archivo de la aplicación web implementado y el recurso está ubicado físicamente en el sistema de archivos. Si se implementará en el sistema de archivos, si se podrá acceder a él directamente desde el JAR o desde otro lugar, como una base de datos (lo cual es completamente posible), realmente depende del contenedor de servlets.

InputStreamResource

InputStreamResource es la implementación de Resource para un InputStream determinado. Sólo debe usarse si una implementación particular de Resource no es aplicable. En particular, prefiera ByteArrayResource o cualquiera de las implementaciones de Resource basadas en archivos siempre que sea posible.

A diferencia de otras implementaciones de Resource, este es un identificador de un recurso ya abierto. Entonces devuelve true de la función isOpen(). No lo use si necesita almacenar un identificador de recurso en algún lugar o si necesita leer la secuencia varias veces.

ByteArrayResource

Este es un implementación de Recurso dirigido a una matriz de bytes determinada. Crea un ByteArrayInputStream para una matriz de bytes determinada.

Es útil para cargar contenido desde cualquier matriz de bytes determinada. sin tener que utilizar un InputStreamResource único.