Java

2024.07.08 JSP 프로그래밍 기본 게시판 만들어 보기 - 1 단계 (미완)

정훈5 2024. 7. 8. 09:54

Dynamic Web Project 를 활용한 기본적인 CRUD JSP 게시판을 만들어 보자.

 

프로젝트 구성

 

 

lib폴더

lombok.jar

mysql-connector-java-8.0.21

 

Mysql workbench  구성

데이터베이스 demo6

create database demo6;
use demo6;

create table posts(
	id int auto_increment primary key,
    title varchar(255) not null,
    content text not null,
    created_at timestamp default current_timestamp
);

select *
from posts;

 

webapp/createPost.jsp

게시글 작성 화면 만들어 보기 (프레젠테이션 계층)

 

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>게시글 작성</title>
<link rel="stylesheet" type="text/css" href="css/styles.css">

</head>
<body>
 	<!--  http://localhost:8080/board/createPost.jsp -->
	<h2>게시글 작성</h2>
	<form action="create-post" method="post">
		
		<label for="title">제목</label>
		<input type="text" id="title" name="title" value="게시글 제목 1">
		
		<br><br>
		
		<label for="content">내용</label>
		<input type="text" id="content" name="content" value="JSP 웹 프로그래밍 ....">
		
		<button type="submit">글 작성</button>
		
	</form>
	
	<br>
	
	<a href="read-posts">게시글 목록</a>

</body>
</html>

 

com.tenco.servlet/CreatePostServlet.java

게시글 작성 기능 만들기 (비즈니스 로직 계층)

package com.tenco.servlet;

import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;

@WebServlet("/create-post")
public class CreatePostServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    public CreatePostServlet() {
        super();
    }

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// 기본 값 설정 (언어 설정)
		request.setCharacterEncoding("UTF-8");
		
		// HTTP 요청 메세지에서 데이터 추출
		String title = request.getParameter("title");
		String content = request.getParameter("content");
		
		// 인증 검사 생략 (로그인 여부 확인) 
		// 데이터 유효성 검사는 생략... 
		
		try(
				Connection conn = DBUtil.getConnection();

				) {
			
			String sql = " INSERT INTO posts(title, content) VALUES (?, ?) ";
			PreparedStatement pstmt = conn.prepareStatement(sql);
			
			pstmt.setString(1, title);
			pstmt.setString(2, content);
			pstmt.executeUpdate();
			
			response.sendRedirect("result.jsp?message=create-success"); // 어디로 보낸다. 메세지 키 값과 같이
			
		} catch (Exception e) {
			e.printStackTrace();
			response.sendRedirect("result.jsp?message=error"); // 어디로 보낸다. 메세지 키 값과 같이
		}

	}

}

 

webapp/result.jsp

결과 확인 페이지 만들어 보기

 

 

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>결과 확인 페이지</title>
</head>
<body>
	
	<h2>결과 확인 페이지</h2>
	<%
		String message = request.getParameter("message");
		if("create-success".equals(message)){
			out.println("<p> 게시글 작성에 성공 </p>");
		
		} else if ("delete-success".equals(message)) {
			out.println("<p>게시글 삭제에 성공</p>");	
		} else if("update-success".equals(message)) {
			out.println("<p>게시글 수정에 성공</p>");
		} else {
			out.println("<p> 게시글 작성에 실패 </p>");
		}
	%>
		<br>
		
	<%-- 게시글 작성 화면으로 이동 --%>
	<a href="createPost.jsp">게시글 작성 페이지</a>
	
	<%-- 게시글 목록 화면으로 이동 --%>
	<a href="read-posts">게시글 리스트 페이지</a>
	
</body>
</html>

 

com.tenco.servlet/DBUtil.java

DB 접근 객체 만들어 보기 (기본)

