파일 업로드 기능 세팅하기

강상은·2023년 12월 4일

세팅하기

application.properties 파일에 설정 추가

마지막 라인의 org.zerock.upload.path는 컨트롤러에서 필요한 변수의 값으로 사용할 예정

설정한대로 운영체제의 C 드라이브에 upload 폴더를 미리 생성해 두자 (Mac이나 Linux에서는 현재 사용자 계정에 있는 폴더를 이용하고 접근 권한을 주도록 합니다)

업로드 처리를 위한 DTO

파일 업로드는 MultipartFile이라는 API를 이용해서 처리합니다.
이 때문에 컨트롤러에서 파라미터를 MultipartFile로 지정해 주면 간단한 파일 업로드 처리는 가능하지만 Swagger UI와 같은 프레임워크로 테스트하기 불편하기 때문에 dto 패키지에 별도의 DTO로 선언해서 사용하는 것이 좋다.

dto 패키지에 upload 하위 패키지를 생성하고 UploadFileDTO를 선언

컨트롤러와 Swagger UI 테스트

실제 파일의 업로드 설정은 controller 패키지의 UpDownController를 작성해서 처리합니다
UpdownController는 파일 업로드와 파일을 보여주는 기능을 메소드로 처리할 것입니다.
@RestController로 설정하고 파일의 업로드를 처리하기 위해서 upload()를 다음과 같이 작성

실행하기

프로젝트를 실행하고 '/swagger-ui/index.html'을 실행해서 다음과 같이 파일 업로드가 가능한 지 확인합니다(실제 파일 업로드는 files 항목을 이용해서 확인 가능)

실제 파일을 처리할 때는 파일의 저장 경로가 필요하므로 application.properties의 설정 정보는 @Value를 이용해서 처리

Swagger-UI에서 파일 업로드하고 실행해보면 서버에는 업로드 된 파일의 이름이 출력되는 것을 확인

첨부파일 저장

실제로 파일을 저장할 때는 같은 이름의 파일이 문제가 됩니다.
이 문제를 해결하고자 가장 많이 사용하는 방법은 java.util.UUID를 이용해서 새로운 값을 만들어내는 방법입니다. (UUID는 중복될 가능성이 거의 없는 코드 값을 생성합니다.)

UUID(16자리) + _ + 원래 파일명

multipartFile의 transferTo 메서드는 업로드된 파일을 서버의 파일 시스템에 저장할 수 있습니다.
괄호 안에는 실제로 파일을 저장할 경로를 지정해줍니다.

Upload 폴더에 UUID 문자열을 포함한 파일들이 생성되는지 확인합니다.
업로드 결과를 확인할 때는 원본과 업로드 결과 파일의 크기가 같은지 확인하도록 합니다


Thumbnail 파일 처리

첨부파일이 이미지 일때는 용량을 줄여서 작은 이미지(이하 섬네일)을 생성하고 이를 나중에 사용하도록 구성해야만 합니다. 이를 처리하기 위해서 Thumbnailator 라이브러리를 이용하도록 합니다.

build.gradle에 Thumbnailator 라이브러리를 추가

섬네일 이미지는 업로드하는 파일이 이미지일 때만 처리하도록 구성해야 하고, 파일 이름은 맨 앞에 's_'로 시작하도록 구성합니다.

upload() 메소드 일부를 다음과 같이 수정해서 해당 파일이 이미지 파일이라면 섬네일을 생성하도록 구성합니다.

Files.probeContentType(savePath): savePath에 해당하는 파일의 MIME 타입을 확인합니다. 이를 통해 파일이 어떤 종류의 파일인지를 판별할 수 있습니다.

Thumbnailator.createThumbnail(sourceFile, targetFile, width, height): Thumbnailator 라이브러리를 사용하여 이미지 파일의 썸네일을 생성합니다. sourceFile은 원본 파일, targetFile은 썸네일 파일, width와 height는 썸네일의 가로 및 세로 크기를 나타냅니다.

수정된 코드를 반영하면 다음과 같이 's_'로 시작하는 썸네일 파일이 생성된 것을 확인 가능

MIME에 대해서는 아래 링크를 참조했습니다.
https://velog.io/@aerirang647/MIME-type%EC%9D%B4%EB%9E%80

업로드 결과의 반환 처리

여러 개의 파일이 업로드 되면 업로드 결과도 여러개 발생, 여러 정보를 반환해야 하므로
별도의 DTO를 구성해서 반환하도록 할 것

  • dto의 upload 패키지에 UploadResultDTO 클래스를 구성
  • UploadResultDTO는 업로드 된 파일의 UUID값과 파일 이름(fileName), 이미지 여부를 객체로 구성하고 getLink()를 통해서 첨부 파일의 경로 처리에 사용

UploadResultDTO 구성하기

UploadResultDTO의 getLink()는 나중에 JSON으로 처리될 때는 link라는 속성으로 자동 처리됩니다.
즉, 이 DTO 객체가 JSON으로 변환되면 JSON 객체에 link라는 키가 추가되고, 그 값은 getLink 메서드의 반환값이 됩니다.

"link라는 속성으로 자동 처리 된다"라는 말을 좀 더 이해하자면

  • 여기서 getLink 메서드는 img 속성이 true이면 이미지인 경우이므로 섬네일 파일명을 반환하고, false이면 이미지가 아니므로 원본 파일명을 반환합니다.

예를 들어, 만약 UploadResultDTO 객체가 다음과 같다면:

UploadResultDTO resultDTO = new UploadResultDTO("1234", "example.jpg", true);

  • 이 객체가 JSON으로 변환될 때는 다음과 같은 형태가 될 것입니다:

즉, getLink 메서드의 반환값이 JSON 객체의 link 속성으로 자동 매핑되어 클라이언트에 전달될 것입니다.

UploadController의 upload()는 List를 반환하도록 수정


Swagger UI로 업로드 결과를 확인하면 다음과 같이 JSON 데이터가 생성된 것을 확인할 수 있습니다(getLink() 대신에 link라는 속성이 생긴 것을 확인)

첨부파일 조회

첨부파일 조회는 가능하면 GET 방식으로 바로 가능하도록 설정합니다.
첨부파일은 나중에 보안 문제가 발생하므로 코드를 통해서 접근 여부를 허용하도록 컨트롤러를 이용하는 것이 좋습니다.

  • 첨부파일을 조회할 때는 '/views/파일이름'으로 동작하도록 UpDownController에 구성

  • UpDownController에는 viewFileGET()메서드를 다음과 같이 추가

    첨부파일 삭제

    첨부파일을 삭제할 때 해당 파일이 이미지라면 썸네일이 존재할 수 있으므로 같이 삭제하도록 구현합니다

    -UpDowncontroller에는 removeFile()을 다음과 같이 작성

0개의 댓글