プロパティじゃなくて単に変数読み込みだけな方法も混じってはいる。
@Value
でfile:..
やclasspath:..
を指定しResource
としてinjectionしてあとは好みの方法で読み込む。以下ではFiles.readString
を使用しているがここは状況に応じた方法で良い。
import java.io.IOException;
import java.nio.file.Files;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.GetMapping;
@Service
public class FileToStringService {
@Value("file:sample.txt")
Resource resource;
public void sample() throws IOException {
String str = Files.readString(resource.getFile().toPath());
System.out.println(str);
}
}
ResourceLoader
を使う方法。
import java.io.IOException;
import java.nio.file.Files;
import org.springframework.core.io.ResourceLoader;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.GetMapping;
@Service
public class FileToStringService {
// コンストラクタ省略
ResourceLoader loader;
public void sample() throws IOException {
String str = Files.readString(loader.getResource("file:sample.txt").getFile().toPath());
System.out.println(str);
}
}
ResourceUtils
を使用する方法。
import org.springframework.util.ResourceUtils;
String str = Files.readString(ResourceUtils.getFile("file:sample.txt").toPath());
ファイルの中身を色んなところで使いたいならbeanにしても良い。
@Bean
@Qualifier("sampleStr1")
public String sample1(ResourceLoader loader) throws IOException {
return Files.readString(loader.getResource("file:sample.txt").getFile().toPath());
}
@Service
public class FileToStringService {
String sampleStr;
public FileToStringService(@Qualifier("sampleStr") String sampleStr) {
this.sampleStr = sampleStr;
}
}
SqELだけでも書けるがトリッキー感がある。
参考:https://stackoverflow.com/questions/14639209/spring-expression-read-file-content
@Value("""
#{T(java.nio.file.Files)
.readString(T(org.springframework.util.ResourceUtils)
.getFile('file:sample.txt'))}
""")
String str;
springの記法(file:..
とか)は使えないがJavaのAPIだけでならこうも書ける。
@Value("#{T(java.nio.file.Files).readString(T(java.nio.file.Path).of('sample.txt'))}")
String str;
適当なファイル読み込みstaticメソッドを一つ作成してそれをSqELから呼び出せば多少は読みやすくなる。
public class FileToStringUtil {
public static String readString(String location) throws IOException {
return Files.readString(ResourceUtils.getFile(location).toPath());
}
}
@Value("#{T(kagamihoge.FileToStringUtil).readString('file:sample.txt')}")
String str;