ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Sneakers Mania - Summernote 이미지 파일 업로드 시 고유 URL 생성
    Projects/Problem & Solution 2022. 1. 29. 12:09

    개요

    문제점

    Summernote는 이미지 파일 업로드 시 base64로 인코딩을 한 후 저장하는 방식이기 때문에, 보안성은 뛰어나지만 이미지 파일 관리가 매우 어렵다는 단점이 있다. 예를 들어서, 고화질의 이미지 파일을 업로드했을 때 DB의 용량을 많이 차지한다는 점과 해당 이미지 파일을 조회할 경우 업로드 시간이 많이 소요된다는 점이다.

     

    해결 방안

    Summernote가 제공하는 callback 함수를 이용하여, 이미지를 특정 경로에 업로드한 후 고유한 URL을 리턴하는 방식으로 해결해 보았다. 추가로, URL을 통한 외부 리소스 접근을 위해 톰캣 설정도 별도로 필요하다.


    구현 방법

    1. Summernote callback 함수
    <script>
        $('.summernote').summernote({
            placeholder: '내용을 입력해주세요.',
            tabsize: 2,
            height: 250,
            callbacks: {
                onImageUpload: function (files) {
                    uploadSummernoteImageFile(files[0], this);
                }
            }
        });
    
        function uploadSummernoteImageFile(file, editor) {
            data = new FormData();
            data.append("file", file);
    
            $.ajax({
                data: data,
                type: "POST",
                url: "/uploadSummernoteImageFile",
                contentType: false,
                processData: false,
                success: function (data) {
                    $(editor).summernote('insertImage', data.url);
                }
            });
        }
    </script>

    Summernote에서는 몇 개의 callback 함수를 지원한다.

    그중 onImageUpload 함수는 Summernote에 이미지를 업로드할 때마다 자동으로 실행되는 함수이다.

    이미지를 업로드할 때마다 onImageUpload 함수가 호출되며, 해당 이미지는 Ajax를 통해 컨트롤러로 전송되는 방식이다.

     

    2. 의존성 추가
    <!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
    <dependency>
        <groupId>commons-io</groupId>
        <artifactId>commons-io</artifactId>
        <version>2.6</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/com.google.code.gson/gson -->
    <dependency>
        <groupId>com.google.code.gson</groupId>
        <artifactId>gson</artifactId>
        <version>2.8.6</version>
    </dependency>

    파일 업로드 로직과 JSON을 리턴하기 위해 위와 같은 의존성을 추가한다.

     

    3. application.properties 설정
    spring.http.converters.preferred-json-mapper=gson

    JsonObject 리턴을 위해 application.properties 파일에 JSON 컨버터를 gson으로 설정한다.

    위 설정을 생략할 시 JsonObject를 리턴하면 오류가 발생하는 문제가 생긴다.

     

    4. Controller 내 파일 업로드 로직 구현
    @PostMapping(value = "/uploadSummernoteImageFile", produces = "application/json; charset=utf8")
    public JsonObject uploadSummernoteImageFile(@RequestParam("file") MultipartFile multipartFile, HttpServletRequest request) {
        JsonObject jsonObject = new JsonObject();
    
        String fileRoot = "C:\\summernote_image\\";   // 저장될 외부 파일 경로
        String originalFileName = multipartFile.getOriginalFilename();   // 오리지날 파일명
        String extension = originalFileName.substring(originalFileName.lastIndexOf("."));   // 파일 확장자
    
        String savedFileName = UUID.randomUUID() + extension;   // 저장될 파일명
    
        File targetFile = new File(fileRoot + savedFileName);
    
        try {
            InputStream fileStream = multipartFile.getInputStream();
            FileUtils.copyInputStreamToFile(fileStream, targetFile);   // 파일 저장
            jsonObject.addProperty("url", "/summernoteImage/" + savedFileName);
            jsonObject.addProperty("responseCode", "success");
    
        } catch (IOException e) {
            FileUtils.deleteQuietly(targetFile);   //저장된 파일 삭제
            jsonObject.addProperty("responseCode", "error");
            e.printStackTrace();
            e.printStackTrace();
        }
    
        return jsonObject;
    }

    이미지 업로드 시 호출되는 컨트롤러이다.

    해당 컨트롤러가 호출이 되면, 고유한 URL이 생성되며, 개발자가 지정한 외부 경로에 파일이 저장된다.

    이미지 파일이 외부 경로에 저장되면, 해당 파일의 URL이 JSON 형태로 리턴된다.

     

    5. 외부 리소스 경로 접근 설정
    @Configuration
    public class WebMvcConfig implements WebMvcConfigurer {
    
        @Override
        public void addResourceHandlers(ResourceHandlerRegistry registry) {
            registry.addResourceHandler("/summernoteImage/**")
                    .addResourceLocations("file:///C:/summernote_image/");
        }
    }

    외부 경로에 있는 리소스를 URL로 불러올 수 있도록 설정을 해주는 코드이다.

    예를 들어, localhost://8000/summernoteImage/1234.jpg로 접속을 하게 되면, C:/summernote_image/1234.jpg 파일을 불러온다.

     

    6. 이미지 파일 업로드

     

    Summernote에 이미지 파일을 업로드하게 되면, 위 사진과 같이 고유한 URL을 통해 생성됨을 확인할 수 있다.


     

    GitHub - qlsdud0604/sneakers-mania: 👟 신발 사진을 업로드하고 소통할 수 있는 커뮤니티

    👟 신발 사진을 업로드하고 소통할 수 있는 커뮤니티. Contribute to qlsdud0604/sneakers-mania development by creating an account on GitHub.

    github.com

     

    728x90

    댓글

Designed by Tistory.