pom.xml
...
<dependencies>
...
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-s3</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
...
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-bom</artifactId>
<version>1.11.475</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
...
AmazonS3Service.java
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.InputStreamResource;
import org.springframework.http.CacheControl;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.ObjectMetadata;
import com.amazonaws.services.s3.model.S3Object;
@Service
public class AmazonS3Service {
@Value("${aws.accessKeyId}")
private String accessKeyId;
@Value("${aws.secretAccessKey}")
private String secretAccessKey;
@Value("${aws.region}")
private String region;
@Value("${aws.bucketName}")
private String bucketName;
public String putObject(File file, String filename, String contentType, long contentLength) {
try {
InputStream inputStream = new FileInputStream(file);
String key = UUID.randomUUID().toString() + "/" + filename; // ファイル名が同じ場合にかぶらないようにキーにUUIDを使用
ObjectMetadata objectMetadata = new ObjectMetadata();
objectMetadata.setContentType(contentType);
objectMetadata.setContentLength(contentLength);
getAmazonS3().putObject(bucketName, key, inputStream, objectMetadata);
return key;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public ResponseEntity<InputStreamResource> downloadObject(String key) {
S3Object s3Object = getAmazonS3().getObject(bucketName, key);
return ResponseEntity.ok()
.contentLength(s3Object.getObjectMetadata().getContentLength())
.contentType(MediaType.parseMediaType(s3Object.getObjectMetadata().getContentType()))
.cacheControl(CacheControl.maxAge(365, TimeUnit.DAYS)) // キャッシュ設定
.body(new InputStreamResource(s3Object.getObjectContent()));
}
private AmazonS3 getAmazonS3() {
return AmazonS3ClientBuilder.standard()
.withCredentials(new AWSStaticCredentialsProvider(new BasicAWSCredentials(accessKeyId, secretAccessKey)))
.withRegion(region)
.build();
}
}
application.properties
# 環境変数からAWS用設定取得 (Eclipseの実行構成に設定、HerokuではBucketeerアドオン導入時に自動的に設定される)
# https://docs.aws.amazon.com/ja_jp/sdk-for-java/v1/developer-guide/credentials.html
aws.accessKeyId=${BUCKETEER_AWS_ACCESS_KEY_ID}
aws.secretAccessKey=${BUCKETEER_AWS_SECRET_ACCESS_KEY}
aws.region=${BUCKETEER_AWS_REGION}
aws.bucketName=${BUCKETEER_BUCKET_NAME}
ImageDownloadController.java
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.InputStreamResource;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class ImageDownloadController implements Consts {
@Autowired
AmazonS3Service amazonS3Service;
@GetMapping(IMAGE_RELATIVE_URL + "**")
@ResponseBody
public ResponseEntity<InputStreamResource> imageDownload(HttpServletRequest request) {
String key = request.getRequestURL().toString().split(IMAGE_RELATIVE_URL)[1];
return amazonS3Service.downloadObject(key);
}
}