package com.tenco.servlet;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class DBUtil {
	// static 쓰는 이유 모든 곳에서 사용할려고 , final 사용 이유 변경할 이유가 없기 때문에
	private static final String URL = "jdbc:mysql://localhost:3306/demo6?serverTimezone=Asia/Seoul";
	private static final String USER = "root";
	private static final String PASSWORD = "asd123";
	
	public static Connection getConnection() throws ClassNotFoundException, SQLException {
		
		Class.forName("com.mysql.cj.jdbc.Driver"); // ClassNotFoundException
		return DriverManager.getConnection(URL, USER, PASSWORD); // SQLException
	}
}

 

com.tenco.servlet/ReadPostsServlet .java

게시글 목록 기능 만들기 (비즈니스 로직 계층)

package com.tenco.servlet;

import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

@WebServlet("/read-posts")
public class ReadPostsServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    public ReadPostsServlet() {
        super();
    }
    // 자원에 대한 요청은 GET 방식이다.
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
		// 응답 처리 MINE TYPE 설정
		response.setContentType("text/html");
		response.setCharacterEncoding("UTF-8");
		
		try(
			Connection conn = DBUtil.getConnection();
				) {
			String sql = " SELECT * FROM posts ORDER BY created_at DESC ";
			PreparedStatement pstmt = conn.prepareStatement(sql);
			ResultSet rs = pstmt.executeQuery();
			
			// request 와 response에 값 담아서 보낸다.
			request.setAttribute("resultSet", rs);
			request.getRequestDispatcher("readPosts.jsp").forward(request, response);
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		
	}

	
}

 

request.getRequestDispatcher("readPosts.jsp").forward(request, response); 활용

 

webapp/readPost.jsp

게시글 목록 화면 만들어 보기 (프레젠테이션 계층)

 

<%@page import="java.sql.ResultSet"%>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>게시글 목록</title>
<link rel="stylesheet" type="text/css" href="css/styles.css">
</head>
<body>
	<h2>게시글 목록</h2>
	<%
	ResultSet rs = (ResultSet) request.getAttribute("resultSet");
	if (rs != null) {
	%>
	<table border="1" class="table">
		<tr>
			<th>ID</th>
			<th>제목</th>
			<th>내용</th>
			<th>작성일자</th>
			<th>@@</th>
		</tr>
		<%
		while (rs.next()) {
		%>
		<tr class="nav">
			<td><%=rs.getInt("id")%></td> 
			<td> <a href="view-post?boardId=<%=rs.getInt("id")%>"> <%=rs.getString("title")%> </a> </td>
			<td><%=rs.getString("content")%></td>
			<td><%=rs.getString("created_at")%></td>
			<td>
				<form action="delete-post" method="get">
					<input type="hidden" name="boardId" value="<%=rs.getInt("id")%>">
					<button type="submit">삭제</button>
				</form>
			</td>
		</tr>
		<%
		}
		%>
	</table>

	<%
	} else {
	%>
	<p>작성된 게시글 하나도 없습니다.</p>

	<%
	}
	%>
</body>
</html>

 

 

com.tenco.servlet/DeletePostServlet .java

게시글 삭제 기능 만들어 보기 (비즈니스 로직 계층)

package com.tenco.servlet;

import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;

@WebServlet("/delete-post")
public class DeletePostServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       

    public DeletePostServlet() {
        super();
    }

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
		 request.setCharacterEncoding("UTF-8");
		 
		 String id = request.getParameter("boardId");
		 System.out.println("id : " + id);
		 
		 try(
				 Connection conn = DBUtil.getConnection();
				 ) {
			 String sql = " DELETE FROM posts WHERE ID = ? ";
			 PreparedStatement pstmt = conn.prepareStatement(sql);
			 pstmt.setInt(1, Integer.parseInt(id));
			 pstmt.executeUpdate();
			 
			 // 클라이언트에게 새로운 URL를 자동으로 요청하도록 HTTP 응답을 보낸다.
			 // HTTP 상태 코드 302(임시 이동) 사용자에게 새로운 URL로 이동처리 시킨다.
			 response.sendRedirect("result.jsp?message=delete-success");
			
		} catch (Exception e) {
			e.printStackTrace();
			response.sendRedirect("result.jsp?message=delete-error");
		}
		 
	}
}

 

