본문 바로가기
  • 개발하는 곰돌이
Development/Spring & Spring Boot

[Spring Boot] Kotlin 기반 Spring Boot 프로젝트에서 파일 업로드하기

by 개발하는 곰돌이 2022. 12. 23.

목차


    기본 환경

    • IntelliJ Ultimate 2022.3
    • Spring Boot 2.7.6
    • Kotlin 1.7.21(JDK 11)
    • Oracle 11g
    • Swagger 3.0.0
    • mybaitis 2.3.0
    Spring Boot 프로젝트에 Swagger 3.0.0을 적용하는 방법은 아래 포스트를 참고하면 된다.

    [Spring Boot] Kotlin 기반 Spring Boot 프로젝트에 Swagger 3.0.0 적용하기


    개요

    예제로 블로그에 글을 작성할 때 제목과 내용, 카테고리 일련번호와 파일 하나를 업로드하여 작성하는 API를 구현한다. Swagger를 통해 테스트하기 때문에 별도의 화면은 구성하지 않는다.


    Domain

    블로그의 글과 관련된 BoardDTO를 작성한다.

    data class BoardDTO(
        var seq: Int?,
        @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Seoul")
        var reg_time: LocalDateTime?,
        var category_id: Int?,
        var subject: String,
        var content: String,
        var thumbnail: String?,
        var view_cnt: Int?,
        var like_cnt: Int?
    ) {
        constructor(
            subject: String, 
            content: String, 
            category_id: Int?, 
            thumbnail: String?
        ) : this(
            null,
            null,
            category_id,
            subject,
            content,
            thumbnail,
            null,
            null
        )
    }

    Controller

    파일은 선택적으로 업로드해야 하므로 uploadFile은 required = false로 지정한다. 글 제목과 내용, 글을 분류할 카테고리 번호와 함께 업로드할 파일을 파라미터로 받는 write() 메소드를 작성한다. 글을 작성한 이후엔 작성한 글을 불러올 것이기 때문에 반환 타입은 BoardDTO로 한다.

    @Api(tags = ["블로그 API"], description = "블로그 글 관련 API")
    @RestController
    class BoardController(val boardMapper: BoardMapper) {
    
        @ApiOperation("글 작성")
        @ApiImplicitParams(
            ApiImplicitParam(name = "subject", value = "글 제목", required = true),
            ApiImplicitParam(name = "content", value = "글 내용", required = true),
            ApiImplicitParam(name = "category_id", value = "글을 분류할 카테고리의 일련번호")
        )
        @PostMapping("/write")
        fun write(
            @RequestParam subject: String,
            @RequestParam content: String,
            @RequestParam(required = false) category_id: Int?,
            @ApiParam("업로드 할 썸네일") @RequestPart(required = false) uploadFile: MultipartFile?
        ): BoardDTO? {
            val path = "D:\\blog\\img\\"
            Files.createDirectories(Paths.get(path))
            var filename: String? = null
    
            if (uploadFile?.isEmpty == false) {
                val extension = FilenameUtils.getExtension(uploadFile.originalFilename)
                val timemillis = System.currentTimeMillis()
                val random = IntRange(10000, 99999).random()
                filename = "${random}${timemillis}.$extension"
    
                uploadFile.transferTo(File("${path}${filename}"))
            }
            val document = BoardDTO(subject, content, category_id ?: 0, filename)
            boardMapper.write(document)
    
            return boardMapper.getDocument(document.seq ?: 0)
        }
    }

    write() 메소드의 동작 과정

    1. 업로드한 파일을 저장할 경로를 설정하고, 해당 경로가 존재하지 않으면 새로운 디렉토리를 만든다.
    2. uploadFile이 null이거나 빈 파일인지 체크하고 업로드한 파일이 빈 파일이 아니라면 업로드 과정을 수행한다.
      • 업로드한 파일의 확장자를 추출하고 현재 시간을 기준으로 무작위 파일명을 부여한 후 지정 경로에 파일을 전송한다. 무작위 파일명은 5자리의 무작위 숫자 뒤에 작성시간의 밀리초 단위를 붙여서 설정한다.
    3. BoardDTO 객체를 생성하여 글을 작성하고 작성된 글을 반환한다.

    Swagger로 테스트

    테스트는 설정해둔 Swagger에서 진행한다. Swagger 설정에 대해선 다음 링크를 참고하면 된다.

     

    [Spring Boot] Kotlin 기반 Spring Boot 프로젝트에 Swagger 3.0.0 적용하기

    기본 환경 IntelliJ Ultimate 2022.3 Spring Boot 2.7.6 Kotlin 1.7.21(JVM 11) Swagger 3.0.0 목차 Swagger란? 1. 의존성 목록에 Swagger 라이브러리 추가 2. Swagger 기본 설정 3. Swagger 문서에서 API 등록 4. Swagger에 등록된 API

    colabear754.tistory.com

     

    글 작성 API를 테스트해보면 정상적으로 작성된 글이 반환된 것을 볼 수 있다.

    파일도 정상적으로 업로드 되었다.

    댓글