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
반응형