The standard java.net.URL
class and the standard handlers for the various URL prefixes in Java are
unfortunately not good enough to provide access to all low-level resources. For example, there is no standardized
URL
implementation that can be used to access a resource that needs to be obtained from the classpath
or relative to the ServletContext
. Although it is possible to register new handlers for specialized
URL
prefixes (similar to existing handlers for prefixes such as http:
), this is usually
quite difficult, and the URL
will still be missing some desirable features, such as a
method for checking the existence of a pointed resource.
The Resource
Interface
The
Resource
Interface of the Spring framework, located in the org.springframework.core.io
package.
is intended to abstract access to low-level resources. The following listing briefly introduces
the Resource
interface. For more information, see the javadoc at 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();
}
As you can see from the definition of the Resource
interface, it extends the InputStreamSource
interface. The following listing shows the definition of the InputStreamSource
interface:
public interface InputStreamSource {
InputStream getInputStream() throws IOException;
}
Some of the most important methods of the Resource
interface are:
getInputStream()
: Finds and opens a resource, returning anInputStream
to read from the resource. Each call is expected to return a newInputStream
. It is the responsibility of the calling code to close the stream.exists()
: Returns aboolean
value indicating whether the stream exists the given resource in physical form.isOpen()
: Returns aboolean
value indicating whether the given resource represents a handle (handle) with an open stream. Iftrue
, thenInputStream
cannot be read multiple times and should be read only once and then closed to avoid resource leakage. Returnsfalse
for all standard resource implementations exceptInputStreamResource
.getDescription()
: Returns a description for this resource, which will be used to display errors when working with the resource. This is often the fully qualified file name or the actual URL of the resource.
Other methods get the actual URL
or File
object. representing a resource (if the base
implementation is compatible and supports this functionality).
Some implementations of the
Resource
interface also implement the extended interface WritableResource
for a resource that supports writing into it.
Spring itself makes extensive use of the Resource
abstraction as an argument type in many method
signatures when some resource is required. Other methods in some Spring APIs (for example, the constructors of
various ApplicationContext
implementations) accept a String
that is used, unadded or
plain, to create a Resource
corresponding to a given context implementation, or by using special
prefixes on the path to String
allows calling code to specify the creation and use of a specific Resource
implementation.
Although the interface Resource
is often used in Spring and by Spring itself,
it's actually very convenient to use as a general utility class in your own code to access resources, even if your
code doesn't know about other parts of Spring and doesn't implement their. While this does bind your code to Spring,
it really only does this kind of binding with this small set of utility classes that serves as a more functional
replacement for URL
and can be considered equivalent to any other library you would use for this goal.
Resource
abstraction does not replace functionality.
Whenever possible, she turns around. For example, UrlResource
wraps a URL and uses the wrapped URL
to accomplish its task.
Built-in implementations of Resource
Spring includes several built-in implementations of Resource
:
UrlResource
ClassPathResource
FileSystemResource
PathResource
ServletContextResource
InputStreamResource
ByteArrayResource
Full list of Resource
implementations available in Spring, can be found in the "All known class
implementations" section of the javadoc at Resource
.
UrlResource
UrlResource
wraps java.net.URL
and can be used to access any object that would normally be
accessed using a URL, such as files, HTTPS target, target FTP and others. All URLs have a standardized
String
representation, so appropriate standardized prefixes are used to distinguish one type of URL
from another. These include file:
for accessing file system paths, https:
for accessing
resources via HTTPS, ftp:
for accessing resources via FTP protocol and others.
UrlResource
is created by Java code by explicitly using the UrlResource
constructor, but
is often created implicitly by calling an API method that takes a String
argument to represent a path.
In the latter case, the PropertyEditor
of the JavaBeans class ultimately decides what type of Resource
to create. If the path string contains a known (meaning to the property editor) prefix (for example, classpath:
),
then a corresponding specialized Resource
is created for this prefix. However, if it does not recognize
the prefix, it assumes the string is a standard URL string and creates a UrlResource
.
ClassPathResource
This class represents the resource to be retrieved from the classpath. To load resources, either the thread's context class loader, this class loader, or this class is used.
This Resource
implementation
supports resolution as java.io.File
if the classpath resource is on the filesystem, but not for
classpath resources that are in a jar and have not been deployed (by the servlet engine or some other environment)
to the filesystem. To solve this problem, various Resource
implementations always have support for
performing permission in the form of java.net.URL
.
ClassPathResource
is created in
Java code using the ClassPathResource
constructor, but is often created implicitly by calling an API
method that takes a String
argument to represent the path. For the latter case, the PropertyEditor
class of JavaBeans recognizes the special prefix classpath:
in the path string and in this case creates
a ClassPathResource
.
FileSystemResource
This is an implementation of
Resource
for handles to instances of the java.io.File
class. It also supports java.nio.file.Path
processing, using Spring's standard string-based path transformations, but performing all operations through the
java.nio.file.Files
API. For pure java.nio.path.Path
based support, use
PathResource
instead. FileSystemResource
supports both File
and
URL
resolution.
PathResource
This is an implementation of the Resource
interface targeting java.nio.file.Path
handles, performing all operations and conversions through the Path
API. This implementation supports
resolution as File
and as URL
, and also implements the extended
WritableResource
interface. PathResource
is actually a pure alternative to FileSystemResource
,
based on java.nio.path.Path
, with a different logic of createRelative
.
ServletContextResource
This is a Resource
implementation for ServletContext
resources that interprets relative
paths in the root directory of the corresponding web application.
It always supports streaming and URL access, but also provides access via java.io.File
only if the
web application archive deployed, and the resource is physically located on the file system. Whether it will be
deployed to the file system, whether it will be accessible directly from the JAR, or from somewhere else, such
as a database (which is entirely possible), really depends on the servlet container.
InputStreamResource
InputStreamResource
is the Resource
implementation for a given InputStream
.
It should only be used if a particular implementation of Resource
is not applicable. In particular,
favor ByteArrayResource
or any of the file-based Resource
implementations whenever
possible.
Unlike other Resource
implementations, this is a handle to an already open resource. So it returns
true
from the isOpen()
function. Don't use it if you need to store a resource handle
somewhere or if you need to read the stream multiple times.
ByteArrayResource
This is an implementation of Resource
targeting a given byte array. Creates a
ByteArrayInputStream
for a given byte array.
It is useful for loading content from any given byte array without having to use a one-time
InputStreamResource
.
GO TO FULL VERSION