Spring Boot에서 Summernote 이미지 업로드

·2020년 5월 15일
0

Spring

목록 보기
1/1

CKEditor5 사용 해보려다가.. 이미지 업로딩에 문제가 있어서 Summernote로 바꿔봤는데 괜찮은것같다.

우선 본인은 기존 부트스트랩 CSS와 겹치지 않는 lite버전을 사용했다.

프론트단에서 파일 업로드를 위한 코드를 서머노트 구현부분 콜백에 작성해준다.

$('#content').summernote({
            minHeight: 500,             // 최소 높이
            maxHeight: null,             // 최대 높이
            focus: true,                  // 에디터 로딩후 포커스를 맞출지 여부
            lang: "ko-KR",					// 한글 설정
            spellCheck: false,
            **callbacks: {	//이미지 첨부하는 부분
               onImageUpload : function(files) {
                    uploadSummernoteImageFile(files[0],this);
                }
            }**
        });

그리고 콜백에서 사용하는 onImageUpload ajax 함수를 구현한다.

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) {
                    //항상 업로드된 파일의 url이 있어야 한다.
                    $(editor).summernote('insertImage', data.url);
                }
            });
        }

이것으로 프론트에서 설정하는 이미지 업로드 구현 설정이 끝났다. 앞으로는 백스테이지에서 작동하는 코드를 구현할 차례다.

  1. 이미지 업로드를 하기 위해서는 JSON을 리턴하기 위해 gson을 사용해야 하므로 의존성을 추가해야 한다.
compile group: 'commons-io', name: 'commons-io', version: '2.6'
compile group: 'com.google.code.gson', name: 'gson', version: '2.8.6'
  1. application.properties에 json 컨버터를 gson으로 세팅한다.
spring.http.converters.preferred-json-mapper=gson
  1. 컨트롤러에서 파일 업로드 구현
import com.google.gson.JsonObject;
import org.apache.commons.io.FileUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.UUID;


@Controller
public class FileManageController {

    @PostMapping(value="/uploadSummernoteImageFile", produces = "application/json")
    @ResponseBody
    public JsonObject uploadSummernoteImageFile(@RequestParam("file") MultipartFile multipartFile) {

        JsonObject jsonObject = new JsonObject();

        String fileRoot = "C:\\summernote_image\\";	//저장될 파일 경로
        String originalFileName = multipartFile.getOriginalFilename();	//오리지날 파일명
        String extension = originalFileName.substring(originalFileName.lastIndexOf("."));	//파일 확장자

        // 랜덤 UUID+확장자로 저장될 savedFileName
        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();
        }

        return jsonObject;
    }

}
  1. 외부 리소스에 접근하기 위한 설정
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
    //web root가 아닌 외부 경로에 있는 리소스를 url로 불러올 수 있도록 설정
    //현재 localhost:8080/summernoteImage/1234.jpg
    //로 접속하면 C:/summernote_image/1234.jpg 파일을 불러온다.
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/summernoteImage/**")
                .addResourceLocations("file:///C:/summernote_image/");
    }
}

이렇게 이미지 업로드 로직을 완성했다.

이미지 파일 Drag & Drop으로 업로드가 안될 경우 html&jsp에 다음 코드를 추가한다.

$("div.note-editable").on('drop',function(e){
         for(i=0; i< e.originalEvent.dataTransfer.files.length; i++){
         	uploadSummernoteImageFile(e.originalEvent.dataTransfer.files[i],$("#summernote")[0]);
         }
        e.preventDefault();
   })


완성!

Summernote의 기본 이미지 업로딩 방식은 Data URL Scheme으로 저장되어 실제 서비스에 사용하기엔 무리가 있다. 불러올 때 매우매우 느려지기 때문에 웬만하면 따로 이미지 업로드 로직을 추가하는것이 좋을것같다...

profile
안녕하세요

0개의 댓글