본문 바로가기
세미프로젝트

세미 프로젝트[어디어디]

by juneMiller 2021. 11. 29.

서블릿과 JSP 를 이용하여 목적별 데이트 코스를 추천해 주는 웹을 개발하였다.

제가 맡은 기능은 사용자 간의 커뮤니티인 게시판을 만는 것이었습니다. 

Servlet, JSP 로 CRUD 게시판 구현, Ajax 를 통해 비동기식 댓글 CRUD 및

사이드 인기 게시글, 검색 부분을 구현하였습니다. 

 

부가기능으로 관리자가 공지한 글이 커뮤니티 상단에 노출 시켜, 드롭다운 방식으로 게시글을 조회 할 수 있습니다.

 

03. 게시글  상세페이지 및 댓글 입력 

	$(function(){
		selectTopList(); // 열자 마자 호출 하고 
		$(".thumbnail").click(function(){
				var bno = $(this).children().eq(0).val();
				location.href="<%=contextPath%>/detail.bo?bno="+bno;
			})
		
		 setInterval(selectTopList, 5000)
	 	 $("#thumbList").on("click",".thumb",function(){
			var bno = $(this).children().eq(0).val();
			location.href = "<%=contextPath%>/detail.bo?bno="+bno;
		}) 
	})

 

JSP 화면에서 클래스 이름으로 접근 .thumbnail  클릭하면 상세페이지로 이동 

 

boardDetailServlet

package semiProject.com.kh.board.controller;

import java.io.IOException;
import java.util.ArrayList;

import javax.servlet.RequestDispatcher;
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 semiProject.com.kh.board.model.service.BoardService;
import semiProject.com.kh.board.model.vo.Attachment;
import semiProject.com.kh.board.model.vo.Board;

/**
 * Servlet implementation class BoardDetailServlet
 */
@WebServlet("/detail.bo")
public class BoardDetailServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public BoardDetailServlet() {
        super();
        // TODO Auto-generated constructor stub
        
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
		int bno = Integer.parseInt(request.getParameter("bno"));
		
		Board b = new BoardService().selectBoard(bno);
		
		ArrayList<Attachment> fileList = new BoardService().selectThumbnail(bno);
		
		if( b != null ) {
			
			request.setAttribute("b", b);
			request.setAttribute("fileList", fileList);
			
			
			request.getRequestDispatcher("views/board/boardDetails.jsp").forward(request, response);
		}else {
       	 request.setAttribute("msg", "사진게시판 상세보기 실패하였습니다.");
       	 request.getRequestDispatcher("views/common/errorPage.jsp").forward(request, response);
        }
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}

화면에서 name 값 bno (boarad number) 를 가져와 객체에 인자로 넘겨 찾는다. 

 

Service

 

public Board selectBoard(int bno) {
		Connection conn = getConnection();
		
		int result = new BoardDao().increaseCount(conn,bno);
		
		Board b = null;
		if(result > 0) {
			commit(conn);
			b = new BoardDao().selectBoard(conn, bno);
		}else {
			rollback(conn);
		}
		return b;
		
	}



	public ArrayList<Attachment> selectThumbnail(int bno) {
		Connection conn = getConnection();
		
		ArrayList<Attachment> list = new BoardDao().selectThumbnail(conn, bno);
		close(conn);
		return list;
	}

bno 값으로 각각의 테이블에서 불러와야 하므로 두개 메소드로 나눠 보내진다. 

SelectBoard 안에서 조회수 증가처리 위해 두개로 나눠 보내진다. 

 

