LoginSignup
14
19

More than 3 years have passed since last update.

Spring FrameworkのResourceインターフェースのおさらいメモ

Posted at

概要

Spring FrameworkのResourceインターフェースと実装クラスをを使ったリソースファイルのアクセス方法をおさらいしたときのメモです。

環境

  • Windows 10 Professional 1909
  • OpenJDK 13
  • Spring Boot 2.2.1

参考

Resource

Since 28.12.2003

Interface for a resource descriptor that abstracts from the actual type of underlying resource, such as a file or class path resource.

Resourceインターフェースのインスタンスを取得する方法には

  1. 実装クラスを使用する
  2. ResourceLoaderを使用する
  3. @Valueアノテーションを使用する

などがあります。

実装クラスを使用する方法

リソースファイルのロケーションに応じて適切なResourceインタフェースの実装クラスを使用する方法です。
たとえば、クラスパス内のリソースにアクセスするためのClassPathResource、ネットワーク上のリソースにアクセスするためのUrlResource、ファイルシステム上のリソースにアクセスするためのFileUrlResourceがあります。

ClassPathResource

Since 28.12.2003

Resource implementation for class path resources. Uses either a given ClassLoader or a given Class for loading resources.

コンストラクタ
ClassPathResource(String path)
ClassPathResource(String path, Class<?> clazz)
ClassPathResource(String path, ClassLoader classLoader)

コード

Resource resource = new ClassPathResource("config/app.properties");

ResourceインタフェースはInputStreamSourceインタフェースを継承しているのでgetInputStreamメソッドで、リソースファイルのInputStreamを取得することができます。

String read(Resource resource) {
    try (InputStream in = resource.getInputStream();
         BufferedReader reader = new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8))) {
        StringBuilder sb = new StringBuilder();
        String line = null;
        while ((line = reader.readLine()) != null) {
            sb.append(line);
        }
        return sb.toString();
    } catch (IOException e) {
        throw new UncheckedIOException(e);
    }
}

なお、ResourceインタフェースはgetFileメソッドもあるので、以下のように記述することができますが、リソースがクラスパス内やネットワーク上にある場合は例外をスローするので、通常はリソースファイルがファイルシステム上にある場合に限って使った方がいいと思います。

String read(Resource resource) {
    try {
        return Files.readString(resource.getFile().toPath());
    } catch (IOException e) {
        throw new UncheckedIOException(e);
    }
}

UrlResource

Since 28.12.2003

Resource implementation for java.net.URL locators. Supports resolution as a URL and also as a File in case of the "file:" protocol.

コンストラクタ
UrlResource(String path)
UrlResource(String protocol, String location)
UrlResource(String protocol, String location, String fragment)
UrlResource(java.net.URI uri)
UrlResource(java.net.URL url)

コード

Resource urlResource = new UrlResource("http://localhost:8887/config/app.properties");

FileUrlResource

Since 5.0.2

Subclass of UrlResource which assumes file resolution, to the degree of implementing the WritableResource interface for it. This resource variant also caches resolved File handles from getFile().

コンストラクタ
FileUrlResource(String location)
FileUrlResource(java.net.URL url)

コード

Resource fileUrlResource = new FileUrlResource("c://var//config/app.properties");

ResourceLoaderを使用する方法

Since 10.03.2004

Strategy interface for loading resources (e.. class path or file system resources). An ApplicationContext is required to provide this functionality, plus extended ResourcePatternResolver support.
DefaultResourceLoader is a standalone implementation that is usable outside an ApplicationContext, also used by ResourceEditor.

ResourceLoaderインタフェースの実装クラスを使ってResourceのインスタンスを取得すれば、Resourceインタフェースの実装クラスを意識せずにすむというメリットがあります。

Spring Bootでは、ResourceLoaderにはAnnotationConfigServletWebServerApplicationContextクラスのインスタンスが注入されます。(このクラスはSpring Bootプロジェクトにあります)

@Autowired
private ResourceLoader resourceLoader;
// org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext

classpath

classpath:から始める書き方をするとClassPathResourceクラスのインスタンスが注入されます。

Resource resource = resourceLoader.getResource("classpath:config/app.properties");
// org.springframework.core.io.ClassPathResource

url

httpスキームで記述するとUrlResourceクラスのインスタンスが注入されます。

Resource resource = resourceLoader.getResource("http://localhost:8887/config/app.properties");
// org.springframework.core.io.UrlResource

file

fileスキームで記述するとFileUrlResourceクラスのインスタンスが注入されます。

Resource resource = resourceLoader.getResource("file:///c://config/app.properties");
// org.springframework.core.io.FileUrlResource

@Valueアノテーションを使用する方法

Valueアノテーションの値により、Spring Frameworkが適切な実装クラスのインスタンスを注入してくれます。
アノテーションに記述する値のフォーマットはResourceLoaderと同じです。

classpath

@Value("classpath:config/app.properties")
private Resource classpathResource;
// org.springframework.core.io.ClassPathResource

url

@Value("http://localhost:8887/config/app.properties")
private Resource urlResource;
// org.springframework.core.io.UrlResource

file

@Value("file:///c://config/app.properties")
private Resource fileUrlResource;
// org.springframework.core.io.FileUrlResource

ResourceUtilsを使用する方法

Since 1.1.5

Utility methods for resolving resource locations to files in the file system. Mainly for internal use within the framework.

APIドキュメントに書かれている通り、主にSpring Framework内部で使用するためのユーティリティークラスです。アプリケーション側で使ってはいけないという記述はありませんが、あくまでもフレームワーク内での使用を目的としているので利用には留意が必要です。

classpath

File file = ResourceUtils.getFile("classpath:config/app.properties");

url

URL url = ResourceUtils.getURL("http://localhost:8887/config/app.properties");

file

File file = ResourceUtils.getFile("file:///c://var//config/app.properties");

StreamUtils

Since 3.2.2

Simple utility methods for dealing with streams. The copy methods of this class are similar to those defined in FileCopyUtils except that all affected streams are left open when done. All copy methods use a block size of 4096 bytes.
Mainly for use within the framework, but also useful for application code.

Spring Frameworkにはストリームを処理するユーティリティクラスもあります。このクラスのcopyToStringメソッドを使うと下記のようにコードを簡略化できます。

String data = StreamUtils.copyToString(resource.getInputStream(), StandardCharsets.UTF_8);
14
19
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
19