output/JSP

게시판 만들기 10강 게시판 글쓰기 기능 구현

hs_developer 2022. 7. 4. 14:59

게시판 페이지에서 로그인을 한 사람들은 '글쓰기' 기능을 사용할 수 있도록 실제 사용자가 입력한 글 제목과 글 내용을 전달 받아 데이터베이스에 실제로 저장되는 기능을 구현한다.

 

 


 

기존의 'bbs.jsp'를 복사해 'write.jsp' 페이지를 생성한다.

 

write.jsp

 

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width", initial-scale="1">
<link rel="stylesheet" href="css/bootstrap.css">
<title>JSP 게시판 웹 사이트</title>
</head>
<body>
	<%
		// 메인 페이지로 이동했을 때 세션에 값이 담겨 있는지 체크
		String userID= null;
	
		if(session.getAttribute("userID")!=null)
		{
			userID= (String)session.getAttribute("userID");
		}
	%>
	<nav class="navbar navbar-default"> <!-- 네비게이션 -->
		<div class="navbar-header"> <!-- 홈페이지 상단 영역 (홈페이지 로고 등을 담당)  -->
			<!-- 네비게이션 상단 박스 영역 -->
			<button type="button" class="navbar-toggle collapsed"
             data-toggle="collapse" data-target="#bs-example-navbar-collapse-1"
             aria-expanded="false">
             	<!-- 화면이 좁아지면 우측에 나타나는 햄버거 버튼 -->
				<span class="icon-bar"></span>
				<span class="icon-bar"></span>
				<span class="icon-bar"></span>
			</button>
			<!-- 헤더 바에 제목 나타나고 클릭하면 메인 페이지로 이동한다 -->
			<a class="navbar-brand" href="main.jsp">JSP 게시판 웹 사이트</a>
		</div>
		<!-- 게시판 제목 이름 옆에 나타나는 메뉴 영역 -->
		<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
			<ul class="nav navbar-nav"> <!-- 리스트 -->
				<li><a href="main.jsp">메인</a></li>
				<li class="active"><a href="main.jsp">게시판</a></li>
			</ul>
			<%
				// 로그인을 하지 않았을 때 보여지는 화면
				if(userID == null)
				{
			
			%>
			<!-- 헤더 바 우측에 나타나는 드랍다운 영역 -->
			<ul class="nav navbar-nav navbar-right">
				<li class="dropdown">
					<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" 
					aria-haspopup="true" aria-expanded="false">접속하기
					<span class="caret"></span></a>
					<!-- 드랍다운 아이템 영역 -->
					<ul class="dropdown-menu">
						<li><a href="login.jsp">로그인</a></li> <!--active: 1개의 홈페이지에서만 사용 가능  -->
						<li><a href="join.jsp">회원가입</a></li>
					</ul>
				</li>
			</ul>
			<% 
				// 로그인이 되어 있는 상태에서 보여주는 화면
				} 
				else 
				{
			%>
			<!-- 헤더 우측에 나타나는 드랍다운 영역 -->
			<ul class="nav navbar-nav navbar-right">
				<li class="dropdown">
					<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" 
					aria-haspopup="true" aria-expanded="false">회원관리<span class="caret"></span></a>
					<!-- 드랍다운 아이템 영역 -->
					<ul class="dropdown-menu">
						<li><a href="logoutAction.jsp">로그아웃</a></li>
					</ul>
				</li>	
			</ul>
			<%
				}
			%>
		</div>
	</nav>
	<!-- 네비게이션 영역 끝 -->
	
	<!-- 게시판 글쓰기 양식 시작 -->
	<div class="container">
		<div class="row">
			<table class="table table-striped" style="text-align: center; border: 1px solid #dddddd">
				<thead>
					<tr>
						<th colspan="2" style="background-color: #eeeeee; text-align: center;">게시판 글쓰기 양식</th>
					</tr>
				</thead>
				<tbody>
					<tr>
						<td><input type="text" class="form-control" placeholder="글 제목" name="bbsTitle" maxlength="50"></td>
					</tr>
					<tr>
						<td><textarea class="form-control" placeholder="글 내용" name="bbsContent" maxlength="2048" style="height: 350px;"></textarea>
					</tr>
				</tbody>
			</table>
			<!-- 글쓰기 버튼 생성 -->
			<a href="write.jsp" class="btn btn-primary pull-right">글쓰기</a>
		</div>
	</div>
	<!-- 게시판 글쓰기 양식 영역 끝 -->
	
	<!-- 부트스트랩 참조 영역 -->
	<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
	<script src="js/bootstrap.js"></script>