Dao

 

	public int increaseCount(Connection conn, int bno) {
		int result = 0;
		PreparedStatement pstmt = null;
		String sql = prop.getProperty("increaseCount");

		try {
			pstmt = conn.prepareStatement(sql);
			pstmt.setInt(1, bno);

			result = pstmt.executeUpdate();

		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			close(pstmt);

		}

		return result;
	}
    
    
    public Board selectBoard(Connection conn, int bno) {
		Board b = null;

		PreparedStatement pstmt = null;
		ResultSet rset = null;

		String sql = prop.getProperty("selectBoard");

		try {
			pstmt = conn.prepareStatement(sql);

			pstmt.setInt(1, bno); // 넘버로 조회해 온다.
			rset = pstmt.executeQuery();


			// 만약에 결과 값이 있으면
			if (rset.next()) {
				b = new Board(rset.getInt("BOARD_NO"), rset.getString("BOARD_TITLE"), rset.getString("BOARD_CONTENT"),
						rset.getString("USER_ID"), rset.getInt("COUNT"), rset.getDate("CREATE_DATE")

				);

			}

		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			close(rset);
			close(pstmt);

		}

		return b;
	}
    
    
    public ArrayList<Attachment> selectThumbnail(Connection conn, int bno) {

		ArrayList<Attachment> list = new ArrayList<>();

		PreparedStatement pstmt = null;
		ResultSet rset = null;
		String sql = prop.getProperty("selectAttachment");

		// selectAttachment=SELECT FILE_NO, ORIGIN_NAME, CHANGE_NAME FROM ATTACHMENT
		// WHERE REF_BNO=? AND STATUS='Y'

		try {
			pstmt = conn.prepareStatement(sql);
			pstmt.setInt(1, bno);
			rset = pstmt.executeQuery();

			while (rset.next()) {

				Attachment at = new Attachment();
				at.setFileNo(rset.getInt("FILE_NO"));
				at.setOriginName(rset.getString("ORIGIN_NAME"));
				at.setChangeName(rset.getString("CHANGE_NAME"));

				list.add(at);

			}
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			close(rset);
			close(pstmt);
		}
		return list;

	}

각 쿼리문을 받아온 bno 값으로 처리한다. 

 

쿼리문

 

selectBoard=SELECT BOARD_NO, BOARD_TITLE, BOARD_CONTENT, USER_ID, COUNT, CREATE_DATE FROM BOARD B JOIN MEMBER ON(BOARD_WRITER = USER_NO)WHERE B.STATUS = 'Y' AND BOARD_NO=?
increaseCount=UPDATE BOARD SET COUNT=COUNT+1 WHERE BOARD_NO=?
selectAttachment=SELECT FILE_NO, ORIGIN_NAME, CHANGE_NAME FROM ATTACHMENT WHERE REF_BNO=? AND STATUS='Y'

 

 

상세페이지 화면 

 

 

<div class="blog__details__comment__form">
                    
                     <% if(loginUser != null) { %> 
                     
                     <div class="blog__details__comment__title"><h4>댓글 달기</h4></div>
                     <div class="input-comment">
                     <textarea rows="5" id="replyContent" style="resize:none; width:100%;"></textarea>
                     </div>
                      <button type="submit" class="site-btn" id="addReply">댓글 등록</button>
                            
                      <% }else{ %> 
                            
                            <div class="input-comment">
                            <p>Comment</p>
                            <textarea rows="5" cols="90" id="replyContent" style="resize:none;" readonly="readonly" disabled>로그인한 사용자만 가능한 서비스입니다. 로그인 후 이용해주세요</textarea>
                            </div>
                            <button type="submit" class="site-btn" disabled>댓글 등록</button>
                            
                             <% } %> 
                             
                             
                     <!-- --댓글 달면 보여질 리스트  -->
                     <br><br>
                     <section class="content-item" id="comments">
							<div class="blog__item__text" id="replyListArea">
			                <div id="replyList"> <!-- 글이 선택되면 자동으로 댓들이 조회됨 --></div>
			                </div>
			         </section>
                             
                             
					</div> <!-- 코멘트 섹션 end  -->
                    
                    <!-- 수정 페이제 모달 -->
					<div class="modal fade" id="mml" role="dialog">
							<div class="modal-dialog">
								<div class="modal-content">
									<div class="modal-header">
										<button type="button" class="close" data-dismiss="modal">&times;</button>					
									</div>
									<div class="modal-body">
										<div class="form-group">
											<input class="form-control" type="hidden" id="replyNo" name="replyNo"  readonly>
										</div>
										<div class="form-group">
											<label for="reply_text">댓글 내용</label> <textarea class="form-control"
												id="updateContent" name="replyContent" style="height: 200px" ></textarea>
										</div>
										<div class="form-group">
										<label for="reply_writer">댓글 작성자</label> <input
												class="form-control" id="writer" name="replyWriter" readonly>
									</div>
								</div>
								<div class="modal-footer">
									<button type="button" class="btn btn-dark"
										data-dismiss="modal">닫기</button>
									<button type="button"  class="btn btn-success modalModBtn">수정</button>
										
								</div>
							</div>
						</div>
				 	</div>

 

