不幸的是,Java的标准Java.net.URL类和各种URL前缀的标准处理程序对于所有对低级资源的访问来说都不够充分。例如,没有标准化的URL实现可以用于访问需要从类路径或相对于Servlet上下文获得的资源。虽然可以为专用URL前缀注册新的处理程序(类似于http:等前缀的现有处理程序),但这通常相当复杂,并且URL接口仍然缺乏一些所需的功能,例如检查所指向的资源是否存在的方法。
Java的标准Java.net.URL 类和各种URL前缀的标准处理程序对于所有对低级资源的访问来说都不够充分,基于此,Spring 的 org.springframework.core.io.Resource 接口旨在成为一个更强大的接口,用于抽象对低级资源的访问,有关Resource接口的更多详细信息,参考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 接口的最核心方法如下:
注:
资源抽象不会取代功能。它尽可能地将其包裹起来。例如,UrlResource包装了一个URL,并使用包装后的URL来完成其工作。
Resource 一些常见接口:
类型 | 接口 |
---|---|
输入流 | org.springframework.core.io.InputStreamSource |
只读资源 | org.springframework.core.io.Resource |
可写资源 | org.springframework.core.io.WritableResource |
编码资源 | org.springframework.core.io.support.EncodedResource |
上下文资源 | org.springframework.core.io.ContextResource |
图解关系如下:
Resource 接口的优缺点:
优点
缺点:
Spring 包含几个内置Resource实现:
资源来源 | 前缀 | 描述 |
---|---|---|
UrlResource | file:、https:、ftp: 等 | UrlResource |
ClassPathResource | classpath: | ClassPathResource |
FileSystemResource | file: | FileSystemResource |
PathResource | – | PathResource |
ServletContextResource | – | ServletContextResource |
InputStreamResource | – | InputStreamResource |
ByteArrayResource | – | ByteArrayResource |
UrlResource 封装了一个 java.net.URL 对象,用于访问可通过 URL 访问的任何对象,例如文件、HTTPS 目标、FTP 目标等。所有 URL 都可以通过标准化的字符串形式表示,因此可以使用适当的标准化前缀来指示一种 URL 类型与另一种 URL 类型的区别。 这包括:file:用于访问文件系统路径;https:用于通过 HTTPS 协议访问资源;ftp:用于通过 FTP 访问资源等等。
UrlResource 是由Java代码显式使用UrlResoResource构造函数创建的,但当您调用采用String参数表示路径的API方法时,通常会隐式创建。对于后一种情况,JavaBeans PropertyEditor最终决定创建哪种类型的Resource。如果路径字符串包含一个众所周知的(对属性编辑器来说就是)前缀(例如classpath:),它会为该前缀创建一个适当的专用Resource。但是,如果它不能识别前缀,它会假定该字符串是标准URL字符串,并创建一个UrlResource。
ClassPathResource从类路径上加载资源。它使用线程上下文加载器、给定的类加载器或给定的类来加载资源。
如果类路径资源驻留在文件系统中,但不支持驻留在jar中且尚未(通过servlet引擎或任何环境)扩展到文件系统的类路径资源,则此Resource实现支持解析为java.io.File。为了解决这一问题,各种Resource实现始终支持解析为java.net.URL。
ClassPathResource是由Java代码显式使用ClassPath资源构造函数创建的,但当您调用接受表示路径的String参数的API方法时,通常会隐式创建。对于后一种情况,JavaBeans PropertyEditor识别字符串路径上的特殊前缀classpath:,并在这种情况下创建一个ClassPathResource。
FileSystemResource是 java.io.File 的资源实现。它还支持 java.nio.file.Path ,应用 Spring 的标准对字符串路径进行转换。FileSystemResource 支持解析为文件和 URL。
PathResource是 java.nio.file.Path 的资源实现。它实际上是FileSystemResource的纯java.nio.path.path替代方案,具有不同的createRelative行为。
ServletContextResource是 ServletContext 的资源实现。它表示相应 Web 应用程序根目录中的相对路径。
它始终支持流访问和URL访问,但仅当web应用程序归档扩展并且资源在文件系统上时才允许java.io.File访问。无论它是在文件系统上扩展还是直接从JAR或其他类似数据库的地方访问(这是可以想象的),实际上都取决于Servlet容器。
InputStreamResource是指定 InputStream的资源实现。注意:如果该 InputStream 已被打开,则不可以多次读取该流。
ByteArrayResource是指定的二进制数组的资源实现。它会为给定的字节数组创建一个 ByteArrayInputStream。
如果喜欢的话,欢迎 🤞关注 👍点赞 💬评论 🤝收藏 🙌一起讨论 你的支持就是我✍️创作的动力! 💞💞💞
参考:
spring - Resource 官方文档