</body>
</html>

 

 


 

'bbs' 패키지에서 'BbsDAO' 클래스를 생성한다.

 

BbsDAO.java

package bbs;

import java.sql.*;

public class BbsDAO {

	private Connection conn;
	private ResultSet rs;
	
	// 기본 생성자
	public BbsDAO()
	{
		try
		{
			String dbURL= "jdbc:mysql://localhost/bbs";
			String dbID= "root";
			String dbPassword= "happy";
			Class.forName("org.mysql.jdbc.Driver");
			conn= DriverManager.getConnection(dbURL, dbID, dbPassword);
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
	}
}

 

생성자 먼저 작성.

 

'BbsDAO' 클래스는 여러 개의 메서드가 사용되기 때문에 각각의 메서드가 데이터베이스 접근에 있어서 서로 마찰이 일어나지 않도록 'PreparedStatement'를 각각의 메서드에 추가한다.

 

 

// 작성일자 메서드
public String getDate()
{
    String sql= "select now()";

    try
    {
        PreparedStatement ps= conn.prepareStatement(sql);
        rs= ps.executeQuery();

        if(rs.next())
        {
            return rs.getString(1);
        }
    }
    catch(Exception ex)
    {
        ex.printStackTrace();
    }
    return ""; // 데이터베이스 오류
}

 

'getDate()' - 작성일자를 구하는 메서드

 

글쓰기를 하는 현재 날짜와 시간을 출력한다.

 

 

// 게시글 번호 부여 메서드
public int getNext() 
{
    // 게시글 번호는 하나씩 늘어나므로 마지막에 쓰인 글을 가져와서 +1을 하면 다음 번호가 된다 
    String SQL = "SELECT bbsID FROM BBS ORDER BY bbsID DESC";

    try 
    {
        PreparedStatement pstmt = conn.prepareStatement(SQL);
        rs = pstmt.executeQuery();
        if (rs.next()) 
        {
            return rs.getInt(1) + 1;
        }
        return 1; // 첫 번째 게시물인 경우
    } 
    catch (Exception e) 
    {
        e.printStackTrace();
    }
    return -1; // 데이터베이스 오류
}

 

'getNext()' 메서드 - 새로운 게시글 번호 부여

 

현재 저장되어 있는 게시글을 내림차순으로 정렬하여 가장 상위의 게시글 번호를 구해서 그 게시글 번호에 1을 더한 값을 새로 작성되는 게시글의 새 번호로 부여한다.

 

예를 들어 현재 'bbs.jsp' 게시판 메인 페이지에 총 13개의 글이 작성 되어 있다면, 가장 최신 글의 번호인 '13'에서 +1을 더한 '14'를 새로 만들어지는 게시글의 번호로 지정한다.

 

 

 

// 실제로 글을 작성하는 함수
public int write(String bbsTitle, String userID, String bbsContent) 
{
    String SQL = "INSERT INTO BBS VALUES (?, ?, ?, ?, ?, ?)";
    try 
    {
        PreparedStatement pstmt = conn.prepareStatement(SQL);
        pstmt.setInt(1, getNext());
        pstmt.setString(2, bbsTitle);
        pstmt.setString(3, userID);
        pstmt.setString(4, getDate());
        pstmt.setString(5, bbsContent);
        pstmt.setInt(6, 1);
        return pstmt.executeUpdate();
    } 
    catch (Exception e) 
    {
        e.printStackTrace();
    }
    return -1; // 데이터베이스 오류
}

 

'write' 메서드 - 글 제목, 사용자 ID, 글 내용을 전달 받아 DB에 새로운 데이터를 입력

 

게시글 번호 → 글 제목 → 사용자 ID → 작성 일자 → 글 내용 → 유효 번호

 

매개변수로 글 제목, 글을 입력한 사용자의 ID, 글 내용을 입력 받고 실제 데이터베이스의 테이블 속성 순서에 맞게 데이터를 입력하는 메서드다.

 

package bbs;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

public class BbsDAO {
	
	private Connection conn;
	private ResultSet rs;
	
