[버그리포트] S3FileUpload 시 중복으로 이미지가 view되는 문제

Cjw.dev·2023년 4월 28일
0

버그리포트

목록 보기
1/1

게시글에 이미지 파일을 첨부하여 업로드 하는 기능을 만드는 중
연속해서 게시글 작성 시 이전 파일이 따라 붙어 중복되는 문제가 생겼다.

서버 실행 후 처음엔 잘 작동 하였으나 연속해서 게시글 작성하면 문제가 발생하였다.


처음 이미지 업로드


연속해서 다음 이미지 업로드

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> 타입)
    }
    

확인한 방법

  1. 프론트에서 s3fileupload 메소드로 넘어오는 파일 확인
  2. 파일 저장 후 URL 값을 담은 LIST 확인

확인 결과

  1. 프론트에서 AWS서버까지 저장되는 과정은 문제가 없었다.
  2. 저장된 파일의 URL을 담은 List의 값에 이전에 저장한 이미지 파일의 URL이 담겨있었다.

문제점

업로드 된 이미지 파일의 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에서 변수를 어디에 선언하느냐에 따라 할당된 데이터 지워지는 시점이 달라지는건 기본적인 부분이다.
다시 한번 기본이 중요하다는 것을 느꼈다.

profile
백엔드 개발 공부 기록 22.11.07 ~ ing

0개의 댓글