게시글에 이미지 파일을 첨부하여 업로드 하는 기능을 만드는 중
연속해서 게시글 작성 시 이전 파일이 따라 붙어 중복되는 문제가 생겼다.
서버 실행 후 처음엔 잘 작동 하였으나 연속해서 게시글 작성하면 문제가 발생하였다.
처음 이미지 업로드
연속해서 다음 이미지 업로드
1개의 이미지 파일만 첨부하여 업로드 하였으나 이전 이미지 파일이 따라와서 함께 업로드 되었다.
AWS 서버쪽 데이터에는 각 게시글마다 저장한 파일 개수만큼 정상적으로 저장 되었으나
파일 저장 후 리턴되는 파일 URL 주소 값이 이전 파일의 주소값과 같이 리턴되었다.
문제의 코드 )
프런트에서 넘어온 img파일의 이름을 가공하고 aws 서버로 저장해주는 코드이다.
해당 코드에서 디버깅을 하며 문제점을 찾아보았다.
List<String> urlList = new ArrayList<>(); //업로드된 url을 받기위한 리스트
public S3FileUploadService(AmazonS3Client amazonS3Client) {
this.amazonS3Client = amazonS3Client;
}
//생성자 주입
public List<String> upload(List<MultipartFile> uploadFile) throws IOException {
System.out.println("여기는 s3서비스 로직 upload 메소드 : " + uploadFile);
//파일이름 새로만들어서 리스트에 담기
List<Map<String, String>> fileList = new ArrayList<>();
for (int i = 0; i < uploadFile.size(); i++) {
String origName = uploadFile.get(i).getOriginalFilename(); //원 파일이름
String ext = origName.substring(origName.lastIndexOf('.')); // 확장자
String saveFileName = getUuid() + ext; //uuid로 새이름 만들기
Map<String, String> map = new HashMap<>();
map.put("saveFile", saveFileName);
// System.out.println("s3맵 : " + saveFileName );
fileList.add(map);
}
System.out.println("확장자바꾼 파일 저장한 리스트 : " + fileList);
for (int i = 0; i < uploadFile.size(); i++) {
String url = "";
File file = new File(System.getProperty("user.dir") + fileList.get(i).get("saveFile"));
//로컬 현재위치에 임시저장 객체 만듬
System.out.println("s3 upload메소드 의심가는 파일 : " + fileList.get(i).get("saveFile"));
uploadFile.get(i).transferTo(file); //로컬에 파일 임시저장
uploadOnS3(fileList.get(i).get("saveFile"), file); //업로드
url = defaultUrl + '/' + fileList.get(i).get("saveFile"); //업로드한 파일의 url주소
urlList.add(url); //리턴을 위해 담음
System.out.println("업로드된 upl 주소 담긴 list : " + urlList); // << 문제의 부분
file.delete(); // 임시파일 삭제
}
return urlList; //업로드 후 리턴값 (List<String> 타입)
}
업로드 된 이미지 파일의 URL을 담을 List를 전역 변수로 지정해두어 메소드 로직이 끝나도 해당 데이터가 삭제되지 않고 그대로 남아있었던 것이다.
@Service
public class S3FileUploadService {
private final AmazonS3Client amazonS3Client; //아마존 계정정보 propertie파일 -> common-context에서 주입
@Value("${aws.s3.bucket}")
private String bucket; //S3버킷정보
@Value("${aws.s3.bucket.url}") //지역정보
private String defaultUrl;
List<String> urlList = new ArrayList<>(); //업로드된 url을 받기위한 리스트
// 전역 변수로 선언한 것이 문제
public S3FileUploadService(AmazonS3Client amazonS3Client) {
this.amazonS3Client = amazonS3Client;
}
//생성자 주입
public List<String> upload(List<MultipartFile> uploadFile) throws IOException {...}
파일 업로드 메소드 작업 종료와 함께 List가 초기화 될 수 있도록 List를 메소드 안에 선언해주었다.
@Service
public class S3FileUploadService {
private final AmazonS3Client amazonS3Client; //아마존 계정정보 propertie파일 -> common-context에서 주입
@Value("${aws.s3.bucket}")
private String bucket; //S3버킷정보
@Value("${aws.s3.bucket.url}") //지역정보
private String defaultUrl;
public S3FileUploadService(AmazonS3Client amazonS3Client) {
this.amazonS3Client = amazonS3Client;
}
//생성자 주입
public List<String> upload(List<MultipartFile> uploadFile) throws IOException {
// 메소드 안에 선언
List<String> urlList = new ArrayList<>(); //업로드된 url을 받기위한 리스트
}
해결된 코드로 다시 파일 업로드를 진행해보자
처음 업로드
연속해서 다음 게시글 업로드
느낀점 :
java에서 변수를 어디에 선언하느냐에 따라 할당된 데이터 지워지는 시점이 달라지는건 기본적인 부분이다.
다시 한번 기본이 중요하다는 것을 느꼈다.