해당 게시물은 본인의 이해를 바탕으로 작성되었으므로 틀린 부분이 있을 수 있습니다.
댓글로 알려주신다면 감사하겠습니다!
----------------------------------------------------
Spring이든 summernote든 전혀 봄과 여름 같지 않았다. 이를 완벽하게 사용하기에는 아직 어려워서 Winter나 blizzardnote라고 해야하지 않을까(웃음). 하지만 이해하고 알아가면 알아갈수록 잘만 사용한다면 개발자에게 봄바람과 여름바다와 같은 훌륭한 도구가 될 것이라는 생각이 든다. 만든 사람들 대단하다.
이 글은 기본적인 썸머노트 연결법은 제외하며 <textarea>가 썸머노트 에디터로 작동하는 상황을 기준으로 한다.
🧀 썸대노트의 이미지 업로드 동작 원리 이해
<p>아아 이것이 썸머노트인가</p><p><img style="width: 25%;" src="/resources/image/summerImageFiles/20220918162246.png"></p><p><span style="background-color: rgb(255, 255, 0);">아름다운 사진</span></p><p><img style="width: 25%;" src="/resources/image/summerImageFiles/20220918162312.png"><br></p>
위는 썸머노트가 적용된 <textarea>의 value가 DB에 저장된 것이다. 썸머노트에디터 속에서 작성된 내용이 HTML통째로 DB에 저장되기 때문에 다시 화면에 출력할 때 작성하였던 형태 그대로 뽑아낼 수가 있다.
녹색 밑줄을 친 이미지 태그의 경로는 콜백함수의 ajax와 매핑된 컨트롤러에서 직접 설정하고 다시 json객체에 담아 서머노트 에디터에 'insertImage'의 값으로 전달한 값이다.
썸대노트를 이용하여 글 작성 시 이미지를 업로드하면,
썸머노트 에디터 속에 업로드한 이미지가 나타난다. (흔히 블로그를 작성할 때 사용하는 에디터와 같다)
이는 이미지를 업로드하는 순간에 어딘가에 이미지가 저장되었고 저장된 이미지의 경로를 다시 에디터 속으로 가져온 것이다. (ajax의 비동기 기능을 이용한 것)
🧀 썸머노트의 이미지 업로드 동작
1. 썸머노트의 에디터에서 이미지를 업로드하는 이벤트가 발생했을 때.
1-1. <script>태그의 .summernote({}); 에 callbacks 프로퍼티가 없다면 -> 썸머노트 자체 로직으로 이미지 업로드 작동.
1-2. callbacks프로퍼티가 있다면 -> 콜백함수 실행(onImageUpload, onPaste 등)
2. 어딘가에 저장되는 이미지 파일
2-1 썸머노트 자체적으로 어딘가에 이미지를 저장하고 불러온다.
2-2 개발자가 컨트롤러에서 직접 이미지가 저장되는 경로를 설정할 수 있다.
🧀 목적: 썸머노트로 업로드한 이미지를 썸네일 이미지로 사용하기
목적은 썸머노트로 업로드한 이미지를 썸네일로 사용하기 위하여 이미지를 원하는 경로에 저장하고, 그 경로와 파일명을 DB에 저장하는 것이다. 이를 위해 건드리는 부분은 다음과 같다.
1. 스크립트 부분
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
<script>
$(document).ready(function(){
$('#summernote').summernote({
height : 300,
width : 700,
lang : "ko-KR",
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",
dataType:"JSON",
contentType:false,
processData:false,
success:function(data){
$(editor).summernote("insertImage",data.url);
$("#thumbnailPath").append("<option value="+data.url+">"+data.originName+"</option>");
}
});
}
});
</script>
|
cs |
2.컨트롤러 부분 (gson, io 라이브러리 pom.xml추가 후)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
@ResponseBody
@RequestMapping(value="/uploadSummernoteImageFile",method=RequestMethod.POST)
public JsonObject uploadSummernoteImageFile(@RequestParam("file") MultipartFile multipartFile,
HttpServletRequest request) {
JsonObject jsonObject = new JsonObject();
//파일저장 외부 경로, 파일명, 저장할 파일명
try {
String originalFileName = multipartFile.getOriginalFilename();
String root = request.getSession().getServletContext().getRealPath("resources");
String savePath = root + "\\image\\review\\summerImageFiles";
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
String extension = originalFileName.substring(originalFileName.lastIndexOf(".")+1);
String boardFileRename = sdf.format(new Date(System.currentTimeMillis())) + "." + extension;
File targetFile = new File(savePath);
if(!targetFile.exists()) {
targetFile.mkdir();
}
multipartFile.transferTo(new File(savePath+"\\"+boardFileRename));
System.out.println(savePath);
jsonObject.addProperty("url","/resources/image/review/summerImageFiles/"+boardFileRename);
jsonObject.addProperty("originName",originalFileName);
jsonObject.addProperty("reponseCode","success");
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return jsonObject;
}
|
cs |
files
썸머노트에 업로드한 이미지 파일은 Formdata에 추가되어 컨트롤러로 전해지고
컨트롤러에서는 @RequestParam으로 이를 받아서 사용한다. 한 번에 한 장 씩 업로드를 하기 때문에 files[0]으로 이미지 파일을 가져왔다. 가지고 온 파일을 원하는 경로에 저장하고 저장한 경로+파일명을 썸머노트로 보내준다.
"/uploadSummernoteImageFile"
ajax에서 서버로 보내는 json의 url로 컨트롤러에 매핑된다.
jsonObject
컨트롤러에서 다시 화면으로 보내는 json객체이다. @ResponseBody 어노테이션이 붙은 컨트롤러의 메소드는
뷰리졸버가 아닌 화면으로 리턴한다. 이 json객체의 url프로퍼티에 저장한 이미지의 경로와 파일명을 담아 보낸다.
컨트롤러에서 반환하는 이 json객체는 화면단 ajax의 sucess함수의 data 매개값으로 들어간다.
data.url
컨트롤러에서 json에 담아서 보낸 파일의 경로는 화면단 ajax의 sucess함수에서 꺼내 사용할 수 있다.
이렇게하여 썸머노트로 업로드하는 이미지의 경로를 DB에 저장할 수 있게 되었다.
썸네일은 다음과 같이 셀렉트태그를 이용하여 에디터에 올린 사진 중에서 선택할 수 있도록 하였다.
$("#thumbnailPath").append("<option value="+data.url+">"+data.originName+"</option>");
ajax의 success 함수가 실행될 때마다 <select>태그의 하위에 <option>태그가 생기도록 한 것이고
최종적으로 작성한 글을 저장할 때 선택한 옵션값의 value(이미지파일의 경로)가 DB에 저장되도록 하였다.
🧀 해결해야할 문제
1. 게시물을 최종 저장하지 않고 에디터에 올려보는 것만으로 서버에 이미지가 저장되고 있다...
최종 저장하지 않은 경우에는 이렇게 저장된 임시 이미지파일들을 삭제하여야 한다.
2. DB는 한 게시물에 썸네일 컬럼을 한 개만 만들었고, 업로드한 다른 이미지파일의 경로는 DB에 저장하지 않았다.
(업로드할 이미지가 몇 개가 될 지 모르기 때문에 하나의 컬럼에 컴마 ',' 등으로 구분하여 경로들을 저장하고 이를 배열로 다루는 방법을 생각해보고 있다.)
게시물을 수정할 때 선택하였던 다른 이미지로 썸네일을 수정할 수 있도록 변경하여야 한다.
3.에디터에 올렸던 이미지파일을 에디터에서 지웠을 때 썸네일 선택용 <option>태그가 지워지도록 해야한다.
'개발 > 코딩' 카테고리의 다른 글
[프로그래머스] 0LV_모스부호(1) 재밌는 문제 (0) | 2023.06.10 |
---|---|
[프로젝트] 문서 제작 툴, 카카오오븐, ERDCloud,Diagram.net 바로가기 (0) | 2022.10.02 |
[썸머노트] 사용법을 알아보던 중 ajax, json에 대한 이해. (0) | 2022.09.17 |
[게시판 기능] 게시판 목록을 3열 종대로 만들기. (0) | 2022.09.17 |
[JSP] EL & JSTL 의 편리함 (0) | 2022.08.03 |