티스토리 뷰
안녕하십니까
Java Spring boot를 이용한 API 개발 중 AWS S3에 이미지 파일을 관리해야 하는 작업이 있어 진행을 해봤습니다.
Java에서 S3나 그 외에 관련된 기능들을 사용하려면 SDK를 Dependency추가해줘야 합니다.
Gradle 4.6 이상
group 'aws.test'
version '1.0-SNAPSHOT'
apply plugin: 'java'
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
dependencies {
implementation 'com.amazonaws:aws-java-sdk-bom:1.11.228'
implementation 'com.amazonaws:aws-java-sdk-s3'
}
Gradle 4.6 미만
group 'aws.test'
version '1.0-SNAPSHOT'
apply plugin: 'java'
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath "io.spring.gradle:dependency-management-plugin:1.0.3.RELEASE"
}
}
apply plugin: "io.spring.dependency-management"
dependencyManagement {
imports {
mavenBom 'com.amazonaws:aws-java-sdk-bom:1.11.228'
}
}
dependencies {
compile 'com.amazonaws:aws-java-sdk-s3'
}
저 같은 경우는 IDE에서는 3 버전을, 실 서버에서는 5 버전 대를 사용했기 때문에 dependencies에도 넣어주고 mavenBom도 추가해줬습니다.
추가를 완료 하였다면 이제 사용을 하면 되는데, 사용을 하기 전 우리는 서비스 클라이언트를 생성해줘야 합니다.
이 서비스 클라이언트를 만들어 줘야 S3, CloudWatch 등 여러 서비스 들을 이용하실 수 있습니다.
Amazon Web Services에 요청하려면 먼저 서비스 클라이언트 객체를 만듭니다. 권장 방법은 서비스 클라이언트 빌더를 사용하는 것입니다.
각 AWS 서비스에는 서비스 API의 각 작업에 대한 메서드를 포함하는 서비스 인터페이스가 있습니다.
예를 들어 Amazon DynamoDB의 서비스 인터페이스 이름은 AmazonDynamoDB입니다. 각 서비스 인터페이스마다 서비스 인터페이스의 구현을 생성하는 데 사용할 수 있는 해당하는 클라이언트 빌더가 있습니다. DynamoDB용 클라이언트 빌더 클래스 이름은 AmazonDynamoDBClientBuilder입니다.
우리는 S3를 이용할 것이니 서비스 인터페이스 이름은 AmazonS3라는 인터페이스를 사용할 것이며, 클라이언트 빌더 이름은 AmazonS3 ClientBuilder가 될 것입니다.
@Configuration
@EnableWebMvc
public class AWSConfiguration implements WebMvcConfigurer {
@Value("${AWS.ACESSKEY}")
private String accessKey;
@Value("${AWS.SECRETKEY}")
private String secretKey;
@Bean
public BasicAWSCredentials AwsCredentials() {
BasicAWSCredentials AwsCreds = new BasicAWSCredentials(accessKey, secretKey);
return AwsCreds;
}
@Bean
public AmazonS3 AwsS3Client() {
AmazonS3 s3Builder = AmazonS3ClientBuilder.standard()
.withRegion(Regions.AP_NORTHEAST_2)
.withCredentials(new AWSStaticCredentialsProvider(this.AwsCredentials()))
.build();
return s3Builder;
}
이제 기능을 구현하면 되는데요. 저는 S3를 이용한 GET, UPLOAD, DELETE를 구현할 것입니다.
@Slf4j
@Service
@Transactional(rollbackFor = Exception.class)
public class AwsS3Service {
@Autowired
private AmazonS3 s3Client;
@Value("${AWS.BUCKET}")
private String bucketName;
public void uploadObject(MultipartFile multipartFile, String storedFileName) throws IOException {
SimpleDateFormat date = new SimpleDateFormat("yyyyMMdd");
ObjectMetadata omd = new ObjectMetadata();
omd.setContentType(multipartFile.getContentType());
omd.setContentLength(multipartFile.getSize());
omd.setHeader("filename", multipartFile.getOriginalFilename());
// Copy file to the target location (Replacing existing file with the same name)
s3Client.putObject(new PutObjectRequest(bucketName + "/" + date.format(new Date()), storedFileName,
multipartFile.getInputStream(), omd));
}
public void deleteObject(String date, String storedFileName) throws AmazonServiceException {
s3Client.deleteObject(new DeleteObjectRequest(bucketName + "/" + date, storedFileName));
}
public Resource getObject(String date, String storedFileName) throws IOException {
S3Object o = s3Client.getObject(new GetObjectRequest(bucketName + "/" + date, storedFileName));
S3ObjectInputStream objectInputStream = o.getObjectContent();
byte[] bytes = IOUtils.toByteArray(objectInputStream);
Resource resource = new ByteArrayResource(bytes);
return resource;
}
}
위의 코드에서 보면 bucketName + "/" + date가 있는데, 이 부분이 폴더 이름이 될 것입니다.
그리고 getObject 부분은 예제와 좀 다르게 구현을 하였는데, Restful API 방식으로 데이터를 전달하기 위해 org.springframework.core.io.Resource를 활용하였습니다.
그리고 그냥 resposne로 보낼 시 File name이 null로 전송되기 때문에 다음과 같이 설정을 해줘야 합니다.
Resource resource = imageService.loadFileAsResource(date, fileName);
// Try to determine file's content type
String contentType = null;
try {
contentType = request.getServletContext().getMimeType(resource.getFile().getAbsolutePath());
} catch (IOException ex) {
log.info("Could not determine file type.");
}
// Fallback to the default content type if type could not be determined
if(contentType == null) {
contentType = "application/octet-stream";
}
return ResponseEntity.ok()
.contentType(MediaType.parseMediaType(contentType))
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + fileName + "\"")
.body(resource);
postman으로 테스트 할 시 제대로 파일을 받을 수 있는 것을 확인 하실 수 있습니다.
출처 및 참고
Java SDK 사용
https://docs.aws.amazon.com/ko_kr/sdk-for-java/v1/developer-guide/setup-project-gradle.html
Java S3
'BackEnd > Java' 카테고리의 다른 글
pm2 java (0) | 2019.09.24 |
---|---|
Log4j2 날짜별 폴더 생성 & Level별 로그 생성 (2) | 2019.09.04 |
Java send HTTP request (0) | 2019.04.02 |
Spring boot + Mybatis 연결하기 (0) | 2019.03.26 |
Spring boot Redis 사용하기 (3) | 2019.03.12 |
- Total
- Today
- Yesterday
- Spring
- Angular
- MySQL
- react
- mobx
- facebook login
- jQuery
- JavaScript
- data table component
- JPA
- 파이썬
- data gird component
- localStorage
- 파이썬3
- data component module
- 페이스북 로그인
- https://www.tistory.com/auth/logout/
- data component
- JSON
- Spring Boot
- Router
- angular router
- React-router
- python3
- Redux
- Python
- Java
- CSS
- data grid component
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |