11
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Spring Cloud AWSのResourceハンドリング機能でAWS S3リソースを検索する

Last updated at Posted at 2017-07-26

AWSのSDKでS3上のリソースを操作できるが、リソース名を指定し検索してくれる機能がないようです。Spring Cloud AWSのResourceハンドリングを使えば、指定のAntパターンにマッチングするリソースの検索が可能です。

完成後画面のイメージ↓
2017-07-26_174655.jpg

#検証環境
・Spring Boot(Thymeleaf)1.4.3

#必要なライブラリ

pom.xml
	...
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-thymeleaf</artifactId>
	</dependency>
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-web</artifactId>
	</dependency>
	<dependency>
	  <groupId>org.springframework.cloud</groupId>
	  <artifactId>spring-cloud-aws-context</artifactId>
	  <version>1.2.1.RELEASE</version>
	</dependency>
	<dependency>
	    <groupId>org.springframework.cloud</groupId>
	    <artifactId>spring-cloud-aws-autoconfigure</artifactId>
	    <version>1.2.1.RELEASE</version>
	</dependency>
	<dependency>
	  <groupId>com.amazonaws</groupId>
	  <artifactId>aws-java-sdk</artifactId>
	  <version>1.11.163</version>
	</dependency>
	...

#AWS S3に接続するための設定
application.propertiesにアクセスキー、シークレットキー、リージョンを指定する。
また、ローカルからのアクセスであるため、リージョンの自動検知を「false」に指定する。

application.properties
cloud.aws.credentials.accessKey=AKIAXXXXXXXXXA3Q
cloud.aws.credentials.secretKey=T9JBXXXXXXXXXXXXXXXXXXXXGfLAQ
cloud.aws.region.static=ap-northeast-1
cloud.aws.region.auto=false

上記の設定値を読み込むために、AWSコンフィグクラスを作成する。

AWSConfig

@Configuration
public class AWSConfig {

	@Value("${cloud.aws.credentials.accessKey}")
	private String accessKey;

	@Value("${cloud.aws.credentials.secretKey}")
	private String secretKey;

	@Value("${cloud.aws.region.static}")
	private String region;

	@Bean
	public BasicAWSCredentials basicAWSCredentials() {
		return new BasicAWSCredentials(accessKey, secretKey);
	}

	@Bean
	public AmazonS3 amazonS3Client(AWSCredentials awsCredentials) {
		return AmazonS3ClientBuilder.standard().withRegion(Regions.fromName(region)).build();
	}
}

上記を作成することで、DIコンテナからResourceLoaderとAmazonS3のインスタンスを取得することが可能になります。

#アプリケーションレイヤ
普通のControllerクラスと画面表示用のフォームクラスを作成する。

AwsS3Controller
	@RequestMapping(value="/aws/s3/search", method=RequestMethod.POST)
	public String search(Model model, S3FileForm fileForm) throws IOException {
		
		S3FileForm s3FileForm = storageService.search(fileForm.getFileName());
		model.addAttribute("s3FileForm", s3FileForm);
		
		return "/aws/s3/downloadFromS3";
	}
S3FileForm
public class S3FileForm implements Serializable {
	
	private String fileName;
	
	private String downloadKey;
	
	private String[] checkedItems;
	
	private List<S3File> fileList;

	//...get set省略
}
S3File
public class S3File implements Serializable {

	private String bucketName;
	
	private String key;
	
	private String contentType;
	
	private Date lastModifiedDate;

	//...get set省略
}

#ドメインレイヤ
サービスクラスにてResourcePatternResolverを使って、Antパターンs3://cinpo/**/*testにマッチングするリソース名を検索し、対象リソース一覧を取得する。さらに、リソース名でAmazonS3オブジェクトを生成し、最終更新日などのキー情報を取得する。
s3://**/*.txtを使えばアクセス可能な全バケットを対象に検索が可能です。

S3StorageService
/**
 * AWS S3操作用サービス
 * @author
 *
 */
@Service
public class S3StorageService {
	
	private final String BUCKET_NAME = "cinpo";
	
	@Autowired
	private ResourceLoader resourceLoader;
	
	@Autowired
 	private ResourcePatternResolver resourcePatternResolver;
	
	@Autowired
	private AmazonS3 amazonS3;
	
	/**
	 * リソース検索
	 * 
	 * @param fileName
	 */
	public S3FileForm search(String fileName) {
		
		// 画面表示用フォーム
		S3FileForm s3FileForm = new S3FileForm();

			Resource[] resources = null;
			try {
				// Antパターン(s3://cinpo/**/*test.*)を指定し、対象一覧を取得する。
				resources = this.resourcePatternResolver.getResources("s3://" + BUCKET_NAME + "/**/*" + fileName + ".*");
			} catch (IOException e) {
				throw new RuntimeException(e);
			}
			
			List<S3File> s3FileList = new ArrayList<S3File>();
			
			// リソース毎にS3Objectを取得する。
			for (Resource resource : resources) {
				S3Object s3Object = amazonS3.getObject(new GetObjectRequest("s3.cinpo", resource.getFilename()));
				
				// 画面表示項目の設定
				S3File s3File = new S3File();
				s3File.setBucketName(s3Object.getBucketName());
				s3File.setKey(s3Object.getKey());
				s3File.setContentType(s3Object.getObjectMetadata().getContentType());
				s3File.setLastModifiedDate(s3Object.getObjectMetadata().getLastModified());
				
				s3FileList.add(s3File);
			}
			s3FileForm.setFileList(s3FileList);
		
		return s3FileForm;
	}
}

#HTML
最後に、検索・一覧表示用の画面を作成する。

downloadFromS3
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:th="http://www.thymeleaf.org">
      
	<head>
		<meta charset="UTF-8" />
		<link th:substituteby="common/header :: common_header"/>
		<title>S3からファイルダウンロード</title>
	</head>
	<body>
		<h1>File Download</h1>
		<p><a href="/index" th:href="@{/index}">Back to home</a></p>
		<form action="#" th:action="@{/aws/s3/search}" th:object="${s3FileForm}" method="post">
			<table>
				<tr>
					<td width="100px"><label for="fileName">検索キー</label>:</td>
					<td><input type="text" id="fileName" th:field="*{fileName}" size="30px" /></td>
				</tr>
				<tr>
					<td colspan="2"><input type="submit" value="Search" /></td>
				</tr>
			</table>
		</form>
		<div th:if="${s3FileForm.fileList != null}">
			<form action="#" th:action="@{/aws/s3/download}" th:object="${s3FileForm}" method="post">
				<table border="1">
					<tr>
						<th width="20px">Download</th>
						<th width="10px">Check</th>
						<th>Bucket</th>
						<th>Key</th>
						<th>Content Type</th>
						<th>Last Modified Date</th>
					</tr>
					<tr th:each="file:${s3FileForm.fileList}">
						<td>
							<button type="submit" name="downloadKey" th:field="*{downloadKey}" th:value="${file.key}">Download</button>
						</td>
						<td><input type="checkbox" th:field="*{checkedItems}" th:value="${file.key}" /></td>
						<td th:text="${file.bucketName}"></td>
						<td th:text="${file.key}"></td>
						<td th:text="${file.contentType}"></td>
						<td th:text="${file.lastModifiedDate}"></td>
					</tr>
				</table>
				<div><input type="submit" value="Download Selected" /></div>
			</form>
		</div>
	</body>
</html>

参考サイド:Spring Cloud AWS

11
8
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
11
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?