본문 바로가기

웹 개발 한걸음

[Mybatis + Ajax] 게시판 글쓰기 구현해보기 + 썸머노트 추가

 

 

** 게시판 목록 만들기에 이어 이전 게시판 글쓰기 역시 Mybatis와 Ajax를 써서 코드를 바꾸어보았다.

 

** 사실 글쓰기가 많이 심플하여 웹에디터썸머노트(summernote)를 추가하였다. 

 


 

   1. WriteControl.java - doGet()   

@WebServlet("/write")
public class WriteControl extends HttpServlet{

	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
		HttpSession session = request.getSession();
		if(session.getAttribute("user")==null) {
			PrintWriter out = response.getWriter();
			out.println("<script>");
			out.println("alert('로그인 하세요.');"); 
			out.println("location.href='login2'");
			out.println("</script>");	
		}else {
			request.getRequestDispatcher("/WEB-INF/write.jsp").forward(request, response);
		}	
	}
}
  • 처음 글쓰기 요청이 들어오면 이쪽으로 온다. 
  • 글쓰기는 회원 전용이므로 세션에 유저정보가 없다면 로그인하도록 유도하고 있다면 forward시켜준다.
  • 저 로그인 확인 자바스크립트 부분을 빼려고 하는데 곧 수정 예정이다.

 


 

   2. write.jsp - html   

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">

<!-- Jquery를 해당 주소에서 가져와 사용할 수 있게 해주는 스크립트  -->
<script src="http://code.jquery.com/jquery-3.1.1.min.js"></script>
 
 <!-- CDN 파일 summernote css/js --> 
 <link href="https://cdn.jsdelivr.net/npm/summernote@0.8.18/dist/summernote.min.css" rel="stylesheet"> 
 <script src="https://cdn.jsdelivr.net/npm/summernote@0.8.18/dist/summernote.min.js"></script>
  <!-- CDN 한글화 -->
 <script src=" https://cdnjs.cloudflare.com/ajax/libs/summernote/0.8.18/lang/summernote-ko-KR.min.js"></script>

</head>
<body>
  <!-- 글쓰기 양식 -->
  <div class="container">
    <div class="row">
      <form>
      	<table class = "table table-striped" style="text-align : center; border-collapse:separate; border: 2px solid #dddddd">
          <thead>
         	 <tr>
        	  <th colspan="2" style="background-color:#eeeeee; text-align: center;">게시판 글쓰기 양식</th>
        	 </tr>
          </thead>	
          <tbody>
          	<tr>
         	 <td><input type="text" id="title" class="form-control" placeholder="글 제목" maxlength="50"></td>			
          	</tr>
        	<tr>	
           	 <td>
         	   <textarea class="form-control" id="content" placeholder="글 내용" name="summernote" maxlength="2048" style="height:350px;"></textarea>
            </td>			
          	</tr>
          </tbody>
        </table>
      <input type="button" id="write_button" class="btn btn-primary pull-right" value="글쓰기">
      </form>
    </div>
  </div>
</body>
</html>

 

  • 썸머노트를 사용하기 위해 js를 추가하려면 우선 두 가지 방법이 있다.
  • 썸머노트 홈페이지에서 js를 다운을 받고 jsp에서 추가해주거나 혹은 cdn으로 추가해준다. 

<!-- 로컬 파일 summernote css/js --> 
<!-- <script src="../4.surmmernote/lib/summernote-bs4.js"></script> -->
<!-- <link rel="stylesheet" href="../4.surmmernote/lib/summernote-bs4.css"> --> 

<!-- CDN 파일 summernote css/js --> 
<link href="https://cdn.jsdelivr.net/npm/summernote@0.8.18/dist/summernote.min.css" rel="stylesheet"> 
<script src="https://cdn.jsdelivr.net/npm/summernote@0.8.18/dist/summernote.min.js"></script> 

<!-- CDN 한글화 --> 
<script src=" https://cdnjs.cloudflare.com/ajax/libs/summernote/0.8.18/lang/summernote-ko-KR.min.js"></script> 