	public BbsDAO() {
		try 
		{
			String dbURL= "jdbc:mysql://localhost:3306/BBS?serverTimezone=UTC";
			String dbID= "root";
			String dbPassword= "happy";
			Class.forName("com.mysql.jdbc.Driver"); 
			conn= DriverManager.getConnection(dbURL, dbID, dbPassword); 
		} 
		catch (Exception e) 
		{
			e.printStackTrace();
		}
	}
	
	// 현재 시간을 가져오는 함수, 게시판의 글을 작성할 때 현재 서버의 시간을 넣어주는 역할
	public String getDate() {
		String SQL = "SELECT NOW()";
		try 
		{
			PreparedStatement pstmt = conn.prepareStatement(SQL);
			rs = pstmt.executeQuery();
			if (rs.next()) 
			{
				return rs.getString(1);
			}
		} catch (Exception e) 
		{
			e.printStackTrace();
		}
		return ""; // 데이터베이스 오류
	}
	
	
	// 게시글 번호 부여 메서드
	public int getNext() 
	{
		// 게시글 번호는 하나씩 늘어나므로 마지막에 쓰인 글을 가져와서 +1을 하면 다음 번호가 된다 
		String SQL = "SELECT bbsID FROM BBS ORDER BY bbsID DESC";
		
		try 
		{
			PreparedStatement pstmt = conn.prepareStatement(SQL);
			rs = pstmt.executeQuery();
			if (rs.next()) 
			{
				return rs.getInt(1) + 1;
			}
			return 1; // 첫 번째 게시물인 경우
		} 
		catch (Exception e) 
		{
			e.printStackTrace();
		}
		return -1; // 데이터베이스 오류
	}
	
	// 실제로 글을 작성하는 함수
	public int write(String bbsTitle, String userID, String bbsContent) 
	{
		String SQL = "INSERT INTO BBS VALUES (?, ?, ?, ?, ?, ?)";
		try 
		{
			PreparedStatement pstmt = conn.prepareStatement(SQL);
			pstmt.setInt(1, getNext());
			pstmt.setString(2, bbsTitle);
			pstmt.setString(3, userID);
			pstmt.setString(4, getDate());
			pstmt.setString(5, bbsContent);
			pstmt.setInt(6, 1);
			return pstmt.executeUpdate();
		} 
		catch (Exception e) 
		{
			e.printStackTrace();
		}
		return -1; // 데이터베이스 오류
	}
}

 

 


 

writeAction.jsp

 

글쓰기 버튼을 눌렀을 때 게시글 내용이 데이터베이스에 실제로 입력 되는 로직을 수행할 수 있는 JSP 파일을 만든다.

 

 

'joinAction.jsp'를 복사 해 'writeAction.jsp'를 생성한다.

 

 

상단에 페이지 세팅을 수정한다.

 

 

<%
    // 현재 세션 상태를 체크한다
    String userID = null;
    if (session.getAttribute("userID") != null) 
    {
        userID = (String) session.getAttribute("userID");
    }

    // 로그인을 한 사람만 글을 쓸 수 있도록 한다
    if(userID == null) 
    {
        PrintWriter script = response.getWriter();
        script.println("<script>");
        script.println("alert('로그인을 하세요.')");
        script.println("location.href = 'login.jsp'");
        script.println("</script>");
    } 
    else 
    {
        // 입력이 안된 부분이 있는지 체크한다
        if (bbs.getBbsTitle() == null || bbs.getBbsContent() == null) 
        {
                PrintWriter script = response.getWriter();
                script.println("<script>");
                script.println("alert('입력하지 않은 사항이 있습니다.')");
                script.println("history.back()");
                script.println("</script");
        } 
        else 
        {
            // 정상적으로 입력이 되었다면 글쓰기 로직을 수행한다
            BbsDAO bbsDAO = new BbsDAO();
            int result = bbsDAO.write(bbs.getBbsTitle(), userID, bbs.getBbsContent());

            // 데이터베이스 오류인 경우
            if (result == -1) 
            {
                PrintWriter script = response.getWriter();
                script.println("<script>");
                script.println("alert('글쓰기에 실패했습니다.')");
                script.println("history.back()");
                script.println("</script>");
            }

            // 글쓰기가 정상적으로 실행되면 알림 창을 띄우고 게시판 메인으로 이동한다
            else 
            {
                PrintWriter script = response.getWriter();
                script.println("<script>");
                script.println("alert('글쓰기 성공')");
                script.println("location.href = 'bbs.jsp'");
                script.println("</script>");
            }
        }
    }
%>

 

1. 먼저 로그인을 한 사람만이 글을 쓸 수 있도록 코드를 수정한다.

 

2. 글 제목과 글 내용 중 누락된 사항이 있는지 체크한다.

 

3. 로그인을 했고 모든 내용이 정상적으로 입력이 되었을 때 '글쓰기 성공' 알림창을 띄우고 게시판 메인 페이지('bbs.jsp')로 이동하게 한다.

 

 

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="bbs.BbsDAO" %>
<%@ page import="java.io.PrintWriter" %>
<% request.setCharacterEncoding("UTF-8"); %>
<jsp:useBean id="bbs" class="bbs.Bbs" scope="page" />
<jsp:setProperty name="bbs" property="bbsTitle" />
<jsp:setProperty name="bbs" property="bbsContent" />
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>JSP 게시판 웹 사이트</title>
</head>
<body>
	<%
		// 현재 세션 상태를 체크한다
		String userID = null;
		if (session.getAttribute("userID") != null) 
		{
			userID = (String) session.getAttribute("userID");
		}
		
