Spring BootでAWS S3に接続
はじめに
Spring Bootでは日常的に触れているAWSに接続できる方法があるということで調べてみました。 まずはS3です。
環境
Mac OSX 10.10.5 Yosemite Java 8 Spring Boot 1.3.5
機能
・S3からローカルにファイルをダウンロード ・S3へローカルからファイルをアップロード ・S3内のオブジェクトを検索
コード
設定ファイル
gradle
buildscript { ext { springBootVersion = '1.3.5.RELEASE' } repositories { mavenCentral() } dependencies { classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}") } } apply plugin: 'java' apply plugin: 'eclipse' apply plugin: 'spring-boot' jar { baseName = 'demo' version = '0.0.1-SNAPSHOT' } sourceCompatibility = 1.8 targetCompatibility = 1.8 repositories { mavenCentral() } dependencies { compile('org.springframework.boot:spring-boot-starter-web:1.3.5.RELEASE') compile('org.springframework.cloud:spring-cloud-starter-aws') compile('org.springframework.cloud:spring-cloud-aws-context') testCompile('org.springframework.boot:spring-boot-starter-test') } dependencyManagement { imports { mavenBom "org.springframework.cloud:spring-cloud-dependencies:Brixton.SR1" } } eclipse { classpath { containers.remove('org.eclipse.jdt.launching.JRE_CONTAINER') } }
application.yml
cloud.aws: credentials: accessKey: "aws_access_key" secretKey: "aws_secret_access_key" region: static: "リージョン"
S3の接続情報を記述します。 ファイル自体は、「src/main/resources」以下にフォルダ「config」を作成して入れます。
起動クラス
Spring Bootを走らせるだけです。
package com.test.aws; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class AwsS3Application { public static void main(String[] args) { SpringApplication.run(AwsS3Application.class, args); } }
コントローラー
package com.test.aws; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.io.Resource; import org.springframework.core.io.ResourceLoader; import org.springframework.core.io.WritableResource; import org.springframework.core.io.support.ResourcePatternResolver; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("/s3") public class S3Controller { @Autowired private ResourceLoader resourceLoader;
24行目、基本のURLを「http://localhost:8080/s3」に設定。 27〜28行目、ResourceLoaderを@Autowierd。これでS3と接続します。
@RequestMapping(value="/download", method=RequestMethod.GET) public void download(@RequestParam String filename) throws IOException { Resource resource = this.resourceLoader.getResource("s3://バケット名/" + filename); InputStream input = resource.getInputStream(); BufferedReader reader = new BufferedReader(new InputStreamReader(input)); String str = new String(); StringBuilder builder = new StringBuilder(); while ((str = reader.readLine()) != null) { builder.append(str); }; File file = new File("ダウンロードファイルを置くURL/ファイル名"); FileWriter writer = new FileWriter(file); writer.write(builder.toString()); writer.close(); reader.close(); input.close(); }
30〜51行目、ダウンロードするメソッドです。 30行目、基本のURLに「/download」でこのメソッドに繋がります。 31行目、接続するバケットとダウンロードするファイルを設定。 33〜39行目、取得したファイルから文字列を取得。 41〜43行目、ダウンロードしたファイルの配置場所とファイル名を設定し、文字を書き込みます。 45〜47行目、終了処理。
@RequestMapping(value="/upload", method=RequestMethod.GET) public void upload(@RequestParam String filename) throws IOException { File file = new File("アップロードするファイルのディレクトリ" + filename); FileInputStream input = new FileInputStream(file); BufferedReader reader = new BufferedReader(new InputStreamReader(input)); String str = new String(); StringBuilder builder = new StringBuilder(); while ((str = reader.readLine()) != null) { builder.append(str); }; Resource resource = this.resourceLoader.getResource("s3://バケット名/" + filename"); WritableResource writableResource = (WritableResource) resource; try (OutputStream output = writableResource.getOutputStream();) { output.write(builder.toString().getBytes()); } }
50行目、基本のURLに「/upload」でこのメソッドに繋がります。 51行目、引数に@RequestParamを設定しているので、URLに「?filename=text.txt」などで値を渡せます。 52行目、アップロードするファイルを指定します。51行目の引数を使うと良いです。 53〜59行目、ファイルから文字列を取得。 61行目、アップロードするバケットとファイル名を設定。ファイル名はアップロード元と合わせなくても大丈夫です。 62〜65行目、取得した文字列を書き込みます。
@Autowired private ResourcePatternResolver resolver; @RequestMapping(value="/search", method=RequestMethod.GET) public String search() throws IOException { Resource[] resources = this.resolver.getResources("s3://バケット名/**/*.txt"); StringBuilder builder = new StringBuilder(); for (int i = 0; i < resources.length; i++) { if (i!=0) { builder.append(", "); } builder.append(resources[i].toString()); } return builder.toString(); } }
68〜69行目、ResourcePatternResolverを繋げます。 71〜83行目、アップロードするメソッドです。バケット内の「.txt」を検索して出力します。 71行目、基本のURLに「/search」でこのメソッドに繋がります。 73行目、探したいファイルを指定。「*」でlike検索が可能です。 74〜80行目、検索結果をStringBuilderに追加し、 82行目、検索を返します。
実行
下記のコマンドで結果を取得できます。
$ curl http://localhost:8080/s3/upload?filename=ファイル名
$ curl http://localhost:8080/s3/download?filename=ファイル名
$ curl http://localhost:8080/s3/search
さいごに
簡単に接続できました。 他のサービスとの接続も試してみたいと思います。