class 29 - 파일 업로드 / summer note

yoneeki·2023년 3월 15일
0

training-jp

목록 보기
19/31

Summer Note

  • 부트스트랩과 함께 게시판 글 작성 기능에 디자인 기능 및 편의를 제공하는 라이브러리
  • 특히 파일을 추가해야 하는 경우에 유용
  • SQL에서 contents를 받는 컬럼을 clob으로 설정해야 한다 (자료 그 자체로 저장됨).

jsp 단

  • ajax 부분에서 .... contentType:false 의 의미는 인코딩이 multipart/form-data라는 것이다. (디폴트가 true => enctype="x-www-form-urlencoded")
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>섬머노트</title>
    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
    <link href="https://fonts.googleapis.com/css2?family=Lato:wght@100;300;400;700;900&family=Noto+Sans+KR:wght@100;300;400;500;700;900&display=swap" rel="stylesheet">
    <link rel="stylesheet" href="../css/reset.css">
    <link rel="stylesheet" href="../css/common.css">
    <link rel="stylesheet" href="../css/layout.css">
    
    <script src="../js/jquery-3.6.3.min.js"></script>
    <link href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
	<script src="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
    
    <script src="//t1.daumcdn.net/mapjsapi/bundle/postcode/prod/postcode.v2.js"></script>
    
    <link href="../summernote/summernote.min.css" rel="stylesheet">
	<script src="../summernote/summernote.min.js"></script>
    
    <!-- 
    	섬머노트
    	부트스트랩이 있어야 한다.
     -->
    
  </head>
  <body>
    <header id="header" class="header">
      <h1 id="logo">
        <a href="index.jsp">JJANG'S MEDIA LAB</a>
      </h1>
      <nav id="gnb">
        <h2 class="hidden">global navigation</h2>
        <ul class="list">
          <li><a href="">회원가입</a></li>
          <li><a href="">로그인</a></li>
          <li><a href="">게시판</a></li>
        </ul>
      </nav>
    </header>
    
<main>
	<form class="form" action="../board/writeProcess" method="POST">
		<table class="board">
			<colgroup>
				<col style="width:20%">
				<col style="width:80%">
			</colgroup>
			<tbody>
				<tr>
					<th>이름</th>
					<td><input type="text" name="userName"></td>
				</tr>
				<tr>
					<th>내용</th>
					<td>
						<textarea name="contents" id="summernote"></textarea>
					</td>
				</tr>
			</tbody>
		</table>
		<div class="btns">
			<button class="btn confirm">확인</button>
			<button class="btn reset" type="reset">취소</button>
		</div>
	</form>
</main>
<script>
	$("#summernote").summernote({
		height:300,
		// 섬머노트에서 제공하는 이벤트 처리 하는 곳
        // 왜 for문? 다중 이미지 처리.
		callbacks:{
			onImageUpload:function(files) {
				console.log("이미지 첨부 됨");
				console.log(files);
				for(let i=0;i<files.length;i++){
					uploadImage(files[i],this);
				}
			}
		}
	})
	// form으로 데이터 보내기(get, post), queryString(주소창에 값 실어 보내기... get)
	function uploadImage(file,editor) {
		
		const sendData = new FormData();  // key:value  <form><input type="file" name="uploadFile"></form>
		sendData.append("uploadFile",file);
		console.log(sendData);
		$.ajax({
			url:"../board/summernoteFileUpload",
			type:"POST",
			data:sendData,
			contentType:false, // true=> enctype="x-www-form-urlencoded" 를 쓰지 않겠다.  false =>  multipart/form-data
			processData:false,  // QueryString으로 날아가는걸 막겠다.
			success:function(response) {
				//위에 있는 url에서 응답을 기대하고 있음...
				console.log(response);
				$(editor).summernote("editor.insertImage",response.fileUrl);
			},
			error:function() {
				console.log("파일 업로드 실패");
			}
		})
	}
</script>
<footer class="footer">
    	<address>
    		<p>all copyrights reserved by ----</p>
    	</address>
    </footer>
  </body>
</html>

서블릿 단

import java.io.File;
import java.io.IOException;
import java.util.HashMap;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.google.gson.Gson;
import com.jjang051.utils.ScriptWriter;
import com.oreilly.servlet.MultipartRequest;
import com.oreilly.servlet.multipart.DefaultFileRenamePolicy;
@WebServlet("/board/summernoteFileUpload")
public class FileUploadController extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    public FileUploadController() {
        super();
    }

	protected void service(HttpServletRequest request, 
			HttpServletResponse response) throws ServletException, IOException {
		request.setCharacterEncoding("UTF-8");
		
		
		int maxFileSize = 1024*1024*50; // 50메가
		String encoding = "UTF-8";
		DefaultFileRenamePolicy fileRenamePolicy = new DefaultFileRenamePolicy();
		
		String savePath = "summerNoteUpload";// 저장할 폴더 이름
		ServletContext context = this.getServletContext();
		String realPath = context.getRealPath(savePath);
		File dir = new File(realPath);
		if(!dir.exists()) {
			dir.mkdir();
		}
		MultipartRequest mutipartRequest = 
				new MultipartRequest(request, realPath, maxFileSize, 
						encoding, fileRenamePolicy);
		
		String fileRealName = 
				mutipartRequest.getFilesystemName("uploadFile"); // 중복된 이름 처리하는 곳
		
		
		System.out.println(fileRealName);
		
		
		String fileUploadedUrl =  
				"/jsp10_board_summernote/"+savePath+"/"+fileRealName;
		HashMap<String, String> fileUrlMap = new HashMap<>();
		fileUrlMap.put("fileUrl",fileUploadedUrl);
		Gson gson = new Gson();
		String fileUrl = gson.toJson(fileUrlMap);
		request.setAttribute("fileUrl", fileUrl);
		RequestDispatcher dispatcher = 
		request.getRequestDispatcher("/WEB-INF/board/summernoteFileUpload.jsp");
		dispatcher.forward(request, response);
		//json으로 응답예정
		
	}
}

서블릿의 response를 받는 jsp

<%@ page language="java" contentType="application/json; charset=UTF-8"
    pageEncoding="UTF-8"%>
    ${fileUrl }
  • 서블릿이 날리는 request는 이미지가 저장된 파일 경로에 관련한다.
  • 그 요청을 이 jsp가 받아 response에 띄우면 앞서 wrtie단의 jsp에 있는 ajax의 success부분이 response를 처리하여, 이미지를 화면에 띄울 수 있게 된다.
profile
Working Abroad ...

0개의 댓글