com.tenco.servlet/DetailPostServlet .java

게시글 상세 보기 기능 만들기 (비즈니스 로직 계층)

package com.tenco.servlet;

import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

@WebServlet("/view-post")
public class DetailPostServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    public DetailPostServlet() {
        super();
    }
    
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
		// 상세보기
		response.setContentType("text/html");
		response.setCharacterEncoding("UTF-8");
		
		String id = request.getParameter("boardId");
		
		try(
				Connection conn = DBUtil.getConnection()
				) {
			String sql = " SELECT * FROM posts WHERE id = ? ";
			PreparedStatement pstmt = conn.prepareStatement(sql);
			pstmt.setInt(1, Integer.parseInt(id));
			ResultSet rs = pstmt.executeQuery(); 
			
			request.setAttribute("resultSet", rs);
			request.getRequestDispatcher("detailPost.jsp").forward(request, response);
			
		} catch (Exception e) {
			e.printStackTrace();
			response.sendRedirect("result.jsp?message=error");
		}
		
	}

}

 

request.getRequestDispatcher("detailPost.jsp").forward(request, response); 활용

 

webapp/detailPost.jsp

게시글 상세보기 화면 (프레젠테이션 계층)

<%@page import="java.sql.ResultSet"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>게시글 상세보기 화면</title>
</head>
<body>
	<h2>상세보기 화면</h2>
	<%
		ResultSet rs  = (ResultSet)request.getAttribute("resultSet");
		if(rs.next()) {
	%>	
		<h3> <%= rs.getString("title") %> </h3>
		<p> <%= rs.getString("content") %> </p>
		<p> <small>  작성일 : <%= rs.getString("created_at") %> </small> </p>
		
		<br><br>
		
		<%-- 수정 폼 --%>
		<h3>게시글 수정</h3>
		<form action="update-post" method="POST">
			
			<input type="hidden" name ="boardId" value= "<%=rs.getInt("id") %>" >
		
			<label for="text">제목 : </label>
			<input type="text" id="title" name="title" value=" <%= rs.getString("title") %> ">
			
			<br> <br>
			
			<label for="content">내용 : </label>
			<input type="text" id="content" name="content" value=" <%= rs.getString("title") %> ">
			
			<br><br>
			
			<button type="submit">수정하기</button>
			
		</form>
		
	<%		
		}
	%>

</body>
</html>

 

com.tenco.servlet/UpdatePostServlet.java

게시글 수정 기능 만들기 (비즈니스 로직 계층)

package com.tenco.servlet;

import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;

@WebServlet("/update-post")
public class UpdatePostServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    public UpdatePostServlet() {
        super();
    }

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
		request.setCharacterEncoding("UTF-8");
		// 일반적인 로직 수정 - 권한확인 (세션정보, 작성자 정보 비교) 
		String id = request.getParameter("boardId");
		
		// SELECT * FROM posts where id = 3;  <--- 작성자 
		
		// 유효성 검사 (사용자가 새로 입력한 정보가 유효성 검사) 
		
		// Update 구문 처리 
		// 트랜잭션 처리를 해야 한다. (commit, rollback)
		
		String title = request.getParameter("title");
		String content = request.getParameter("content");
		
		try(
				Connection conn = DBUtil.getConnection();
				) {
			
			String sql = " UPDATE posts SET title = ?, content = ? WHERE id = ? ";
			PreparedStatement pstmt = conn.prepareStatement(sql);
			pstmt.setString(1, title);
			pstmt.setString(2, content);
			pstmt.setInt(3, Integer.parseInt(id));
			pstmt.executeUpdate();
			response.sendRedirect("result.jsp?message=update-success");
			
		} catch (Exception e) {
			e.printStackTrace();
			response.sendRedirect("result.jsp?message=error");
		}
		
	}

}