Azure에서 NCP으로 교체하는 요청이 있었다.
파일서버 연동은 처음이라 공식홈페이지의 샘플코드를 보면서 작업을 했지만 도통 뭔소린지 알 수 없어 꽤나 걱정이 많았던 작업이었다.
약 1주정도 무한 구글링을 하면서 필요한 지식들을 조각조각 모아서 테스트를 성공적으로 마쳤다.
너무 큰 고통을 받고나니 Spring과 AWS에 대한 공부가 많이 필요하다는 것을 느꼈다.
java 17
Spring boot 3.2.x
1. build.gradle 설정
implementation 'com.amazonaws:aws-java-sdk-s3:1.12.638'
2. 클래스 구현
package com.org.mgt.common.util;
import com.amazonaws.SdkClientException;
import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.client.builder.AwsClientBuilder;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.*;
import com.amazonaws.util.IOUtils;
import com.org.mgt.common.vo.FileDTVO;
import com.org.mgt.common.vo.FileHTVO;
import com.org.mgt.common.vo.UserVO;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.http.*;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MultipartFile;
import java.io.*;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.*;
@Slf4j
@Component
public class NcpStorage {
private final Environment env;
private String endPoint = "https://kr.object.ncloudstorage.com";
private String regionName = "kr-standard";
private String accessKey = "";
private String secretKey = "";
private String bucketName = "";
private String root = "";
private AmazonS3 s3 = null;
public NcpStorage(Environment env) {
this.env = env;
this.accessKey = env.getProperty("ncp.accessKey");
this.secretKey = env.getProperty("ncp.secretKey");
this.bucketName = env.getProperty("ncp.bucketName");
//wiselection-bucket.kr.object.ncloudstorage.com/
this.root = env.getProperty("ncp.root");
// S3 client
this.s3 = AmazonS3ClientBuilder.standard()
.withEndpointConfiguration(new AwsClientBuilder.EndpointConfiguration(endPoint, regionName))
.withCredentials(new AWSStaticCredentialsProvider(new BasicAWSCredentials(accessKey, secretKey)))
.build();
}
/**
* 파일 업로드
*/
public FileDTVO uploadFile(
HttpServletRequest request,
Environment env,
FileHTVO fileHTVO,
MultipartFile multipartFile
){
FileDTVO fileDTVO = new FileDTVO();
fileDTVO.setResultCode("OK");
try {
if (multipartFile != null){
Date date = new Date();
SimpleDateFormat sdf= new SimpleDateFormat("yyyyMMddmmssSSS", Locale.KOREA);
String fileDate = sdf.format(date);
//확장자
int pos = multipartFile.getOriginalFilename().lastIndexOf(".");
String ext = multipartFile.getOriginalFilename().substring(pos + 1);
String filePath = fileHTVO.getFileStoreLocation();
String fileName = multipartFile.getOriginalFilename();
String key = filePath + "/" + fileName;
File file = new File(filePath);
if (!file.exists()) {
file.mkdirs();
}
file = new File(key);
fileDTVO.setFileStoreLocation(filePath);
UserVO loginUser = (UserVO) request.getSession().getAttribute("loginUser");
HttpServletRequest req = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
String ip = req.getHeader("X-FORWARDED-FOR");
if (ip == null) {
ip = req.getRemoteAddr();
}
if (loginUser != null) {
fileDTVO.setRegIdx(loginUser.getUserId());
}
fileDTVO.setRegIp(ip);
// 네이버 클라우드 플랫폼 Upload 시작
String folderName = filePath;
String objectName = folderName + "/" + fileName;
String fileNo = "";
// String fileUrl = createBucketFileUrl();
ObjectMetadata objectMetadata = new ObjectMetadata();
objectMetadata.setContentLength(multipartFile.getSize());
objectMetadata.setContentType(multipartFile.getContentType());
PutObjectRequest putObjectRequest = new PutObjectRequest(
bucketName,
objectName,
multipartFile.getInputStream(),
objectMetadata
).withCannedAcl(CannedAccessControlList.PublicRead);
fileNo = putObjectRequest.getKey();
try {
s3.putObject(putObjectRequest);
} catch (AmazonS3Exception e) {
e.printStackTrace();
} catch(SdkClientException e) {
e.printStackTrace();
}
// 네이버 클라우드 플랫폼 Upload 끝
fileDTVO.setFileNo(fileHTVO.getFileNo()); // fileNo
fileDTVO.setOriginFileNm(fileName); // name
fileDTVO.setStoreFileNm(key);
fileDTVO.setFileStoreCours(env.getProperty("ncp.root") + "/" + key); // full URL
fileDTVO.setFileExtsn(ext);
fileDTVO.setFileSize(multipartFile.getSize());
}
} catch (Exception e) {
e.printStackTrace() ;
System.out.println( e.getMessage());
}
return fileDTVO;
}
/**
* 파일 다운로드
*/
public ResponseEntity<byte[]> downloadFile(String fileName, String orgFileName, String fileStoreCours) {
byte[] bytes = null;
HttpHeaders headers = null;
String objectName = fileName;
String downloadFilePath = fileStoreCours;
try {
S3Object s3Object = s3.getObject(bucketName, objectName);
S3ObjectInputStream s3ObjectInputStream = s3Object.getObjectContent();
bytes = IOUtils.toByteArray(s3ObjectInputStream);
headers = new HttpHeaders();
headers.setContentType(MediaType.IMAGE_PNG);
headers.setContentDisposition(ContentDisposition.builder("attachment")
.filename(URLEncoder.encode(orgFileName,"UTF-8")).build());
} catch (IOException e) {
e.printStackTrace();
}
return new ResponseEntity<byte[]>(bytes, headers, HttpStatus.OK);
}
/**
* 파일목록 단건삭제
*/
public void deleteFileOne(String objectName) throws Exception {
try {
s3.deleteObject(bucketName, objectName);
System.out.format("Object %s has been deleted.\n", objectName);
} catch (AmazonS3Exception e) {
e.printStackTrace();
} catch(SdkClientException e) {
e.printStackTrace();
}
}
/**
* 파일목록 전체삭제
*/
public void deleteFileAll() throws Exception {
try {
// list all in the bucket
ListObjectsRequest listObjectsRequest = new ListObjectsRequest()
.withBucketName(bucketName)
.withMaxKeys(300);
ObjectListing objectListing = s3.listObjects(listObjectsRequest);
while (true) {
for (S3ObjectSummary objectSummary : objectListing.getObjectSummaries()) {
log.info("### url: {}", root + objectSummary.getKey());
log.info("### url: {}", root + objectSummary.getSize());
log.info("### url: {}", root + objectSummary.getOwner().getId());
deleteFileOne(objectSummary.getKey());
}
if (objectListing.isTruncated()) {
objectListing = s3.listNextBatchOfObjects(objectListing);
} else {
break;
}
}
} catch (AmazonS3Exception e) {
System.err.println(e.getErrorMessage());
System.exit(1);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* 파일목록 조회
*/
public ArrayList<Map<String, Object>> selectFileInfo(String key) {
ArrayList<Map<String, Object>> resultList = new ArrayList<>();
Map<String, Object> resultMap = new HashMap<>();
try {
// list all in the bucket
ListObjectsRequest listObjectsRequest = new ListObjectsRequest()
.withBucketName(bucketName)
.withMaxKeys(300);
ObjectListing objectListing = s3.listObjects(listObjectsRequest);
while (true) {
for (S3ObjectSummary objectSummary : objectListing.getObjectSummaries()) {
if(key.equals(objectSummary.getKey())){
log.info("### url: {}", root + "/" + objectSummary.getKey());
resultMap.put("fileNo", objectSummary.getKey());
resultMap.put("url", root + "/" + objectSummary.getKey());
resultMap.put("size", objectSummary.getSize());
resultList.add(resultMap);
}
}
if (objectListing.isTruncated()) {
objectListing = s3.listNextBatchOfObjects(objectListing);
} else {
break;
}
}
} catch (AmazonS3Exception e) {
System.err.println(e.getErrorMessage());
System.exit(1);
} catch (Exception e) {
throw new RuntimeException(e);
}
return resultList;
}
// private String createBucketFileUrl() {
// // 버킷 파일의 URL을 생성
// UUID key = UUID.randomUUID();
// String fileUrl = s3.getUrl(bucketName, String.valueOf(key)).toString();
//
// return fileUrl;
// }
}
728x90
반응형
'프로그래밍 > 백엔드' 카테고리의 다른 글
Spring boot 3.2.x 버전에서 Spring Security 기본틀 구현 (1) | 2024.04.20 |
---|---|
Spring 6 과 Spring Boot 3.0 의 변경사항 정리 (2) | 2023.12.21 |
리눅스 서버에서 한글 깨질 때 (Tomcat 9, Ubuntu) (0) | 2023.07.14 |
maven 라이브러리 경로가 삭제되는 현상 (0) | 2023.06.22 |
[Java] Eclipse server clean 오류 해결 방법 (0) | 2023.06.09 |