<!-- 로컬 파일 한글화 --> 
<!-- <script src="../4.surmmernote/lib/lang/summernote-ko-KR.min.js"></script> --> 
<!-- <script src="../4.surmmernote/lib/lang/summernote-ko-KR.js"></script> -->

 

  • cdn으로 추가하였는데 주의할 점은 jquery보다 더 뒤에 위치해야 오류가 나지 않는다. (필자는 이것 때문에 많은 오류가 발생하였다)
  • js를 추가했다면 엘레멘트에 썸머노트를 적용해야하는데 이 또한 2가지 방법이 있다.
  • textarea에 적용하는 방법과 div에 적용하는 방법이다. 
<!-- 1. textarea에 적용 -->
<form method="post">
  <textarea id="summernote"></textarea>
</form>
<!-- 2. div에 적용하는 방법 -->
<div id="summernote">Hello Summernote</div>
  • id가 반드시 summernote일 필요는 없고 다르다면 아래 자바스크립트 부분에서 해당 id값으로 바꿔주면 된다.

 

 


 

 

   3. write.jsp - javascript   

<script type="text/javascript">
	//썸머노트 적용과 기능 추가
	$(document).ready(function() {
		var toolbar = [
			    // 굵기, 기울임꼴, 밑줄,취소 선, 서식지우기
			    ['style', ['bold', 'italic', 'underline','strikethrough', 'clear']],
			    // 글자색
			    ['color', ['forecolor','color']],
			    // 표만들기
			    ['table', ['table']],
			    // 글머리 기호, 번호매기기, 문단정렬
			    ['para', ['ul', 'ol', 'paragraph']],
			    // 줄간격
			    ['height', ['height']],
			    // 그림첨부, 링크만들기, 동영상첨부
			    ['insert',['picture','link','video']],
			    // 코드보기, 확대해서보기, 도움말
			    ['view', ['codeview','fullscreen', 'help']]
			  ];
	
		var setting = {
	            height : 300,
	            minHeight : null,
	            maxHeight : null,
	            focus : true,
	            lang : 'ko-KR',
	            toolbar : toolbar,
	            callbacks : { //여기 부분이 이미지를 첨부하는 부분
	            onImageUpload : function(files, editor,
	            welEditable) {
	            for (var i = files.length - 1; i >= 0; i--) {
	            uploadSummernoteImageFile(files[i],
	            this);
	            		}
	            	}
	            }
	         };
	        $('#content').summernote(setting);
	 });
	
	//글쓰기 버튼 눌렀을시
	$("#write_button").click(function() {
		
		var title = $("#title").val();
		var content = $("#content").val();		
		
		if(title.length < 0){
			alert("제목을 입력해주세요.");
			$("#title").focus();
			return;
		}
		
		if(content.length < 0){
			alert("내용을 입력해주세요.");
			$("#content").focus();
			return;
		}
		
		if(title!=""&&content!=""){
			$.ajax({
				url:"./write",
				type:"post",
				dataType:"json",
				data : {
						"title" : title,
						"content" : content
					}
				
			}).done(function(data) {
				if(data.chk == 1){
					alert("글이 등록되었습니다.");
					location.href = "bbs2";
				}else{
					alert("등록이 실패했습니다.");
				}
			}).fail(function(err) {
				console.log(err);
			});	
		}
	});

</script>	

썸머노트를 적용하려면 간단하다. 자바스크립트 부분에 아래 코드만 적용해주면 된다.

$(document).ready(function() {
  $('#summernote').summernote();
});
  • 아까 말했듯 id는 summernote일 필요없고 다른 id일시 summernote 대신 적용할 div 혹은 textarea의 id를 넣어주면 된다. 
  • 필자는 적용할 textarea의 id가 content이므로 content로 넣었다.
  • 바로 위의 기본형 외로 추가적으로 옵션 셋팅을 적용할 수 있는데 옵션값들이 많아 다 정리는 못하고 아래 링크에서 자세하게 알 수 있다.

https://summernote.org/deep-dive/#custom-toolbar-popover

 

Summernote - Super Simple WYSIWYG editor

Super Simple WYSIWYG Editor on Bootstrap Summernote is a JavaScript library that helps you create WYSIWYG editors online.

