JSP

[JSP] JSP로 CRUD 게시판 만들기 (4) - 게시판 만들기

Song hyun 2024. 7. 16. 09:31
728x90
반응형

[JSP] JSP로 CRUD 게시판 만들기 (4) - 게시판 만들기

 

1. BoardController 만들기

package com.tenco.tboard.controller;

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 jakarta.servlet.http.HttpSession;

import java.io.IOException;
import java.util.List;

import com.tenco.tboard.model.Board;
import com.tenco.tboard.model.User;
import com.tenco.tboard.repository.interfaces.BoardRepository;
import com.tenco.tboard.repository.interfaces.BoardRepositoryImpl;
import com.tenco.tboard.repository.interfaces.UserRepository;

@WebServlet("/board/*")
public class BoardController extends HttpServlet {
	
	private static final long serialVersionUID = 1L;
    private BoardRepository boardRepository;
	
	@Override
	public void init() throws ServletException {
		boardRepository = new BoardRepositoryImpl();
	}
	
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		String action = request.getPathInfo();
		// 세션 - 인증 처리
		HttpSession session=request.getSession(false);
		if(session==null || session.getAttribute("principal")==null) {
			response.sendRedirect(request.getContextPath()+"/user/signin");
			return;
		}
		
		
		switch (action) {
		case "/create":
			showCreateBoardForm(request,response,session);
			break;
		case "/list":
			handleListBoards(request, response,session);
			break;

		default:
			break;
		}
		
	}

	/**
	 * 게시글 생성 화면 이동
	 * @param request
	 * @param response
	 * @param session
	 * @throws IOException 
	 * @throws ServletException 
	 */
	private void showCreateBoardForm(HttpServletRequest request, HttpServletResponse response, HttpSession session) throws ServletException, IOException {
		request.getRequestDispatcher("/WEB-INF/views/board/create.jsp").forward(request, response);
	}

	/**
	 * 페이징 처리 하기 
	 * @param request
	 * @param response
	 * @throws IOException 
	 * @throws ServletException 
	 */
	private void handleListBoards(HttpServletRequest request, HttpServletResponse response, HttpSession session) throws ServletException, IOException {
		// 게시글 목록 조회 기능
		int page = 1; // 기본 페이지 번호 
		int pageSize = 3; // 한 페이지당 보여질 게시글에 수  
		
		try {
			 String pageStr = request.getParameter("page");
			 if(pageStr != null ) {
				 page = Integer.parseInt(pageStr);
			 }
		} catch (Exception e) {
			// 유효하지 않은 번호를 마음대로 보낼 경우 
			page = 1; 
		}
		// pageSize --> 3이다 
		// page 1, page 2, page 3 요청 동적으로 시작값을 계산하는 산수 공식 넣기 
		int offset = (page - 1) * pageSize; // 시작 위치 계산( offset 값 계산)

		// pageSize <-- 한 페이지당 보여줄 게시글 수 (limit 로 바라 볼 수 있다 ) 
 		List<Board> boardList =  boardRepository.getAllBoards(pageSize, offset);
		// 페이징 처리 1단계 (현재 페이지 번호, pageSize , offset) 
		////////////////////////////////////////////////////////////////
		
		// 전체 게시글 수 조회 
		int totalBoards = boardRepository.getTotalBoardCount();
		
		// 총 페이지 수 계산 -->  [1][2][3][...]
		int totalPages = (int) Math.ceil(totalBoards / pageSize);
		
		request.setAttribute("boardList", boardList);
		request.setAttribute("totalPages", totalPages);
		request.setAttribute("currentPage", page);
		
		// 현재 로그인한 사용자 ID 설정
		if(session!=null) {
			User user=(User)session.getAttribute("principal");
			if(user!=null) {
				request.setAttribute("userId", user.getId());
			}
		}
		request.getRequestDispatcher("/WEB-INF/views/board/list.jsp").forward(request, response);
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		String action = request.getPathInfo();
		// 세션 - 인증 처리
		HttpSession session=request.getSession(false);
		if(session==null || session.getAttribute("principal")==null) {
			response.sendRedirect(request.getContextPath()+"/user/signin");
			return;
		}
		
		
		switch (action) {
		case "/create":
			handleCreateBoard(request,response,session);
			break;
		case "/edit":
			showCreateBoardForm(request,response,session);
			break;
		case "/addComment":
			showCreateBoardForm(request,response,session);
			break;
		default:
			response.sendError(HttpServletResponse.SC_NOT_FOUND);
			break;
		}
	}

	/**
	 * 게시글 생성 처리
	 * @param request
	 * @param response
	 * @param session
	 * @throws IOException 
	 */
	private void handleCreateBoard(HttpServletRequest request, HttpServletResponse response, HttpSession session) throws IOException {
		// 유효성 검사 생략
		String title=request.getParameter("title");
		String content=request.getParameter("content");
		User user=(User)session.getAttribute("principal");
		
		Board board= Board.builder()
				.userId(user.getId())
				.title(title)
				.content(content)
				.build();
		boardRepository.addBoard(board);
		response.sendRedirect(request.getContextPath()+"/board/list?page=1");
	}

}

 

 

 

