채팅 파일 업로드 구현하기

이상혁·2024년 4월 24일
0

문제 상황

프로젝트를 진행 중에 채팅으로 파일 업로드를 구현하는 부분이 있었다.
게시판 부분에서 파일 업로드를 구현을 해서 딱히 어렵지 않다고 생각을 했다.
하지만 내가 생각한 것과는 달라 문제가 생겼다.

내가 생각을 한 것은 chatService에서 RequestPart를 통해서 파일을 가지고 온 뒤 게시판 파일 업로드처럼 S3에 업로드를 하는 것이다.
하지만 stomp에서는 RequestPart를 사용할 수가 없었다.

해결 방법

파일 업로드를 구현하기 위해서 구글링을 해보던 도중 이미지 업로드 부분을 보게 되었는데 base64로 구현한 부분을 보게 되었다.
base64란 바이너리 데이터를 문자 코드에 영향을 받지 않는 공통 ASCII 문자로 표현하기 위해 만들어진 인코딩이다.
즉, 파일을 스트링타입으로 표현한 것이다.

그래서 이 base64를 받아서 파일로 변환을 해주고 업로드를 해주면 되겠다라는 생각을 했다.
근데 여기서 생각해야할 한 가지 문제가 파일의 확장자이다.
스트링 타입으로 오기에 이 파일이 어떤 확장자를 가지는 지 알아야 했다.
그런데 basw64를 보면 맨 앞에

data:image/jpeg;base64,asdasdadasd......

이런 식으로 확장자를 나타낸준다.
그래서 ,를 통해서 스트링을 나누고 앞에 data 부분을 통해서 확장을 구분해서 판단을 하였다.

private void chatFileUpload(String base64, List<String> fileNames) throws IOException {
        String[] strings = base64.split(",");
        String base64Image = strings[1];

        String extension = "";
        if (strings[0].equals("data:image/jpeg;base64")) {
            extension = "jpeg";
        } else if (strings[0].equals("data:image/png;base64")){
            extension = "png";
        } else if (strings[0].equals("data:image/jpg;base64")) {
            extension = "jpg";
        } else if (strings[0].equals("data:application/pdf;base64")) {
            extension = "pdf";
        } else if (strings[0].equals("data:application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;base64")) {
            extension = "xlsx";
        } else if (strings[0].equals("data:application/vnd.openxmlformats-officedocument.wordprocessingml.document;base64")) {
            extension = "docx";
        }

        byte[] imageBytes =  DatatypeConverter.parseBase64Binary(base64Image);

        File tempFile = File.createTempFile("file", "." + extension);

        try (OutputStream outputStream = new FileOutputStream(tempFile)) {
            outputStream.write(imageBytes);
        }

        String originalName = UUID.randomUUID().toString() + "." + extension;

        amazonS3.putObject(new PutObjectRequest(bucket, originalName, tempFile).withCannedAcl(CannedAccessControlList.PublicRead));

        String awsS3ImageUrl = amazonS3.getUrl(bucket, originalName).toString();

        try {
            FileOutputStream fileOutputStream = new FileOutputStream(tempFile);
            fileOutputStream.close();
            if (tempFile.delete()) {
                log.info("File delete success");
            } else {
                log.info("File delete fail");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        fileNames.add(awsS3ImageUrl);
}

위 내용을 코드로 나타낸 것이다.
split 메소드를 통해서 data와 파일을 나누고 data로 확장자를 구분을 한다.
그리고 파일 스트링을 바이너리로 타입을 변환을 해서 임시파일을 만들어주고 이를 S3에 업로드를 해준다.
임시 파일을 지워준 뒤 S3에 업로드 된 파일의 이름을 가지고 와서 이를 반환을 한다.

이러한 방법을 통해서 채팅에서 상대방에서 파일을 업로드하고 전달을 하였다.

profile
개발 공부 하기 위해 만든 블로그

0개의 댓글