summernote.org

  • 제목과 내용이 비었는지를 확인 후 이상없다면 ajax로 title과 content를 post방식으로 컨트롤러로 보낸다.
  • 통신 후 반환값이 1이라면 정상적으로 insert되어 글이 작성됐다는 의미이므로 알림과 함께 정상적으로 글이 작성됨을 확인할 수 있는 게시판으로 바로 이동해준다.

 

 

 


 

   4. WriteControl.java - doPost()   

@WebServlet("/write")
public class WriteControl extends HttpServlet{

	@Override
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

			String title = request.getParameter("title");
			String content = request.getParameter("content");
			
			HttpSession session = request.getSession();
			User user = (User) session.getAttribute("user");
			String userID = user.getUserID();

			BbsDAO2 bao = BbsDAO2.getInstance();
			
			int result = bao.write(title, userID, content);
			HashMap<String, String> map = new HashMap<String, String>();
			
			if(result == 1) {
				map.put("chk", "1");
			}else {
				map.put("chk", "0");
			}
			
			String gson = new Gson().toJson(map);
			response.getWriter().write(gson);
			
	}
}

 

  • 클라이언트로부터 입력받은 title과 content를 httpServletRequest로 여기서 받는다. 
  • 글 작성에 필요한 현재 로그인한 아이디인 userID를 세션으로부터 받고 title과 content와 함께 bbsDAO의 wirte메서드를 호출하는 인자로 넣는다.
  • 게시물 등록이 성공적으로 되었다면 1을, 실패하였다면 0을 반환할 것이다.
  • HashMap을 하나 만들어 chk값에 반환값을 넣어주고 호출했던 ajax에 응답으로 보낸다. 

 


 

   5. BbsDAO.java   

public class BbsDAO2 {

	private static BbsDAO2 bao;
	SqlSessionFactory factory;
	
	private BbsDAO2() {
		factory = MybatisConnector.getInstance().getFactory();
	}
	
	public static BbsDAO2 getInstance() {
		if(bao == null) {
			bao = new BbsDAO2();
		}
		return bao;
	}
	

	//마지막 글 번호 알아내서 다음 글 번호 만드는 메서드
	public int getNext() {
		
		SqlSession session = factory.openSession();
		int bbsID = session.selectOne("bbs.getNext");
		int id = 0;
		
		if(bbsID > 0  ) 
			id = bbsID+1;
		System.out.println(id);
		return id;
		
	}

	//글쓰기
	public int write(String title, String userID, String content) {
		
		SqlSession session = factory.openSession(true);
        
		Bbs bbs = new Bbs(getNext(), title, userID, "", content, 1);
		
		int result = 0;
		result = session.insert("bbs.write", bbs);
		System.out.println(result);
		
		return result;
	}	
}

d인자로 받은 title과 user과 userID, content로 VO인 Bbs객체를 만든다. 

bbs table

bbsID는 getNext메서드로 최신의 bbsID를 조회한 후 +1해주어 다음 bbsID를 만들어준 것을 넣고

작성 날짜인 bbsDate는 mapper에서 자체 함수인 now()를 사용할 것이므로 공백을 넣어주었다.

이렇게 만든 객체를 insert함수로 mapper에 전한다. 

이 때 주의할 점은 openSession에 true를 넣어주어야 자동커밋이 된다. 

 

[해결][Mybatis] insert 할 때 commit 안 됨

** 게시판 글쓰기 기능을 만드는 중에 분명 insert하기 직전까지의 값들도 확인했고 insert도 1을 반환하는 등 코드에 문제가 없다 생각했는데 정작 실제 DB 테이블에는 insert가 안되는 문제가 발생하

egu99.tistory.com

제대로 insert가 되었다면 1을 반환할 것이다. 호출한 컨트롤러로 반환해준다.

 

 


 

 

   6. bbsMapper.xml   

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="bbs">

  	<!-- 글쓰기 -->
  	<insert id="write" parameterType="Bbs">
  		insert into BBS values(#{bbsID},#{bbsTitle}, #{userID}, now() ,#{bbsContent}, 1);
  	</insert>
    
</mapper>

Bbs 객체를 파라미터로 받아 꽂아주고 insert문을 실행한다. 

날짜는 자체 메서드인 now로 해준다. 

제대로 insert가 되었다면 1을 아니라면 0을 반환할 것이다. 

 

 


 

 

   7. 결과화면    

 

 

♣ 참고 및 인용 :