2. BoardRepository (인터페이스) 만들기

-BoardRepository.java(인터페이스 형식): BoardDAO의 뼈대를 만들어주는 클래스.

어떤 변수를 받고, 어떤 자료형의 값을 return 할 것인지를 미리 설계해둔다. -> 추후 implements를 통해 구현!

package com.tenco.tboard.repository.interfaces;

import java.util.List;

import com.tenco.tboard.model.Board;

public interface BoardRepository {
	// CRUD
	void addBoard(Board board);
	void updateBoard(Board board,int principalId);
	void deleteBoard(int id);
	Board selectBoardById(int id);
	List<Board> getAllBoards(int limit,int offset);
	int getTotalBoardCount();
}

 

 

 

3. Board DTO 만들기

-Board.java: Board를 인스턴스화 할 때(=객체로 만들때) 필요한, 의미있는 자료형의 집합.

-SQL 상에서의 데이터 항목(=컬럼)과 동일하게 작성한다.

package com.tenco.tboard.model;

import java.sql.Timestamp;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;

@Data
@ToString
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class Board {
	private int id;
	private int userId;
	private String title;
	private String content;
	private Timestamp createdAt;
}

 

 

 

4. SQL 쿼리문

-오류 방지를 위해 MySQL에서 미리 쿼리를 작성, 체크 후에 DAO에 넣는다.

select * from board order by created_at desc limit ? offset ? ;

 

 

5. List.JSP

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
   
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>게시글 목록</title>
<link rel="stylesheet" type="text/css" href="${pageContext.request.contextPath}/resources/css/common.css">
<link rel="stylesheet" type="text/css" href="${pageContext.request.contextPath}/resources/css/list.css">
</head>
<body>
	<h2>게시글 목록</h2>
	<div class="action">
		<a class="btn btn-create" href="${pageContext.request.contextPath}/board/create" >새글 작성하기</a>
		<a class="btn btn-back" href="${pageContext.request.contextPath}/index.jsp" >홈 화면</a>
	</div>
	
	<c:forEach var="board"  items="${boardList}">
		<div class="board-item">
			<h3><a href="#">${board.title}</a></h3>
			<p>${board.content}</p>
			<p> <fmt:formatDate value="${board.createdAt}" pattern="yyyy-MM-dd HH:mm" /></p>
			<!-- 게시글에 작성자가 세션 유저와 동일하다면 수정, 삭제 버튼을 보여주자  -->
			<c:if test="${board.userId==userId }">
				<a class="btn btn-edit" href="#">수정</a>
				<a class="btn btn-delete" href="#">삭제</a>
			</c:if>
		</div>
	</c:forEach>
	
	<br>
	<div class="pagination">
		<!-- index for  -->
		<c:forEach begin="1" end="${totalPages}"  var="i" >
			<c:choose>
				<c:when test="${ i == currentPage }">
					<span class="current-page" >${i}</span>
				</c:when>
				<c:otherwise>
					<span><a href="${pageContext.request.contextPath}/board/list?page=${i}">${i}</a></span>	
				</c:otherwise>
			</c:choose>
		</c:forEach>
	</div>
	
</body>
</html>

 

 

6. CSS

(1) common.css

@charset "UTF-8";

body{
	font-family:Arial,Sans-serif;
	margin: 0;
	padding: 0;
	background-color: #f4f4f4;
	color: #333;
	
}

 

(2) list.css

@charset "UTF-8";
@import url("board.css");

.action{
	margin-bottom: 20px;
}
.action .btn{
	margin-right:10px;
}

.board-item{
	margin-bottom:20px;
	padding: 15px;
	border-bottom: 1px solid #ddd;
}
.board-item h3{
	margin: 0;
}

.board-item P{
	margin: 5px 0;
}

.btn-create{
	background-color: #28a745;
	color: white;
	text-align:center;
}

