1. 게시판 UI 만들기
동적으로 목록에 게시글을 뿌려주는건 차근차근 알아보고 일단 정적인 페이지로 구현해보겠습니다.
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="UTF-8"%>
<%@ page import="java.io.PrintWriter" %>
<%@ page import="bbs.BbsDAO" %>
<%@ page import="bbs.Bbs" %>
<%@ page import="java.util.*" %>
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>JSP 게시판 페이지</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-T3c6CoIi6uLrA9TneNEoa7RxnatzjcDSCmG1MXxSR1GAsXEV/Dwwykc2MPK8M2HN" crossorigin="anonymous">
</head>
<style>
/* 네비게이션 바의 드롭다운 메뉴 위치 조정 */
.navbar-nav .dropdown-menu {
position: absolute;
right: 0;
overflow-x: hidden;
}
a, a:hover {
color: #000000;
text-decoration: none;
}
</style>
<body>
<%
String userID = null;
if(session.getAttribute("userID")!=null){
userID = (String)session.getAttribute("userID");
}
%>
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<div class="container-fluid">
<a class="navbar-brand" href="#">JSP 게시판 웹 사이트</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNavDropdown" aria-controls="navbarNavDropdown" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNavDropdown">
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
<li class="nav-item">
<a class="nav-link" href="main.jsp">메인</a>
</li>
<li class="nav-item">
<a class="nav-link active" href="#">게시판</a>
</li>
</ul>
<!-- 로그인 전에는 로그인, 회원가입 버튼을, 로그인 후에는 로그아웃 버튼만 보여준다. -->
<%
if(userID == null){
%>
<ul class="navbar-nav">
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdownMenuLink" role="button" data-bs-toggle="dropdown" aria-expanded="false">
계정
</a>
<ul class="dropdown-menu dropdown-menu-end" aria-labelledby="navbarDropdownMenuLink">
<li><a class="dropdown-item" href="login.jsp">로그인</a></li>
<li><a class="dropdown-item" href="join.jsp">회원가입</a></li>
</ul>
</li>
</ul>
<%
} else {
%>
<ul class="navbar-nav">
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdownMenuLink" role="button" data-bs-toggle="dropdown" aria-expanded="false">
회원관리
</a>
<ul class="dropdown-menu dropdown-menu-end" aria-labelledby="navbarDropdownMenuLink">
<li><a class="dropdown-item" href="logoutAction.jsp">로그아웃</a></li>
</ul>
</li>
</ul>
<%
}
%>
</div>
</div>
</nav>
<div class="container mt-5">
<h2>게시판</h2>
<form method="post" action="writeAction.jsp">
<table class="table">
<thead>
<tr>
<th scope="col">번호</th>
<th scope="col">제목</th>
<th scope="col">작성자</th>
<th scope="col">작성일</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>안녕하세요.</td>
<td>우루루파도</td>
<td>2024-02-07</td>
</tr>
</tbody>
</table>
<div class="d-flex justify-content-between my-4">
<!-- 글쓰기 버튼 -->
<div>
<a href="write.jsp" class="btn btn-primary pull-right">글쓰기</a>
</div>
</div>
</form>
</div>
<script
src="https://code.jquery.com/jquery-3.7.1.js"
integrity="sha256-eKhayi8LEQwp4NKxN+CfCh+3qOVUtJn3QNZ0TciWLP4="
crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-C6RzsynM9kWDrMNeT87bh95OGNyZPhcTNXj1NW7RuBCsyN/o0jlpcV8Qyq46cDfL" crossorigin="anonymous"></script>
</body>
</html>
로컬 서버를 실행하면 이렇게 게시판이 뜹니다.
실제 DB에 있는 걸 가져온게 아니라 정적인 UI입니다.
이제 이 게시판 UI에 기능을 덧붙여주면 됩니다.
- 글쓰기 기능
- 실제 DB와 연동해서 게시판 목록 조회하기
- 게시글 수 10개 단위로 페이징하기
- 게시글 제목 클릭하여 상세 내용 보기
- 수정, 삭제기능
- 세션ID로 권한체크하여 내가 쓴 글만 수정,삭제 버튼 보이기
페이징 기능과 게시판 목록 조회 기능 구현을 같이 구현해보겠습니다.
2. DTO 클래스 만들기 (Bbs.java)
게시판 데이터의 그릇이 되어줄 DTO클래스를 만들겁니다.
bbs 패키지를 위와 같은 경로에 만들어줍니다.
그리고 Bbs.java 클래스를 생성하고
bbs테이블에 있는 컬럼에 맞춰 private 접근제한자를 가진 멤버변수들을 만들어줍니다.
getter와 setter를 만들어주면 게시판 DTO만들기 끝!
package bbs;
public class Bbs {
private int bbsID;
private String bbsTitle;
private String userID;
private String bbsDate;
private String bbsContent;
private int bbsAvailable;
public int getBbsID() {
return bbsID;
}
public void setBbsID(int bbsID) {
this.bbsID = bbsID;
}
public String getBbsTitle() {
return bbsTitle;
}
public void setBbsTitle(String bbsTitle) {
this.bbsTitle = bbsTitle;
}
public String getUserID() {
return userID;
}
public void setUserID(String userID) {
this.userID = userID;
}
public String getBbsDate() {
return bbsDate;
}
public void setBbsDate(String bbsDate) {
this.bbsDate = bbsDate;
}
public String getBbsContent() {
return bbsContent;
}
public void setBbsContent(String bbsContent) {
this.bbsContent = bbsContent;
}
public int getBbsAvailable() {
return bbsAvailable;
}
public void setBbsAvailable(int bbsAvailable) {
this.bbsAvailable = bbsAvailable;
}
}
3. 글쓰기 UI 만들기(write.jsp)
게시판 페이지에서 글쓰기 버튼을 눌렀을때 마주할 페이지를 만들어봅니다.
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="UTF-8"%>
<%@ page import="java.io.PrintWriter" %>
<%@ page import="bbs.Bbs" %>
<%@ page import="bbs.BbsDAO" %>
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>JSP 게시판 페이지</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-T3c6CoIi6uLrA9TneNEoa7RxnatzjcDSCmG1MXxSR1GAsXEV/Dwwykc2MPK8M2HN" crossorigin="anonymous">
</head>
<style>
/* 네비게이션 바의 드롭다운 메뉴 위치 조정 */
.navbar-nav .dropdown-menu {
position: absolute;
right: 0;
overflow-x: hidden;
}
</style>
<body>
<%
String userID = null;
if(session.getAttribute("userID")!=null){
userID = (String)session.getAttribute("userID");
}
// if (useID == null){
// }
%>
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<div class="container-fluid">
<a class="navbar-brand" href="#">JSP 게시판 웹 사이트</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNavDropdown" aria-controls="navbarNavDropdown" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNavDropdown">
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
<li class="nav-item">
<a class="nav-link" href="main.jsp">메인</a>
</li>
<li class="nav-item">
<a class="nav-link active" href="write.jsp">게시판</a>
</li>
</ul>
<%
if(userID == null){
%>
<ul class="navbar-nav">
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdownMenuLink" role="button" data-bs-toggle="dropdown" aria-expanded="false">
계정
</a>
<ul class="dropdown-menu dropdown-menu-end" aria-labelledby="navbarDropdownMenuLink">
<li><a class="dropdown-item" href="login.jsp">로그인</a></li>
<li><a class="dropdown-item" href="join.jsp">회원가입</a></li>
</ul>
</li>
</ul>
<%
} else {
%>
<ul class="navbar-nav">
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdownMenuLink" role="button" data-bs-toggle="dropdown" aria-expanded="false">
회원관리
</a>
<ul class="dropdown-menu dropdown-menu-end" aria-labelledby="navbarDropdownMenuLink">
<li><a class="dropdown-item" href="logoutAction.jsp">로그아웃</a></li>
</ul>
</li>
</ul>
<%
}
%>
</div>
</div>
</nav>
<div class="container mt-5">
<h2>게시판</h2>
<form method="post" action="writeAction.jsp">
<table class="table">
<thead>
<tr>
<th colspan="2" scope="col">게시판 글쓰기 양식</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></td>
</tr>
</tbody>
</table>
<!-- 글쓰기 버튼 -->
<div class="d-flex justify-content-end">
<input type="submit" class="btn btn-primary pull-right" value="글쓰기">
</div>
</form>
</div>
<script
src="https://code.jquery.com/jquery-3.7.1.js"
integrity="sha256-eKhayi8LEQwp4NKxN+CfCh+3qOVUtJn3QNZ0TciWLP4="
crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-C6RzsynM9kWDrMNeT87bh95OGNyZPhcTNXj1NW7RuBCsyN/o0jlpcV8Qyq46cDfL" crossorigin="anonymous"></script>
</body>
</html>
글 제목과 글 내용을 적을 input태그, textarea태그를 만들어줍니다.
각 필드에 있는 name 속성은 서버로 전송될 때 해당 데이터를 식별하는 데 사용됩니다.
여기서는 글 제목이 bbsTitle로, 글 내용이 bbsContent로 식별됩니다.
글쓰기 버튼을 누르면 writeAction.jsp로 이동합니다.
4. DAO 클래스 구현하기 ( BbsDAO.java )
글쓰기 로직을 구현하려면, UI에서 입력한 데이터가 DB에 저장이 되어야합니다.
데이터베이스 CRUD 연산을 수행하는 BbsDAO.java 클래스를 Bbs.java와 같은 경로에 만들어줍니다.
package bbs;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
public class BbsDAO {
private Connection conn;
//private PreparedStatement pstmt;
//PreparedStatement은 각 함수내에 선언하는게 좋다.
//각각의 SQL쿼리를 독립적으로 관리.
private ResultSet rs;
public BbsDAO() {
try {
String dbURL = "jdbc:mariadb://localhost:3306/BBS";
String dbID = "root";
String dbPassword = "root";
//driver는 mariaDB에 접속할 수 있도록 매개체 역할을 함.
Class.forName("org.mariadb.jdbc.Driver");
//접속이 완료되면 conn객체안에 접속정보가 담기게 된다.
conn = DriverManager.getConnection(dbURL, dbID, dbPassword);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public String getDate() {
String sql = "SELECT NOW()"; //CURDATE()는 현재 날짜 반환함.
try {
//SQL문장을 실행 준비단계로 만들어줌.
PreparedStatement pstmt = conn.prepareStatement(sql);
rs = pstmt.executeQuery();
if(rs.next()) {
return rs.getString(1);//현재 날짜 반환
}
}catch(Exception e){
e.printStackTrace();
}
return ""; //데이터베이스 오류
}
//다음에 올 bbsID를 계산하는 메서드
public int getNext() {
String sql = "SELECT bbsID FROM BBS ORDER BY bbsID DESC"; //CURDATE()는 현재 날짜 반환함.
try {
//SQL문장을 실행 준비단계로 만들어줌.
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); //bbsAvailable 1 넣음.
//insert는 executeUpdate
return pstmt.executeUpdate();
}
catch(Exception e){
e.printStackTrace();
}
return -1; //데이터베이스 오류
}
✔️작성날짜를 받아올 getData() 메서드를 만들어줍니다.
rs.getString(1) 은 ResultSet의 첫 번째 컬럼 값을 추출합니다.
✔️채번을 하는 getNext() 메서드를 만들어줍니다.
bbsID를 내림차순으로 조회하면 가장 최근 글이 첫번째 행에 조회됩니다.
여기에 +1을 해주면 새로운 게시물의 bbsID를 구할 수 있습니다.
✔️ 어떻게 데이터가 들어오는지 생각하고 코드를 짜줍니다.
bbsID는 getNext()로!
bbsTitle은 input태그로!
userID는 세션 ID로!
bbsDate는 getDate()로!
bbsContent는 textarea로 입력을 받을 것입니다.
5. 글쓰기 실행 로직 만들기 (writeAction.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");%>
<!-- 자바빈은 데이터를 저장하고 데이터에 접근하는 메서드(getter, setter)를 제공한다. -->
<jsp:useBean id="bbs" class="bbs.Bbs" scope = "page"/>
<!-- 프로퍼티에 해당하는 setter가 호출되어 요청(request)에 있는 같은 이름의 파라미터 값으로 설정됨 -->
<jsp:setProperty name="bbs" property="bbsTitle"/>
<jsp:setProperty name="bbs" property="bbsContent"/>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>글쓰기 액션</title>
</head>
<body>
<%
/* 로그인 세션확인 */
String userID = null;
if(session.getAttribute("userID") !=null){ //세션ID 존재하면 userID에 값넣어줌.
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){ //DB오류
PrintWriter script = response.getWriter();
script.println("<script>");
script.println("alert('글쓰기에 실패했습니다.')");
script.println("history.back()");
script.println("</script>");
} else if(result == 1){//게시글 작성완료.
PrintWriter script = response.getWriter();
script.println("<script>");
script.println("location.href = 'bbs.jsp'");
script.println("</script>");
}
}
}
%>
</body>
</html>
BbsDAO에서 글쓰기 성공시 pstmt.executeUpdate()을 반환하는데,
executeUpdate() 메소드는 실행에 의해 영향을 받은 행의 수를 반환합니다.
따라서, 1을 반환하는 겁니다.
리턴값이 -1이면 오류 발생, 1이면 글쓰기 완료 로직을 수행하여 게시판 페이지로 이동합니다.
앞으로 남은 기능은 추후 업로드 하겠습니다. 뿅!
- 실제 DB와 연동해서 게시판 목록 조회하기
- 게시글 수 10개 단위로 페이징하기
- 게시글 제목 클릭하여 상세 내용 보기
- 수정, 삭제기능
- 세션ID로 권한체크하여 내가 쓴 글만 수정,삭제 버튼 보이기
'프로그래밍 언어 > Java' 카테고리의 다른 글
[책 리뷰] 객체지향의 사실과 오해 - 객체지향의 본질 (0) | 2024.12.31 |
---|---|
[IntelliJ] Live Templates 사용법 | 반복되는 코드 편하게 작성하기 (0) | 2024.08.08 |
[JSP] 게시판 만들기 | 4편.회원가입 기능 구현하기 / 로그아웃 (1) | 2024.02.07 |
[JSP] 게시판 만들기 | 3편.로그인 기능 구현하기 (0) | 2024.02.07 |
[JSP] 게시판 만들기 | 2편.데이터베이스 설치 및 연동 (1) | 2024.02.07 |