댓글 관련 Ajax 통신 ( 리스트, 입력, 삭제, 수정) 

var rlist = [];
    $(function(){
		selectReplyList(); //글이 조회되면 댓글이조회 되어야 한다.
		
		$("#addReply").click(function(){
			
			if($("#replyContent").val() != "") {
			var content = $("#replyContent").val();
			var bno = <%=b.getBoardNo()%>;
			
			$.ajax({
				url:"rInsert.bo",
				type: "post",
				data: {
					content: content,
					bno:bno
					
				},
				success:function(status){
					if(status == "success"){
						selectReplyList();
						$("#replyContent").val(""); //컨테츠에 값으 초기화 함 
					}
				},error : function() {
					console.log("ajax 통신 실패  - 댓글 등록")
				}
			})
			
			}else{
				alert("댓글 내용을 입력하세요.")
			}
			})
		
		
		
		})
		
		//댓글 생성
		function selectReplyList(){
    		$("#replyList").empty(); //테이블을 비우고 
			
			$.ajax({
				url: "rList.bo",
				type: "get",
				data: {
					bno: <%=b.getBoardNo() %>

				},
				
				success : function(list){
					console.log(list);
					console.log("${loginUser.userId}")
					
					
				var value="";
		         $.each(list, function(i, obj){
	 	          rlist.push(obj);
				//for(var i in list){
					var rno = list[i].replyNo;
					var user = list[i].replyWriter;
					//console.log(user);
					value += '<br><br><p>'+
					'<input type="hidden" id="rno" name="rno" value="'+rno+'">'+
					list[i].replyContent+
					'<ul class="blog__item__widget">'+
					'<hr>'+
					'<li  class="no'+i+'">'+'<i class="fa fa-comment"> '+list[i].replyNo+'</i></li>'+
					'<li>'+'<i class="fa fa-clock-o">'+'</i>'
					+list[i].createDate+'</li>'+
					'<li>'+'<i class="fa fa-user">&nbsp;'+user+'</i>'
					+'</li>';
				
					if("${loginUser.userId}" == user){
						value +='<button class="reBtn" onclick="updateForm('+ rno +')" data-toggle="modal"  data-target="#mml" style="background-color: green;">수정</button>&nbsp;&nbsp;'+
						'<button class="reBtn" onclick="del('+ rno +')" style="background-color: gray;">삭제</button></ul>';
					}else{ 
						value += '<br><br><br></ul>';
					}
					
				 });
				$("#replyList").html(value);
				
				},
	            error:function(){
	               console.log("ajax 통신 실패 - 댓글 조회");
	            }
	            
	         })
	      }
  		  //댓글 삭제 
   		 function del(rno){
	    	if(confirm("정말 삭제 하시겠습니까?") == true){
	    		$.ajax({
	        		url: "deleteComment.bo",
	        		data : { 
	        			rno : rno
	        		},
	        		type: "post",
	        		
	        		success : function(result){
	        			
	        			console.log(result)
	        			selectReplyList();
	        			
	        		},
	        		error : function(e){
	        			console.log(e);
	        		}
	        	})
	    		}else{
	    		 return;
	    		}
	    	}
    

    	
	   function updateForm(rno){
		  
		    for(var i = 0; i< rlist.length; i++){
		    	
		    	 var text = rlist[i].replyContent;
				  var content = text.replace(/(<br>|<br\/>|<br \/>)/g, '\r\n');
			   if(rno == rlist[i].replyNo){
	 				$("#replyNo").val(rlist[i].replyNo);
	 				$("#updateContent").val(content);
	 				$("#writer").val(rlist[i].replyWriter); 
	 				}

	 		} 

			   
		   };
				
			    	
	   
	   
	   $(".modalModBtn").on("click", function(){
		   var replyNo = $("#replyNo").val();
		   var replyContent = $("#updateContent").val();
		   var content = replyContent.replace('\r\n', /(<br>|<br\/>|<br \/>)/g );
		   console.log(replyNo)
		   console.log(replyContent)
		   $.ajax({
			   url:"updateReply.bo",
			   type:"get",
			   data:{ replyNo : replyNo,
				      replyContent : content
				      },
				success : function(result){
				   console.log("결과"+result)
				   alert("댓글 수정 성공");
				   selectReplyList();
				   $("#mml").modal("hide");
				}
		   
		   });
		   
		   
	   });

 