.btn-create:hover{
	background-color: #218838;
}

.btn-edit{
	background-color: #007bff;
	color: white;
	text-align:center;
}

.btn-edit:hover{
	background-color: #0056b3;
}
.btn-delete{
	background-color: #dc3545;
	color: white;
	text-align:center;
}

.btn-delete:hover{
	background-color: #c82333;
}

.btn-back{
	background-color: #6c757d;
	color: white;
}
.btn-back:hover{
	background-color: #5a6268;
}


.pagination{
	text-align:center;
	margin-top: 20px;
	margin-bottom: 40px;
}

.pagination a{
	display: inline-block;
	padding: 5px 10px;
	margin: 0 5px;
	border: 1px solid #ddd;
	text-decoration: none;
	color: #007bff;
}

.pagination a:hover{
	background-color: #007bff;
	color: white;
}

.current-page{
	display: inline-block;
	padding: 5px 10px;
	background-color: #007bff;
	border: 1px solid #007bff;
	border-radius: 4px;
	text-decoration: none;
	color: white;
}

 

(3) board.css

@charset "UTF-8";

h2{
	text-align: center;
	color: #007aba;
}

.btn {
	display: inline-block;
	padding: 10px 15px;
	margin-top: 10px;
	text-decoration: none;
	border-radius: 4px;
	
}

 

7. UserController

package com.tenco.tboard.controller;

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 jakarta.servlet.http.HttpSession;

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

import com.tenco.tboard.model.User;
import com.tenco.tboard.repository.UserRepositoryImpl;
import com.tenco.tboard.repository.interfaces.UserRepository;


@WebServlet("/user/*")
public class UserController extends HttpServlet {
	private static final long serialVersionUID = 1L;
    
	private UserRepository userRepository;
	
	@Override
	public void init() throws ServletException {
		userRepository = new UserRepositoryImpl();
	}


	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
		String action = request.getPathInfo();
		
		switch (action) {
		case "/signup": 
			request.getRequestDispatcher("/WEB-INF/views/user/signup.jsp").forward(request, response);
			break;
		case "/signin":
			request.getRequestDispatcher("/WEB-INF/views/user/signin.jsp").forward(request, response); 
			break;
		case "/logout":
			handleLogout(request, response);
			break;
		default:
			response.sendError(HttpServletResponse.SC_NOT_FOUND);
			break;
		}
		
	}
	
	/**
	 * 로그아웃 기능 처리 
	 * @throws IOException 
	 * http://localhost:8080/t-board/user/logout
	 */
	private void handleLogout(HttpServletRequest request, HttpServletResponse response) throws IOException {
		HttpSession session = request.getSession();
		session.invalidate();
		response.sendRedirect(request.getContextPath() + "/user/signin");
	}


	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		String action = request.getPathInfo();
		switch (action) {
		case "/signup": 
			handleSignup(request, response);
			break;
		case "/signin":
			 handleSignin(request, response); 
			break;
		default:
			response.sendError(HttpServletResponse.SC_NOT_FOUND);
			break;
		}
		
	}


	private void handleSignin(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
		String username = request.getParameter("username");
		String password = request.getParameter("password");
		User principal = userRepository.getUserByUsernameAndPassword(username, password);
		
		if(principal != null && principal.getPassword().equals(password)) {
			HttpSession session = request.getSession();
			session.setAttribute("principal", principal);
			response.sendRedirect(request.getContextPath() + "/board/list");
		} else {
			request.setAttribute("errorMessage", "잘못된 요청입니다.");
			request.getRequestDispatcher("/WEB-INF/views/user/signin.jsp").forward(request, response);
		}
	}


	private void handleSignup(HttpServletRequest request, HttpServletResponse response) throws IOException {
		// 데이터 추출 
		String username = request.getParameter("username") ; 
		String password = request.getParameter("password") ; 
		String email = request.getParameter("email");
		
		// 데이터 유효성 검사 생략 
		
		User user = User.builder()
					.username(username)
					.password(password)
					.email(email)
					.build();
		// TODO 삭제 예정 
		System.out.println(user);
		int result = userRepository.addUser(user);
		if(result != 0) {
			response.sendRedirect(request.getContextPath() + "/user/signin");
		} else {
			 response.setContentType("text/html; charset=UTF-8");
			 PrintWriter out = response.getWriter();
			 out.println("<script> alert('잘못된 요청입니다'); history.back();  </script>");
		}
	}
}
728x90
반응형