		// 로그인을 한 사람만 글을 쓸 수 있도록 한다
		if(userID == null) 
		{
			PrintWriter script = response.getWriter();
			script.println("<script>");
			script.println("alert('로그인을 하세요.')");
			script.println("location.href = 'login.jsp'");
			script.println("</script>");
		} 
		else 
		{
			// 입력이 안된 부분이 있는지 체크한다
			if (bbs.getBbsTitle() == null || bbs.getBbsContent() == null) 
			{
					PrintWriter script = response.getWriter();
					script.println("<script>");
					script.println("alert('입력하지 않은 사항이 있습니다.')");
					script.println("history.back()");
					script.println("</script");
			} 
			else 
			{
				// 정상적으로 입력이 되었다면 글쓰기 로직을 수행한다
				BbsDAO bbsDAO = new BbsDAO();
				int result = bbsDAO.write(bbs.getBbsTitle(), userID, bbs.getBbsContent());
				
				// 데이터베이스 오류인 경우
				if (result == -1) 
				{
					PrintWriter script = response.getWriter();
					script.println("<script>");
					script.println("alert('글쓰기에 실패했습니다.')");
					script.println("history.back()");
					script.println("</script>");
				}
				
				// 글쓰기가 정상적으로 실행되면 알림 창을 띄우고 게시판 메인으로 이동한다
				else 
				{
					PrintWriter script = response.getWriter();
					script.println("<script>");
					script.println("alert('글쓰기 성공')");
					script.println("location.href = 'bbs.jsp'");
					script.println("</script>");
				}
			}
		}
	%>
</body>
</html>

 

 

 


 

 

글쓰기 기능 실행 테스트

 

 

로그인을 하지 않고 글 작성 시 로그인을 하라는 알림창 출력 됨.

 

확인을 누르면 로그인 창으로 이동.

 

 

 

로그인 후 글 작성.

 

 

 

글쓰기가 완료되고 알림창이 뜸.

 

 

 

글쓰기는 성공했지만 '게시글 목록' 기능은 구현 되지 않았기에 게시판 메인 페이지는 이전과 똑같음.

 

 

mysql> select * from bbs;
+-------+----------+--------+---------------------+-------------------------+--------------+
| bbsID | bbsTitle | userID | bbsDate             | bbsContent              | bbsAvailable |
+-------+----------+--------+---------------------+-------------------------+--------------+
|     1 | ㅗㅎ     | dd     | 2022-07-04 20:01:15 | ㅜ                      |            1 |
|     2 | ㅇ       | dd     | 2022-07-04 20:07:59 | ㅇ                      |            1 |
|     3 | d        | dd     | 2022-07-04 20:08:16 | d                       |            1 |
|     4 | ㄹ       | dd     | 2022-07-04 20:11:55 | ㄹ                      |            1 |
|     5 | ㄹ       | dd     | 2022-07-04 20:12:10 | ㅎ                      |            1 |
|     6 | 흠       | ff     | 2022-07-04 21:03:13 | 무슨 말이 필요해        |            1 |
|     7 | 흠       | ff     | 2022-07-04 21:04:19 | 무슨 말이 필요하냐고... |            1 |
+-------+----------+--------+---------------------+-------------------------+--------------+
7 rows in set (0.05 sec)

 

MySQL 커맨드 창으로 데이터를 확인 할 수 있음.