ReplyListServlet 

package semiProject.com.kh.board.controller;

import java.io.IOException;
import java.util.ArrayList;

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.google.gson.GsonBuilder;

import semiProject.com.kh.board.model.service.BoardService;
import semiProject.com.kh.board.model.vo.Reply;

/**
 * Servlet implementation class ReplyListSerjvlet
 */
@WebServlet("/rList.bo")
public class ReplyListSerjvlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public ReplyListSerjvlet() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
		String boardNo = request.getParameter("bno");
		if(boardNo != null) 
		
		{
			
			int bno = Integer.parseInt(request.getParameter("bno"));
			ArrayList<Reply> list = new BoardService().selectRList(bno);
			
			response.setContentType("application/json; charset=utf-8");

			Gson gson = new GsonBuilder().setDateFormat("yyyy년MM월dd일").create();
			gson.toJson(list, response.getWriter());
			
		}
		
		
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}

bno로 받아온 자바 객체를 toJson 처리 해주는데 응답스트림에서 기록하기 위해 response.getWirter() 선언해 준다. 

 

 

ReplyInsertSerlvet

 

 

package semiProject.com.kh.board.controller;

import java.io.IOException;
import java.io.PrintWriter;

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 semiProject.com.kh.board.model.service.BoardService;
import semiProject.com.kh.board.model.vo.Reply;
import semiProject.com.kh.member.model.vo.Member;

/**
 * Servlet implementation class ReplyInsertServlet
 */
@WebServlet("/rInsert.bo")
public class ReplyInsertServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public ReplyInsertServlet() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
		String content = request.getParameter("content");
		int bno = Integer.parseInt(request.getParameter("bno"));
		
		int writer = ((Member)request.getSession().getAttribute("loginUser")).getUserNo();
		
		Reply r = new Reply();
		r.setReplyContent(content.replaceAll("\n", "<br>"));
		r.setRefBoardId(bno);
		r.setReplyWriter(String.valueOf(writer));
		
		int result = new BoardService().insertReply(r);
		
		
		PrintWriter out = response.getWriter();
		if(result > 0 ) {
			out.print("success");
		}else {
			out.print("fail");
		}
		
		out.flush();
		out.close();
		
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}

 

 

ReplyUpdateServlet

 

package semiProject.com.kh.board.controller;

import java.io.IOException;
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 semiProject.com.kh.board.model.service.BoardService;
import semiProject.com.kh.board.model.vo.Reply;
import semiProject.com.kh.member.model.vo.Member;

/**
 * Servlet implementation class ReplyUpdateServlet
 */
@WebServlet("/updateReply.bo")
public class ReplyUpdateServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public ReplyUpdateServlet() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
		String content = request.getParameter("replyContent");
		int rno = Integer.parseInt(request.getParameter("replyNo"));
	

		Reply r = new Reply();
		r.setReplyContent(content.replaceAll("\n", "<br>"));
		r.setReplyNo(rno);

		
		new BoardService().updateReply(r);
		

	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}