ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 게시판 만들기 - 6. 게시판의 게시글에 답글 달기
    JAVA/웹 프로그래밍 - JSP 2020. 11. 27. 18:42

    아래의 내용에 뒤이어 구현해보자.

    designatedroom87.tistory.com/324?category=901206

     

    게시판 만들기 - 5. DB에 저장한 게시글을 조회하고 읽기 가능하게 만들기

    게시글 나오게 하고, 글 읽기하고 조회한 게시물 증가를 구현하자. src/board.model/Board.java 파일에 수정이 필요하다. 기존에 날짜는 자료형을 String에서 Date로 수정한다. Board.java 더보기 package board.m..

    designatedroom87.tistory.com

     

    /board/read_fail.jsp 에 약간의 수정이 발생한다.

    read_fail.jsp

    더보기
    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <div>
    글 읽기 실패
    </div>

    /board/read.jsp에도 수정을 하나 한다. reply에서 replyForm으로 이름 변경 하자.

    read.jsp

    더보기
    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
        
    <div class="container">
      <h2><button class="btn" onclick="location.href='/index.jsp'"><i class="fa fa-home"></i></button>글읽기</h2>
         
        <div class="form-group">
          글번호: [${board.idx}] 제목: ${board.title}<p>
          작성자: ${board.write_name} 작성일: ${board.write_day} 조회수: ${board.readcount}<p>
        </div>
     
        <div class="form-group">
          <label for="content">내용:</label>
          <textarea class="form-control" disabled id="content" name="content" cols="80%" rows="10" placeholder="글을 입력하세요">
          ${board.content}
          </textarea>
        </div>
        
        <div class="form-group">
    	<button onclick="location.href='/board/list?requestPage=${requestPage}'">목록으로</button>
    	<button onclick="location.href='/board/replyForm?idx=${board.idx}&groupid=${board.groupid}&depth=${board.depth}&re_order=${board.re_order}&title=${board.title}&requestPage=${requestPage}'">답글쓰기</button>
    	<button onclick="location.href='/board/update?idx=${board.idx}'">글 수정</button>
    	<button onclick="location.href='board/delete.do?idx=${board.idx}'">글 삭제</button>
        </div>
     
    </div>

     

    답글쓰기를 구현해보자. 정말 핵 중요한 내용이다.

    답글쓰기에서는 입력받을 Form이 하나 필요하다.

    DB에서 데이터를 입력한다는 것보다는 새로운 폼에서 해당하는 내용에 말 그대로 답글을 쓰는 것이다.
    즉, 폼이 하나 열린다.

    read.jsp파일에서 답글쓰기 버튼을 선택하면, board.controller 패키지의 Controller에서 처리를 하도록 넘길 것이다.

    이는 Controller 내의 아래의 replyForm에서 처리할 것이다.

    (Controller의 내용은 맨 아래에 있다.)

    이는 replyForm.jsp 파일로 넘길 것이다.

    WEB-INF/board폴더에 replyForm.jsp파일을 만들자.

    replyForm.jsp 에서는 내용을 모두 입력을 하면 "댓글 달기" 버튼을 선택해서 댓글을 다는 작업을 한다.

    이 댓글의 작업은 Controller(앞으로 딱히 설명이 없으면 Controller는 board.controller의 컨트롤러이다.)

    의 reply.do에서 처리를 할 것이다.

    만약 취소 버튼을 선택하면 요청한 페이지(현재 보고 있는 페이지)를 볼 수 있는 상태인 Controller의 list 로 보낸다.

    아래가 Controller에서 취소 버튼을 선택했을 때의 처리할 조건이다.

     

    댓글 입력 페이지인 replyForm.jsp에서 "댓글 달기" 버튼이 눌리면 많은 정보가 Controller로 넘어간다.

    그룹아이디와 depth와 re_order,타이틀, 요청페이지를 넘긴다.
    컨트롤러에서는 필요한 정보들을 모두 넘겨받는다.

    "댓글 달기"버튼이 아닌 "취소" 버튼이 눌리면 현재 보고 있는 페이지(요청 페이지)를 보도록 Controller의 list로 넘긴다.

    우선 앞에서 설명한 내용에 대해 보충 설명을 하도록 한다.

    원글들은 idx와 groupid가 서로 일치한다.

    댓글의 idx는 글은 쓴 순서라고 볼 순 있어도, 댓글의 groupid는 부모 글(원 게시글)의 groupid를 따라 간다.

    replyForm.jsp

    더보기
    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    
    <script>
    function dataCheck(){
    	if(document.getElementById("title").value==""){
    		alert("제목을 입력해 주세요")
    		return;
    	}
    	if(document.getElementById("content").value==""){
    		alert("내용을 입력해 주세요")
    		return;
    	}
    	document.form.submit();
    }
    </script>
    
    <div class="container">
      <h2><button class="btn" onclick="location.href='/index'"><i class="fa fa-home"></i></button>댓글 달기</h2>
      <form name=form action="/board/reply.do" method=post>
        
        <div class="form-group">
          <label for="title">제목</label>
          <!-- 페이지에서 페이지로의 전달에서는 param이 가능 -->
          <input value="re:${param.title}" type="text" class="form-control" id="title" name="title" placeholder="제목을 입력 하세요">
        </div>
        
        <div class="form-group">
          <label for="write_name">작성자</label>
          <input value="${sessionScope.id}" type="text" class="form-control" id="write_name" name="write_name" readonly />
        </div>
        
        <div class="form-group">
          <label for="content">글내용</label>
          <textarea class="form-control" id="content" name="content" cols="80%" rows="10" placeholder="글을 입력하세요"></textarea>
        </div>
        
        <button type="button" onclick=dataCheck() class="btn btn-default">댓글달기</button>
        <!-- 취소 버튼을 누르면 다시 list로 이동. -->
        <button type="button" onclick="location.href='/board/list?requestPage=${param.requestPage}'" class="btn btn-default">취소</button>
        
      <!-- 댓글 달기 전의 정보(read.jsp)에 대해 숨겨둔 채 정보 전달. requestPage는 페이지를 표시할 때 필요 
      		parent_idx가 아주 중요하다. 부모글에 대한 정보이다. 즉, 댓글에서는 부모 댓글이 누구인지 아는 것이 중요하다.
      		어느 글의 댓글인지를 파악할 때 유용하다.
      -->  
      <!-- 처음 글은 idx와 groupid가 시퀸스의 nextval을 이용했지만, 댓글에서는 groupid에 대한 시퀸스 사용 안함-->
      <input type="hidden" name="parent_idx" value="${param.idx}" />
      <input type="hidden" name="groupid" value="${param.groupid}" />
      <input type="hidden" name="depth" value="${param.depth}" />
      <input type="hidden" name="re_order" value="${param.re_order}" />
      <input type="hidden" name="requestPage" value="${param.requestPage}" />
      <input type="hidden" name="write_id" value="${sessionScope.id}" />
    
      </form>
    </div>

     

    replyForm.jsp에서 댓글을 쓰고 "댓글달기" 버튼을 누르면 Controller의 reply.do에서 처리를 하는데,

    DB에대한 접속해서 이 댓글을 저장하는 일을 한다. 

    그런데 여기서 replyForm.jsp에서 댓글을 쓰고 컨트롤러에 넘길 정보가 많다.

    넘겨야 할 정보는 아래와 같다.

    댓글 달기 전의 정보(read.jsp)에 대해 숨겨둔 채 정보를 전달 한다.

    requestPage는 페이지를 표시할 때 필요하다. 

    예를 들어 2번 페이지에 어떤 글에 댓글을 달려다가 취소 버튼을 누르면 기존의 2번 페이지로 이동해야 하기 때문에
    요청 페이지에 대한 정보를 넘겨야 한다. 
    parent_idx가 아주 중요하다. 부모글에 대한 정보이다. 
    즉, 댓글에서는 부모 댓글이 누구인지 아는 것이 중요하다.
    어느 글의 댓글인지를 파악할 때 유용하다.
    처음 글은 idx와 groupid가 시퀸스의 nextval을 이용했지만, 댓글에서는 groupid에 대한 시퀸스 사용 안함.

    리플은 바로 저장하는 것이아니라 부모글이 삭제가 되었는지에 대한 확인 절차 작업이 필요하고

    (isdel 이라는 필드가 여기에서 사용된다.)
    삭제된 부모가 없으면 depth과 re_order를 변경해줘야 한다.
    부모가 리플인 경우도 있기 때문이다.
    부모에 대한 정보도 바뀌는 부분이 있다.

    Controller의 reply.do에서 해야할 작업이 길다. 우선 보자.

    댓글을 DB에 저장해야하는 작업을 해야 하므로, Service와 DAO 객체가 필요하다.

    그리고 이는 replyInsert함수를 통해 이루어 진다.

    만약 DB에 저장이 무사히 완료되면, 게시판의 글을 보여주는 list.jsp 파일로 이동하고

    만약 실패하면 reply_fail.jsp 파일로 이동을 하게 된다.

    두 클래스 모두에 이 함수를 정의한다.

    두 파일의 원본은 아래에 있다.

    아래는 BoardService.java에 정의한 함수이다.

    아래는 BoardDAO.java에 정의한 함수이다.

    replyInsert함수를 구현 하기 위해 보조 함수 2개가 필요하다. 아래를 보자.

    BoardService.java

    더보기
    package board.service;
    
    import board.dao.BoardDAO;
    import board.model.Board;
    import board.model.PageBoard;
    
    public class BoardService {
    	private static BoardService service = new BoardService();
    	public BoardDAO dao = BoardDAO.getInstance();
    	
    	private BoardService() {}
    	
    	public static BoardService getInstance(){return service;}
    	
    	//	글 입력
    	public int insert(String title, String content, String write_name) {
    		return dao.insert(title,content,write_name);
    	}
    	
    	//	글 입력
    	public int insert(Board board) {
    		return dao.insert(board);
    	}
    
    	public PageBoard list(int requestPage) {
    		return dao.list(requestPage);
    	}
    
    	public void incrementReadCount(int idx) {
    		dao.incrementReadCount(idx);
    	}
    
    	public Board selectById(int idx) {
    		return dao.selectById(idx);
    	}
    
    	public int replyInsert(Board board) {
    		return dao.replyInsert(board);
    	}
    }

     

    BoardDAO.java

    더보기
    package board.dao;
    
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.util.ArrayList;
    import java.util.List;
    
    import com.sun.net.httpserver.Authenticator.Result;
    
    import board.model.Board;
    import board.model.PageBoard;
    
    public class BoardDAO {
    	private static BoardDAO dao = new BoardDAO();
    	
    	private BoardDAO() {}
    	public static BoardDAO getInstance() {
    		return dao;
    	}
    	
    	public Connection connect()
    	{
    		Connection conn = null;
    		
    		try {
    		Class.forName("oracle.jdbc.driver.OracleDriver");
    		conn=DriverManager.getConnection(
    		"jdbc:oracle:thin:@localhost:1521:xe","hr","1234");
    
    		if(conn==null) {System.out.println("DB접속에 실패");}
    		System.out.println("DB접속 성공");
    		
    		}catch(Exception e) {}
    		
    		return conn;
    	}
    	
    	public void close(Connection conn, PreparedStatement pstmt, ResultSet rs)
    	{
    		if (rs != null) 
    		{
    			try 
    			{
    				rs.close();
    			}
    			catch (SQLException e) {e.printStackTrace();}
    		}
    		this.close(conn,pstmt);
    	}
    	
    	public void close(Connection conn, PreparedStatement pstmt)
    	{
    		try {
    		pstmt.close();
    		conn.close();
    		}
    		catch (SQLException e) {e.printStackTrace();}
    	}
    	
    	//	글 입력
    	public int insert(String title, String content, String write_name) {
    		Connection conn = null;
    		PreparedStatement pstmt = null;
    		int result = 0;
    		String sql = null;
    		
    		try {
    			conn = this.connect();
    			
    			conn.setAutoCommit(false);	//	DB 트랜잭션의 시작
    			
    			sql = "insert into board values(";
    			sql += "board_idx_seq.nextval,";
    			sql += "?,?,0,";
    			sql	+=	"board_groupid_seq.nextval,0,0,";
    			sql +=	"0,";
    			sql +=	"?,?,sysdate";
    			sql +=	")";
    			
    			pstmt = conn.prepareStatement(sql);
    			pstmt.setString(1, title);
    			pstmt.setString(2, content);
    			pstmt.setString(3, write_name);	//	id
    			pstmt.setString(4, write_name);	//	name
    			
    			result = pstmt.executeUpdate();
    			
    			if (result > 0) {
    				System.out.println("SQL 글 입력 성공");
    				conn.commit();
    			}else {
    				System.out.println("SQL 글 입력 실패");
    				conn.rollback();
    			}
    			this.close(conn, pstmt);
    		}
    		catch(Exception e) 
    		{	
    			try {
    				conn.rollback();
    			} catch (SQLException e1) {e1.printStackTrace();}
    		}
    		return result;
    	}
    	
    	//	글 입력
    	public int insert(Board board) {
    		Connection conn = null;
    		PreparedStatement pstmt = null;
    		int result = 0;
    		String sql = null;
    		
    		try {
    			conn = this.connect();
    			
    			conn.setAutoCommit(false);	//	DB 트랜잭션의 시작
    			
    			sql = "insert into board values(";
    			sql += "board_idx_seq.nextval,";
    			sql += "?,?,0,";
    			sql	+=	"board_groupid_seq.nextval,0,0,";
    			sql +=	"0,";
    			sql +=	"?,?,sysdate";
    			sql +=	")";
    			
    			pstmt = conn.prepareStatement(sql);
    			pstmt.setString(1, board.getTitle());
    			pstmt.setString(2, board.getContent());
    			pstmt.setString(3, board.getWrite_name());	//	id
    			pstmt.setString(4, board.getWrite_name());	//	name
    			
    			result = pstmt.executeUpdate();
    			
    			if (result > 0) {
    				System.out.println("SQL 글 입력 성공");
    				conn.commit();
    			}else {
    				System.out.println("SQL 글 입력 실패");
    				conn.rollback();
    			}
    			this.close(conn, pstmt);
    		}
    		catch(Exception e) 
    		{	
    			try {
    				conn.rollback();
    			} catch (SQLException e1) {e1.printStackTrace();}
    		}
    		return result;
    	}
    	public PageBoard list(int requestPage) 
    	{
    		Connection conn = null;
    		PreparedStatement pstmt = null;
    		ResultSet rs = null;
    		String sql = null;
    		List<Board> list = new ArrayList<Board>();	//	글 번호에 대한 리스트를 담는 객체
    		PageBoard pageboard = null;					//	페이지 정보와 리스트를 담는 객체
    		
    		//	페이지 관련 정보 사항
    		//int requestPage = 0;		//	요청한 페이지
    		int totalPage = 0;			//	전체 페이지
    		int beginPage = 0;			//	시작 페이지
    		int	endPage = 0;			//	마지막 페이지
    		int firstRow = 0;			//	시작 글번호
    		int endRow = 0;				//	끝 글번호
    		int articleCount = 0;		//	글의 전체 개수
    		int countPerPage = 10;		//	페이지 당 보여줄 글의 개수
    		
    		try {
    			System.out.println("-------BoardDAO-------------");
    			conn = this.connect();					//	DB접속
    			conn.setAutoCommit(false);
    			
    			//	페이지에 대한 정보
    			//	1. 전체 게시물 수 구하기(articleCount)
    			sql = "select count(*) from board";
    			pstmt = conn.prepareStatement(sql);
    			rs = pstmt.executeQuery();
    			if (rs.next()) {
    				articleCount = rs.getInt(1);
    			}
    			else {
    				articleCount = 0;
    			}
    			//rs.close();
    			//	2. 전체 페이지 수를 구하기(totalPage)
    			//	예를 들어 총 게시글이 71개이면, 총 페이지는 8개가 되야 한다.
    			totalPage = articleCount / countPerPage;
    			if (articleCount % countPerPage > 0)
    				totalPage += 1;
    			
    			//	3. 요청한 페이지에 대한 시작 글번호와 끝 글번호 구하기
    			firstRow = (requestPage - 1) * countPerPage + 1;
    			endRow = firstRow + countPerPage - 1; 
    			System.out.printf("firstRow : %d, endRow : %d\n",firstRow, endRow);
    			//	4. 시작 페이지 번호, 끝 페이지 번호(beginPage, endPage)
    			if (totalPage > 0) {
    				beginPage = (requestPage - 1) / countPerPage * countPerPage + 1;
    				//	beginPage = requestPage - 2;
    				endPage = beginPage + 4;	//	4는 요청 페이지를 기준으로 보여줄 페이지의 간격
    				
    				if (endPage > totalPage)	endPage = totalPage;
    			}
    			
    			//	5. 페이지에 해당하는 리스트(firstRow, endRow)
    			sql = "select idx, title, content, readcount, groupid, depth, re_order, isdel, write_id, write_name, write_day from (";
    			sql += "select rownum rnum, idx, title, content, readcount, groupid, depth, re_order, isdel, write_id, write_name, write_day from (";
    			sql += "select * from board a order by a.groupid desc, a.depth asc, a.idx asc) where rownum <= ?";
    			sql += ") where rnum >= ?";
    			pstmt = conn.prepareStatement(sql);
    			pstmt.setInt(1, endRow);	//	큰 수. 40이라고 가정
    			pstmt.setInt(2, firstRow);	//	작은 수. 31이라고 가정
    			rs = pstmt.executeQuery();
    			
    			//	6. DB의 리스트를 board객체에 담아 전송
    			while (rs.next()) {
    				Board board = new Board();
    				board.setIdx(rs.getInt("idx"));
    				board.setTitle(rs.getString("title"));
    				board.setContent(rs.getString("content"));
    				board.setReadcount(rs.getInt("readcount"));
    				board.setGroupid(rs.getInt("groupid"));
    				board.setDepth(rs.getInt("depth"));
    				board.setRe_order(rs.getInt("re_order"));
    				board.setIsdel(rs.getInt("isdel"));
    				board.setWrite_id(rs.getString("write_id"));
    				board.setWrite_name(rs.getString("write_name"));
    				board.setWrite_day(rs.getDate("write_day"));
    				
    				list.add(board);
    			}
    			
    			pageboard = new PageBoard(list, requestPage,totalPage,
    					beginPage, endPage, firstRow, endRow, articleCount,countPerPage
    					);
    			
    			this.close(conn, pstmt, rs);
    			conn.commit();
    		}
    		catch(Exception e) 
    		{
    			try {conn.rollback();} 
    			catch (SQLException e1) {e1.printStackTrace();} 
    			
    			e.printStackTrace();
    		}
    		System.out.println("-----end BoardDAO-------------");
    		return pageboard;
    	}
    	public void incrementReadCount(int idx) 
    	{
    		Connection conn = null;
    		PreparedStatement pstmt = null;
    		String sql = null;
    		
    		try {
    			conn = this.connect();
    			sql = "update board set readcount=readcount+1 where idx=?";
    			pstmt = conn.prepareStatement(sql);
    			pstmt.setInt(1, idx);
    			pstmt.executeUpdate();
    			
    			this.close(conn, pstmt);
    		}catch(Exception e){}
    	}
    	public Board selectById(int idx) 
    	{
    		Board board = null;
    		Connection conn = null;
    		PreparedStatement pstmt = null;
    		ResultSet rs = null;
    		String sql = null;
    		
    		try {
    			conn = this.connect();
    			//conn.setAutoCommit(false);
    			sql = "select * from board where idx=?";
    			pstmt = conn.prepareStatement(sql);
    			pstmt.setInt(1, idx);
    			rs = pstmt.executeQuery();
    			
    			if (rs.next())
    			{
    				board = new Board(
    						rs.getInt("idx"), 
    						rs.getString("title"), 
    						rs.getString("content"), 
    						rs.getInt("readcount"), 
    						rs.getInt("groupid"), 
    						rs.getInt("depth"), 
    						rs.getInt("re_order"), 
    						rs.getInt("isdel"), 
    						rs.getString("write_id"), 
    						rs.getString("write_name"), 
    						rs.getDate("write_day")
    						);
    			}	
    			//conn.commit();
    			this.close(conn, pstmt, rs);
    		}
    		catch(Exception e) 
    		{
    			try {conn.rollback();} 
    			catch (SQLException e1) {e1.printStackTrace();}
    		}
    		return board;
    	}
    	
    	//	replyInsert함수에서 이용
    	public boolean checkParent(int idx) 
    	{
    		Connection conn = null;
    		PreparedStatement pstmt = null;
    		ResultSet rs = null;
    		String sql = null;
    		int result = 0;
    		
    		try {
    			conn = this.connect();
    			
    			//	isdel이 0이면 삭제가 되지 않았다는 의미
    			sql = "select count(*) from board where idx=? and isdel=0";
    			pstmt = conn.prepareStatement(sql);
    			pstmt.setInt(1, idx);
    			rs = pstmt.executeQuery();
    			
    			if (rs.next()) 
    			{
    				result = rs.getInt(1);
    			}
    			if (result != 1)
    			{
    				//this.close(conn, pstmt, rs);
    				return false;
    			}
    			
    			this.close(conn, pstmt, rs);
    		}catch(Exception e) {}
    		
    		return true;
    	}
    	
    	//	replyInsert함수에서 이용
    	public void reply_before_update(int depth, int groupid) 
    	{
    		Connection conn = null;
    		PreparedStatement pstmt = null;
    		String sql = null;
    		
    		try {
    			conn = this.connect();
    			
    			//	isdel이 0이면 삭제가 되지 않았다는 의미
    			sql = "update board set depth=depth+1 where groupid=? and depth>?";
    			
    			pstmt = conn.prepareStatement(sql);
    			pstmt.setInt(1, groupid);
    			pstmt.setInt(2, depth);
    			
    			pstmt.executeUpdate();
    				
    			this.close(conn, pstmt);
    		}catch(Exception e) {}
    	}
    	
    	public int replyInsert(Board board) 
    	{
    		//	댓글은 
    		//		1. 부모 글이 존재하는지 여부 확인 checkParent(board.getIdx());
    		//		2. 댓글과 상관이 있는 글에 대해 groupid, depth, [re_order]값을 변경 - reply_before_update(depth,groupid);
    		//				re_order는 잘 안 바뀐다.
    		//		3. 댓글이 등록 - insert();
    		//	위의 조건에 따라 DB에 저장한다.
    		
    		Connection conn = null;
    		PreparedStatement pstmt = null;
    		String sql = null;
    		int result = 0;
    		
    		try {
    			conn = this.connect();
    			conn.setAutoCommit(false);			//	반드시 필요하다.
    			
    			//	부모 글의 존재여부 확인
    			if(!checkParent(board.getIdx())) 	//	board의 idx는 부모 idx이다.
    			{	
    				conn.rollback();
    				return 0;
    			}
    			System.out.println("부모글 확인");
    			
    			//	댓글과 관련된 글에 대해 업데이트
    			reply_before_update(board.getDepth(),board.getGroupid());
    			System.out.println("관련 댓글 입력 완료");
    			
    			//	insert 작업
    			sql = "insert into board values(";
    			sql += "board_idx_seq.nextval,";
    			sql += "?,?,0,";		//	1.title, 2.content, readcount
    			sql	+=	"?,?,?,";		//	3.groupid, 4.depth, 5.re_order
    			sql +=	"0,";			//	삭제 여부
    			sql +=	"?,?,sysdate";	//	6.write_id, 7.write_name, 8.날짜
    			sql +=	")";
    			
    			pstmt = conn.prepareStatement(sql);
    			pstmt.setString(1, board.getTitle());
    			pstmt.setString(2, board.getContent());
    			pstmt.setInt(3, board.getGroupid());
    			pstmt.setInt(4, board.getDepth());
    			pstmt.setInt(5, board.getRe_order());
    			pstmt.setString(6, board.getWrite_id());	//	id
    			pstmt.setString(7, board.getWrite_name());	//	name
    			//pstmt.setDate(8, (java.sql.Date)board.getWrite_day());
    			
    			result = pstmt.executeUpdate();
    			
    			if (result == 0) 
    			{
    				conn.rollback();
    				return 0;
    			}
    			else {conn.commit();}
    		}
    		catch(Exception e) 
    		{
    			try {
    				conn.rollback();
    			} catch (SQLException e1) {
    				// TODO Auto-generated catch block
    				e1.printStackTrace();
    			}
    		}
    		
    		return result;
    	}
    }

     

    아래의 reply_fail.jsp는 댓글 달기 실패했을 시에 보게될 페이지이다.

    WEB-INF/board에 파일을 만들자.

    reply_fail.jsp

    더보기
    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <div>
    댓글 입력 실패
    </div>

     

    Controller의 reply.do에서 댓글 달기가 성공하면 게시글 목록을 보여주는 list.jsp로 이동한다.

    /board/list.jsp에서 수정할 내용은 아래와 같다.

    리플이 달릴 때 보여줄 이미지를 저장할 폴더를 WebContent에 img폴더를 하나 만들자.

    그리고 리플에 어울리는 이미지를 하나 구해서 이 폴더에 저장하자.

    이름은 reply_icon.gif라 한다. (이름을 변경하기 싫으면 아래의 list.jsp에서 수정을 하자.)

    만약, 이미지 파일을 찾는 것이 귀찮다면, 

    img 태그있는 부분을 지우고 img 태그 아래의 문장인

    <c:forEach begin="1" end="${board.depth}">-</c:forEach>&gt; 문장의 주석을 제거하고 써도 된다.

    list.jsp

    더보기
    <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    
    <script>
    function dataCheck()
    {
    	if(document.getElementById("search").value == "")
    	{
    		alert("검색할 단어를 입력하세요");
    		document.getElementById("search").focus();
    		return;
    	}
    	document.form.submit();
    }
    </script>
    
    <!-- 로그인이 되지 않을 경우 페이지 이동 -->
    <c:if test="${empty sessionScope.id}">
    <jsp:forward page="/index"></jsp:forward>
    </c:if>
    <!-- ----------------- -->
    
    <div class="container">
     <h2><button class="btn" onclick="location.href='/index'"><i class="fa fa-home"></i></button>메시지 전체 리스트</h2>
    <!-- 검색리스트 -->
    <form name=form action="/board/searchList" method=post>
     	<div class="form-group">
     	
     	<select name=field>
     	<option value=title>제목</option>
     	<option value=content>내용</option>
     	<option value=write_name>작성자</option>
     	</select>
        
        <input onmouseover="this.focus()" type="text" id="search" name="search" placeholder="찾을 내용을 입력하세요">
        <button type="button" onclick=dataCheck() class="btn btn-default">검색</button>
        </div>
     </form>
    <!-- 검색리스트  -->
    
    <table class="table">
    <!-- 페이지번호 표시 -->
    <tr align="right">
    <td colspan="5">
    ${pageboard.articleCount-pageboard.firstRow+1}-${pageboard.articleCount-pageboard.endRow+1}
    [${pageboard.requestPage}/${pageboard.totalPage }]
    </td>
    </tr>
    
    <tr class="success">
    <th>번호</th><th>제목</th><th>작성자</th><th>작성일</th><th>조회수</th>
    </tr>
    <c:forEach var="board" items="${pageboard.list}">
    <tr onmouseover="this.style.backgroundColor='lightgray'" 
    	onmouseout="this.style.backgroundColor='white'"
    	onclick="location.href='/board/read?idx=${board.idx}&requestPage=${pageboard.requestPage}'">
    <td>${board.idx}</td>
    <td>
    <c:if test="${board.depth>0}">
    	<!-- &nbsp;는 하나의 공백 -->
    	<c:forEach begin="1" end="${board.depth}">&nbsp;&nbsp;&nbsp;</c:forEach><img style="width:42px; height:15px" src="/img/reply_icon.gif"/>
    	<!-- <c:forEach begin="1" end="${board.depth}">-</c:forEach>&gt; -->
    </c:if>
    ${board.title}
    
    </td>
    <td>${board.write_name}</td>
    <td>${board.write_day}</td>
    <td>${board.readcount}</td>
    </tr>
    </c:forEach>
    <!-- page list -->
    <tr>
    <td colspan=4 align=center valign="center">
    <ul class="pagination">
       
        <c:if test="${pageboard.requestPage!=1}">
        <li class="page-item"><a class="page-link" href="/board/list?requestPage=${pageboard.requestPage-1}">이전페이지</a></li>
        </c:if>
     
        <c:forEach var="i" begin="${pageboard.beginPage}" end="${pageboard.endPage}">
        <li class="page-item"><a class="page-link" href="/board/list?requestPage=${i}">${i}</a></li>
        </c:forEach>
       
        <c:if test="${pageboard.totalPage!=pageboard.requestPage}">
        <li class="page-item"><a class="page-link" href="/board/list?requestPage=${pageboard.requestPage+1}">다음페이지</a></li>
        </c:if>
        
      </ul>
    </td>
    <td>
    <button onclick="location.href='/board/insert'">글쓰기</button>
    </td>
    </tr>
    <!-- end page list -->
    </table>
    
    </div>

     

    그리고, board.controller의 Controller.java 내용이다.

    Controller.java

    더보기
    package board.controller;
    
    import java.io.IOException;
    import java.util.Date;
    
    import javax.servlet.RequestDispatcher;
    import javax.servlet.ServletConfig;
    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 javax.servlet.http.HttpSession;
    
    import board.model.Board;
    import board.model.PageBoard;
    import board.service.BoardService;
    
    //	member로 들어오는 모든 url에 대해서 해당 컨트로럴가 이에 대한 처리를 하겠다는 의미
    @WebServlet("/board/*")
    public class Controller extends HttpServlet {
    	private static final long serialVersionUID = 1L;
           
    	public void init(ServletConfig config) 
    			throws ServletException {}
    
    	protected void service(HttpServletRequest request, HttpServletResponse response) 
    			throws ServletException, IOException {
    	
    		request.setCharacterEncoding("UTF-8");		//	한글 깨짐 방지
    		//ServletContext application = request.getServletContext();	//	전역 객체
    		
    		//	페이지 페이지 마다 연결 시간 설정 가능. 전역 객체이다.
    		HttpSession session = request.getSession();					 
    		
    		//	1. 페이지를 전송하기 전에 url을 분석하고 분류해서 실행
    		String url = request.getRequestURI();
    		//System.out.println("url : " +url);
    		String contextPath = request.getContextPath();
    		//System.out.println("contextPath : " +contextPath);
    		String path = url.substring(contextPath.length());
    		//System.out.println("path : " +path);
    		String lastPath = url.substring(url.lastIndexOf('/') + 1);	//	마지막 /를 기준으로 분리
    		System.out.println("subPath : " +lastPath);
    		String command = lastPath;
    		
    		//	로그인 여부를 먼저 확인
    		if (session.getAttribute("id") != null) 
    		{
    			if (command.equals("board")) 
    			{
    				request.setAttribute("page", "list.jsp");
    			}
    			else if (command.equals("list")) 
    			{
    				//	폼에서 전송된 데이터 받기 request.getParameter()
    				String requestPage_ = request.getParameter("requestPage");
    				System.out.printf("%s\n",requestPage_);
    				int requestPage = 1;
    				if (requestPage_ != null) 
    				{
    					requestPage = Integer.parseInt(requestPage_);
    				}
    	
    				//	service-dao work
    				BoardService service = BoardService.getInstance();
    				PageBoard pageboard = new PageBoard();
    				pageboard = service.list(requestPage);
    				
    				request.setAttribute("pageboard", pageboard);
    				System.out.println(pageboard.getList().toString());
    				request.setAttribute("page", "list.jsp");
    			}
    			else if (command.equals("searchList")) 
    			{
    				String field = request.getParameter("field");
    				String search = request.getParameter("search");
    				System.out.printf("%s %s\n",field,search);
    				
    				request.setAttribute("page", "list.jsp");
    			}
    			//	글쓰기버튼이 눌리면
    			else if (command.equals("insert")) 
    			{
    				request.setAttribute("page", "writeForm.jsp");
    			}
    			else if (command.equals("insert.do")) 
    			{
    				String title = request.getParameter("title");
    				String content = request.getParameter("content");
    				String write_name = request.getParameter("write_name");
    				System.out.printf("%s %s %s\n",title,content,write_name);
    				
    				//	model을 적용하여 전송
    				Board board = new Board();
    				board.setTitle(title);
    				board.setContent(content);
    				board.setWrite_name(write_name);
    				//	model 적용 end
    				
    				BoardService service = BoardService.getInstance();
    				
    				//int result = service.insert(title,content,write_name);
    				int result = service.insert(board);
    				
    				if (result == 1)
    				{
    					System.out.println("글입력 성공");
    					
    					request.setAttribute("page", "success.jsp");
    				}
    				else 
    				{
    					System.out.println("글입력 실패");
    					
    					request.setAttribute("page", "fail.jsp");
    				}
    			}
    			else if (command.equals("read")) 
    			{
    				String idx_ = request.getParameter("idx");
    				String requestPage_ = request.getParameter("requestPage");
    				System.out.printf("%s %s\n",idx_,requestPage_);
    				
    				int requestPage = 1;
    				if (requestPage_ != null) 
    					requestPage = Integer.parseInt(requestPage_);
    				
    				int idx = 0;
    				if (idx_ != null) 
    				{
    					idx = Integer.parseInt(idx_);
    					
    					BoardService service = BoardService.getInstance();
    					//	조회수가 1증가하고 해당 글에 대해 view를 해주는 작업
    					service.incrementReadCount(idx);
    					Board board = service.selectById(idx);
    					
    					request.setAttribute("board",board);
    					request.setAttribute("requestPage",requestPage);
    					request.setAttribute("page", "read.jsp");
    				}
    				else{request.setAttribute("page", "read_fail.jsp");}
    			}			
    			else if (command.equals("replyForm")) 
    			{
    				request.setAttribute("page", "replyForm.jsp");
    			}
    			else if (command.equals("reply.do")) 
    			{	
    				String parent_idx = request.getParameter("parent_idx");
    				String groupid = request.getParameter("groupid");
    				String depth = request.getParameter("depth");
    				String re_order = request.getParameter("re_order");
    				String title = request.getParameter("title");
    				String content = request.getParameter("content");
    				String write_id = request.getParameter("write_id");
    				String write_name = request.getParameter("write_name");
    				String requestPage_ = request.getParameter("requestPage");
    				
    				System.out.printf("parent_idx : %s\n",parent_idx);
    				System.out.printf("groupid : %s\n",groupid);
    				System.out.printf("depth : %s\n",depth);
    				System.out.printf("re_order : %s\n",re_order);
    				System.out.printf("title : %s\n",title);
    				System.out.printf("content : %s\n",content);
    				System.out.printf("write_id : %s\n",write_id);
    				System.out.printf("write_name : %s\n",write_name);
    				System.out.printf("requestPage : %s\n",requestPage_);
    				
    				Board board = new Board();
    				board.setIdx(Integer.parseInt(parent_idx));	//	주의<DB에 입력 시, 사용 안함> 부모가 존재하는 여부 확인
    				board.setTitle(title);
    				board.setContent(content);
    				board.setGroupid(Integer.parseInt(groupid));
    				board.setDepth(Integer.parseInt(depth) + 1);		//	기존의 depth에 1을 추가
    				board.setRe_order(Integer.parseInt(re_order) + 1);	//	기존 re_order에 1을 추가	
    				board.setWrite_id(write_id);
    				board.setWrite_name(write_name);
    				board.setWrite_day(new Date());
    				
    				int requestPage = 1;
    				if (requestPage_ != null) 
    					requestPage = Integer.parseInt(requestPage_);
    				
    				BoardService service = BoardService.getInstance();
    				
    				//	댓글은 
    				//		1. 부모 글이 존재하는지 여부 확인
    				//		2. 댓글과 상관이 있는 글에 대해 groupid, depth, [re_order]값을 변경
    				//				re_order는 잘 안 바뀐다.
    				//		3. 댓글이 등록
    				//	위의 과정의 의해 처리한다.
    				
    				//	위의 과정은 DB에서 한 번에 처리를 한다.
    				int result = service.replyInsert(board);
    				//request.setAttribute("requestPage",requestPage);
    				
    				if (result > 0)		//	댓글 입력 성공
    				{
    					PageBoard pageboard = new PageBoard();
    					pageboard = service.list(requestPage);
    					request.setAttribute("pageboard", pageboard);
    					
    					request.setAttribute("page", "list.jsp");
    				}
    				else				//	댓글 입력 실패
    				{
    					request.setAttribute("page", "reply_fail.jsp");
    				}
    			}
    			else
    			{
    				request.setAttribute("page", "list.jsp");
    			}
    		}
    		else{	request.setAttribute("page", "fail.jsp");	}
    		
    		//	2. 분류된 url을 선택하고 전송하는 작업
    		RequestDispatcher dispatcher = request.getRequestDispatcher(
    				"/WEB-INF/board/index.jsp"
    				);
    				
    		//	3. 페이지로 밀어주는 작업
    		dispatcher.forward(request, response);
    	}
    
    	protected void doGet(HttpServletRequest request, HttpServletResponse response) 
    			throws ServletException, IOException {}
    
    	protected void doPost(HttpServletRequest request, HttpServletResponse response) 
    			throws ServletException, IOException {}
    }

     

     

    뒤이어 아래를 구현해보자.

    designatedroom87.tistory.com/326?category=901206

     

    게시판 만들기 - 7. 채팅 기능 추가 하기

    index 파일을 실행하면 header에는 아래와 같이 목록이 뜬다. IOT라는 항목을 선택했을 때, 채팅 기능이 나오도록 할 것이다. 물론 로그인 상태여야 이 채팅 기능을 보여줄 것이고, 그렇지 않으면 로

    designatedroom87.tistory.com

     

    댓글

Designed by Tistory.