๐งโ๐ป ๊ฐ์ธ ํ๋ก์ ํธ - ํ์์ ๊ฒ์ํ ๋ง๋ค๊ธฐ(JAVA)
JWT ์ธ์ฆ ๊ธฐ๋ฐ ํ์์ ๊ฒ์ํ ๊ตฌํ Project ์ ๋๋ค.
JAVA ํ์์ ๊ฒ์ํ ๊ตฌํ
1. ํ๋ก์ ํธ ์๊ฐ
ใ ค์ด ํ๋ก์ ํธ๋ JAVA๋ก ๊ตฌํ๋ ํ์์ ๊ฒ์ํ ์ฌ์ดํธ์ ๋๋ค.
ใ ค์ฌ์ฉ์๋ ํ์๊ฐ์ ์ ํตํด ๊ฒ์๊ธ ๋ฑ๋ก, ์์ , ์ญ์ , ์กฐํ๋ฅผ ํ ์ ์์ต๋๋ค. ใ ค
2. ํ๋ก์ ํธ ๊ตฌ์กฐ
์์ธ ๊ตฌ์กฐ๋ ํ์ด์ง ์๋จ์ ๊นํ๋ธ ๋งํฌ๋ฅผ ์ฐธ๊ณ ํด์ฃผ์ธ์
๐src
โโโ๐main
โโโ๐java
โโโ๐controller - ๐๊ฒ์ํ CRUD, ๋ก๊ทธ์ธ, ํ์๊ฐ์
์ฉ ์ปจํธ๋กค๋ฌ
โโโ๐filter -๐ํ ํฐ ๊ธฐ๋ฐ ์ฌ์ฉ์ ์ธ์ฆ ์ฒ๋ฆฌ ํํฐ
โโโ๐listener -๐์น ์ ํ๋ฆฌ์ผ์ด์
์์, ์ข
๋ฃ ์ด๋ฒคํธ ์ฒ๋ฆฌ ๋ฆฌ์ค๋
โโโ๐model - ๐ํ์ด์ง ์ฒ๋ฆฌ ๋ฐ UI ์์ฑ ์ ํธ๋ฆฌํฐ ํด๋์ค
โโโ๐resources
โโโ๐service
โโโ๐webapp
โโโ๐bbspage - ๐๊ฒ์ํ ํ์ด์ง CRUD ๊ด๋ จ ๋ก์ง
โโโ๐connectionpool
โโโ๐META_INF
โโโ๐page - ๐ํ์๊ฐ์
, ๋ก๊ทธ์ธ , ํ ํ์ด์ง ๊ด๋ จ ๋ก์ง
โโโ๐template
โโโ๐WEB-INF
3. ์ฃผ์ ์ฝ๋
์์ธ ์ฝ๋๋ ํ์ด์ง ์๋จ์ ๊นํ๋ธ ๋งํฌ๋ฅผ ์ฐธ๊ณ ํด์ฃผ์ธ์
LoginController.java
์๋ ์ฝ๋๋ ๋ก๊ทธ์ธ ๊ธฐ๋ฅ์ ์ฒ๋ฆฌํ๋ ์๋ธ๋ฆฟ์ผ๋ก, ์ฌ์ฉ์๊ฐ ์ ๋ ฅํ ์์ด๋์ ๋น๋ฐ๋ฒํธ๋ฅผ ๊ฒ์ฆํ๊ณ ์ธ์ฆ๋ ์ฌ์ฉ์์ ์ธ์ ์ ์์ฑํฉ๋๋ค.
์ฑ๊ณต์ ์ธ ๋ก๊ทธ์ธ ์ ํ ํฐ์ ๋ฐ๊ธํ์ฌ ์ฟ ํค์ ์ธ์ ์ ์ ์ฅํ๊ณ , ๋ก๊ทธ์ธ ์ฑ๊ณต ํ ์ง์ ๋ ํ์ด์ง๋ก ๋ฆฌ๋ค์ด๋ ์ ํฉ๋๋ค.
์คํจ ์ ์๋ฌ ๋ฉ์์ง๋ฅผ ๋ก๊ทธ์ธ ํ์ด์ง์ ์ ๋ฌํฉ๋๋ค.
@WebServlet("/LoginController")
public class LoginController extends HttpServlet {
private static final long serialVersionUID = 1L;
// POST ์์ฒญ ์ฒ๋ฆฌ
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("UTF-8"); // ํ๊ธ ์ธ์ฝ๋ฉ ์ค์
String username = request.getParameter("username"); // ์
๋ ฅ๋ฐ์ ์์ด๋
String password = request.getParameter("password"); // ์
๋ ฅ๋ฐ์ ๋น๋ฐ๋ฒํธ
// ๊ฐ๋จํ ์ ํจ์ฑ ๊ฒ์ฌ (์์ด๋์ ๋น๋ฐ๋ฒํธ๊ฐ ๋น์ด์์ง ์์์ง ํ์ธ)
if (username == null || username.trim().isEmpty() || password == null || password.isEmpty()) {
handleError(request, response, "์์ด๋์ ๋น๋ฐ๋ฒํธ๋ฅผ ๋ชจ๋ ์
๋ ฅํ์ธ์");
return;
}
UserDAO userDAO = new UserDAO(); // ์ฌ์ฉ์ ๊ฒ์ฆ์ ์ํ UserDAO ๊ฐ์ฒด ์์ฑ
// ์์ด๋์ ๋น๋ฐ๋ฒํธ ๊ฒ์ฆ
if (userDAO.validateUser(username, password)) {
// ์ธ์ฆ ์ฑ๊ณต ์ ํ ํฐ ๋ฐ๊ธ
String token = userDAO.issueToken(username); // ์ฌ์ฉ์์๊ฒ ๋ฐ๊ธํ ํ ํฐ ์์ฑ
Cookie tokenCookie = new Cookie("token", token); // ํ ํฐ์ ์ฟ ํค๋ก ์์ฑ
tokenCookie.setMaxAge(60 * 60 * 24 * 7); // ์ฟ ํค ์ ํจ๊ธฐ๊ฐ ์ค์ (7์ผ)
response.addCookie(tokenCookie); // ์ฟ ํค๋ฅผ ์๋ต์ ์ถ๊ฐ
// HttpSession์ ์ด์ฉํ์ฌ ์ฌ์ฉ์ ์ ๋ณด ์ ์ฅ
HttpSession session = request.getSession(); // ์ธ์
์์ฑ
request.getSession().setAttribute("token", token); // ์ธ์
์ ํ ํฐ ์ ์ฅ
session.setAttribute("token", token); // ์ธ์
์ ํ ํฐ ์ ์ฅ
session.setAttribute("username", username); // ์ธ์
์ ์ฌ์ฉ์ ์ด๋ฆ ์ ์ฅ
// ๋ก๊ทธ์ธ ์ฑ๊ณต ํ ํ์ด์ง ๋ฆฌ๋ค์ด๋ ํธ
response.sendRedirect(request.getContextPath() + "/page/LoginOk.jsp");
} else {
// ์ธ์ฆ ์คํจ ์ ์๋ฌ ๋ฉ์์ง ์ถ๋ ฅ
handleError(request, response, "์์ด๋ ๋๋ ๋น๋ฐ๋ฒํธ๊ฐ ์๋ชป๋์์ต๋๋ค");
}
}
// ์๋ฌ ๋ฉ์์ง๋ฅผ ๋ก๊ทธ์ธ ํ์ด์ง์ ์ ๋ฌํ๋ ๋ฉ์๋
private void handleError(HttpServletRequest request, HttpServletResponse response, String message) throws ServletException, IOException {
request.setAttribute("errorMessage", message); // ์๋ฌ ๋ฉ์์ง ์ค์
request.getRequestDispatcher("/page/Login.jsp").forward(request, response); // ๋ก๊ทธ์ธ ํ์ด์ง๋ก ํฌ์๋
}
}
LogoutController.java
์๋ ์ฝ๋๋ ๋ก๊ทธ์์ ๊ธฐ๋ฅ์ ์ฒ๋ฆฌํ๋ ์๋ธ๋ฆฟ์ผ๋ก, ์ฌ์ฉ์๊ฐ ๋ก๊ทธ์์์ ์์ฒญํ๋ฉด ์ธ์ ๊ณผ ์ฟ ํค๋ฅผ ์ด๊ธฐํํ๊ณ , ๋ก๊ทธ์ธ ํ์ด์ง๋ก ๋ฆฌ๋ค์ด๋ ํธํฉ๋๋ค.
POST ์์ฒญ์์ ์ธ์ ์ ๋ฌดํจํํ๊ณ , "token"์ด๋ผ๋ ์ด๋ฆ์ ์ฟ ํค๋ฅผ ์ญ์ ํ ํ ๋ก๊ทธ์ธ ํ์ด์ง๋ก ์ด๋ํฉ๋๋ค.
@WebServlet("/LogoutController")
public class LogoutController extends HttpServlet {
private static final long serialVersionUID = 1L;
// POST ์์ฒญ ์ฒ๋ฆฌ
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// ์ธ์
๋ฌดํจํ
request.getSession().invalidate(); // ์ธ์
์ด๊ธฐํ
// "token" ์ฟ ํค ์ญ์
Cookie[] cookies = request.getCookies(); // ์์ฒญ์์ ๋ชจ๋ ์ฟ ํค๋ฅผ ๊ฐ์ ธ์ด
if (cookies != null) {
for (Cookie cookie : cookies) {
if (cookie.getName().equals("token")) { // "token" ์ฟ ํค ์ฐพ๊ธฐ
cookie.setMaxAge(0); // ์ฟ ํค ์ ํจ๊ธฐ๊ฐ์ 0์ผ๋ก ์ค์ ํ์ฌ ์ญ์
response.addCookie(cookie); // ์ญ์ ๋ ์ฟ ํค๋ฅผ ์๋ต์ ์ถ๊ฐ
break; // ๋ ์ด์ ๋ฐ๋ณตํ ํ์ ์์
}
}
}
// ๋ก๊ทธ์์ ํ ๋ก๊ทธ์ธ ํ์ด์ง๋ก ๋ฆฌ๋ค์ด๋ ํธ
response.sendRedirect(request.getContextPath() + "/page/Login.jsp"); // ๋ก๊ทธ์ธ ํ์ด์ง๋ก ์ด๋
}
// GET ์์ฒญ์ POST ์์ฒญ์ผ๋ก ์ฒ๋ฆฌ
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response); // GET ์์ฒญ์ POST ์์ฒญ์ผ๋ก ์ฒ๋ฆฌ
}
}
Login.jsp
์๋ ์ฝ๋๋ ๋ก๊ทธ์ธ ํ๋ฉด์ ๊ตฌ์ฑํ๋ JSP ๋ก, ์ฌ์ฉ์๊ฐ ์์ด๋์ ๋น๋ฐ๋ฒํธ๋ฅผ ์ ๋ ฅํ ์ ์๋๋ก ํผ์ ์ ๊ณตํฉ๋๋ค.
ํผ ์ ์ถ ์, ๋ก๊ทธ์ธ ์ ๋ณด๋ฅผ `LoginController`๋ก ์ ์กํ๋ฉฐ, ๋ก๊ทธ์ธ ์คํจ ์ ์๋ฌ ๋ฉ์์ง๋ฅผ ํ์ํฉ๋๋ค.
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>
<html>
<head>
<jsp:include page="/template/Config.jsp" />
<title>Login</title> // ํ์ด์ง ์ ๋ชฉ ์ค์
<script>
// ํ์ด์ง ๋ก๋ฉ ํ, ์๋ฌ ๋ฉ์์ง๊ฐ ์์ ๊ฒฝ์ฐ ๊ฒฝ๊ณ ์ฐฝ์ผ๋ก ํ์
document.addEventListener('DOMContentLoaded', function() {
var errorMsg = '<%= request.getAttribute("errorMsg") %>'; // request ๊ฐ์ฒด์์ ์๋ฌ ๋ฉ์์ง ๊ฐ์ ธ์ค๊ธฐ
if (errorMsg && errorMsg !== 'null') {
alert(errorMsg); // ์๋ฌ ๋ฉ์์ง ์กด์ฌ ์ ๊ฒฝ๊ณ ์ฐฝ์ผ๋ก ํ์
}
});
</script>
</head>
<body>
<div class="container">
<div class="container-fluid">
<jsp:include page="/template/Header.jsp" />
<div class="p-5 bg-success text-white">
<h1 style="font-weight: bold;">๋ก๊ทธ์ธ</h1>
</div>
<fieldset class="border rounded-3 p-3 text-center mt-3 mb-3">
<legend class="float-none w-auto px-3" style="font-weight: bold;">๋ก๊ทธ์ธ ์ ๋ณด๋ฅผ ์
๋ ฅํ์ธ์</legend> // ๋ก๊ทธ์ธ ํผ ์ ๋ชฉ
<form class="needs-validation" action="${pageContext.request.contextPath}/LoginController" method="post">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="row mb-3">
<div class="col-md-4 mb-2 mt-5 d-flex align-items-center justify-content-md-end">
<label for="username" class="form-label" style="font-weight: bold;">์์ด๋</label> // ์์ด๋ ์
๋ ฅ ํ๋ ๋ผ๋ฒจ
</div>
<div class="col-md-6 mb-3 mt-5">
<input type="text" class="form-control" id="username" placeholder="์์ด๋ ์
๋ ฅ" name="username" value="${param.username}"> // ์์ด๋ ์
๋ ฅ ํ๋
</div>
</div>
<div class="row mb-3">
<div class="col-md-4 mb-2 mt-3 d-flex align-items-center justify-content-md-end">
<label for="password" class="form-label" style="font-weight: bold;">๋น๋ฐ๋ฒํธ</label> // ๋น๋ฐ๋ฒํธ ์
๋ ฅ ํ๋ ๋ผ๋ฒจ
</div>
<div class="col-md-6 mb-3 mt-3">
<input type="password" class="form-control" id="password" placeholder="๋น๋ฐ๋ฒํธ ์
๋ ฅ" name="password"> // ๋น๋ฐ๋ฒํธ ์
๋ ฅ ํ๋
</div>
</div>
<div class="row mb-3">
<div class="col-md-12">
<button type="submit" class="btn btn-dark">๋ก๊ทธ์ธ</button> // ๋ก๊ทธ์ธ ๋ฒํผ
</div>
</div>
<c:if test="${not empty errorMessage}">
<div class="row mb-3">
<div class="col-md-12 d-flex justify-content-center">
<div class="alert alert-danger" style="max-width: 50%; padding: 20px;">
${errorMessage} // ๋ก๊ทธ์ธ ์คํจ ์, ์ค๋ฅ ๋ฉ์์ง๋ฅผ ํ์
</div>
</div>
</div>
</c:if>
</div>
</div>
</form>
</fieldset>
<jsp:include page="/template/Footer.jsp" />
</div>
</div>
</body>
</html>
LoginOk.jsp
์๋ ์ฝ๋๋ ๋ก๊ทธ์ธ ์ฑ๊ณต ํ ์ฌ์ฉ์์๊ฒ ํ์ ๋ฉ์์ง๋ฅผ ํ์ํ๋ JSP ์ ๋๋ค.
๋ก๊ทธ์ธ ์ฑ๊ณต ์, ์ธ์ ์์ ์ฌ์ฉ์์ ํ ํฐ์ ๋ก์ปฌ ์คํ ๋ฆฌ์ง์ ์ ์ฅํ๋ฉฐ, ์ฌ์ฉ์์๊ฒ ํ์ ๋ฉ์์ง๋ฅผ ๋ณด์ฌ์ค๋๋ค.
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> // ํ์ด์ง์ ์ธ์ฝ๋ฉ ๋ฐ ์ธ์ด ์ค์
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> // JSTL ์ฝ์ด ํ๊ทธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ํฌํจ
<!DOCTYPE html>
<html>
<head>
<jsp:include page="/template/Config.jsp"/>
<title>LoginOk.jsp</title>
<script>
// ํด๋ผ์ด์ธํธ ์ธก JavaScript ์ฝ๋ ์์ฑ
var token = '${sessionScope.token}'; // ์ธ์
์์ ํ ํฐ ๊ฐ์ ๊ฐ์ ธ์ด
localStorage.setItem('token', token); // ๋ก์ปฌ ์คํ ๋ฆฌ์ง์ ํ ํฐ ์ ์ฅ
</script>
</head>
<body>
<div class="container">
<div class="container-fluid">
<jsp:include page="/template/Header.jsp"/>
<!-- ์ปจํ
์ธ ์์ -->
<div class="p-5 bg-success text-white">
<h1 style="font-weight:bold;">๋ก๊ทธ์ธ ์ฑ๊ณต</h1> // ๋ก๊ทธ์ธ ์ฑ๊ณต ๋ฉ์์ง ํ์
</div>
<fieldset class="border rounded-3 p-3 text-center mt-3 mb-3">
<h3 class="display-6" style="font-weight:bold;">${sessionScope.username}๋ ํ์ํฉ๋๋ค!</h3> // ๋ก๊ทธ์ธํ ์ฌ์ฉ์์ ์ด๋ฆ์ ์ถ๋ ฅ
<div class="row mt-4">
<div class="col-md-12">
<h5>์๋จ ๋ฉ๋ด๋ฅผ ํตํด ์ด๋ํด์ฃผ์ธ์</h5>
</div>
</div>
</fieldset>
<!-- ์ปจํ
์ธ ๋ -->
<jsp:include page="/template/Footer.jsp"/>
</div><!-- container-fluid -->
</div><!-- container -->
<script>
document.getElementById('boardBtn').addEventListener('click', function() {
window.location.href = '${pageContext.request.contextPath}/BoardController'; // ๊ฒ์ํ ํ์ด์ง๋ก ์ด๋
});
</script>
</body>
</html>
SignUpController.java
์๋ ์ฝ๋๋ ํ์๊ฐ์ ์ ์ฒ๋ฆฌํ๋ ์๋ธ๋ฆฟ์ ๋๋ค.
์ฌ์ฉ์๊ฐ ํ์๊ฐ์ ํผ์ ์ ์ถํ๋ฉด ์ด ์๋ธ๋ฆฟ์ด ํธ์ถ๋์ด ์ ํจ์ฑ ๊ฒ์ฌ์ ์ค๋ณต ๊ฒ์ฌ ํ, ์ฌ์ฉ์์ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํฉ๋๋ค.
@WebServlet("/SignUpController") // ์ด ์๋ธ๋ฆฟ์ "/SignUpController" URL์ ๋งคํ
public class SignUpController extends HttpServlet {
private static final long serialVersionUID = 1L; // ์ง๋ ฌํ ID ์ค์
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("UTF-8"); // ์์ฒญ์ ๋ฌธ์ ์ธ์ฝ๋ฉ์ UTF-8๋ก ์ค์
// ์์ฒญ ํ๋ผ๋ฏธํฐ๋ฅผ ๋ฐ์์ด
String username = request.getParameter("username"); // ์ฌ์ฉ์ ์์ด๋
String password = request.getParameter("password"); // ์ฌ์ฉ์ ๋น๋ฐ๋ฒํธ
String passwordConfirm = request.getParameter("passwordConfirm"); // ๋น๋ฐ๋ฒํธ ํ์ธ
String gender = request.getParameter("gender"); // ์ฑ๋ณ
String[] interests = request.getParameterValues("interests"); // ๊ด์ฌ์ฌ
String grade = request.getParameter("grade"); // ํ๋ ฅ
String self = request.getParameter("self"); // ์๊ธฐ์๊ฐ
String token = request.getParameter("token"); // ํ ํฐ
// ์ ํจ์ฑ ๊ฒ์ฌ
if (username == null || username.trim().isEmpty()) { // ์์ด๋ ์
๋ ฅ ํ์ธ
handleError(request, response, "์์ด๋๋ฅผ ์
๋ ฅํ์ธ์");
return;
}
if (password == null || password.isEmpty()) { // ๋น๋ฐ๋ฒํธ ์
๋ ฅ ํ์ธ
handleError(request, response, "๋น๋ฐ๋ฒํธ๋ฅผ ์
๋ ฅํ์ธ์");
return;
}
if (!password.equals(passwordConfirm)) { // ๋น๋ฐ๋ฒํธ ํ์ธ ์ผ์น ํ์ธ
handleError(request, response, "๋น๋ฐ๋ฒํธ๋ฅผ ๋ค์ ํ๋ฒ ํ์ธํด ์ฃผ์ธ์");
return;
}
if (gender == null || gender.isEmpty()) { // ์ฑ๋ณ ์
๋ ฅ ํ์ธ
handleError(request, response, "์ฑ๋ณ์ ์ ํํ์ธ์");
return;
}
if (interests == null || interests.length < 2) { // ๊ด์ฌ์ฌ 2๊ฐ ์ด์ ์ ํ ํ์ธ
handleError(request, response, "๊ด์ฌ์ฌํญ์ 2๊ฐ ์ด์ ์ ํํ์ธ์");
return;
}
if (grade == null || grade.isEmpty()) { // ํ๋ ฅ ์
๋ ฅ ํ์ธ
handleError(request, response, "ํ๋ ฅ์ ์ ํํ์ธ์");
return;
}
if (self == null || self.trim().isEmpty()) { // ์๊ธฐ์๊ฐ ์
๋ ฅ ํ์ธ
handleError(request, response, "์๊ธฐ์๊ฐ๋ฅผ ์
๋ ฅํ์ธ์");
return;
}
// ์ค๋ณต ์ฒดํฌ
UserDAO userDAO = new UserDAO();
if (userDAO.checkUsernameExists(username)) { // ์์ด๋ ์ค๋ณต ์ฒดํฌ
handleError(request, response, "์ค๋ณต๋ ์์ด๋๊ฐ ์์ต๋๋ค. ๋ค๋ฅธ ์์ด๋๋ฅผ ์ฌ์ฉํด์ฃผ์ธ์");
return;
}
// ์ ํจ์ฑ ๊ฒ์ฌ๋ฅผ ๋ชจ๋ ํต๊ณผํ๋ฉด UserDTO ๊ฐ์ฒด๋ฅผ ์์ฑํ๊ณ ์ ์ฅ
UserDTO user = new UserDTO(username, password, passwordConfirm, gender, interests, grade, self, token);
if (userDAO.saveUser(user)) { // ์ฌ์ฉ์ ์ ์ฅ ์ฑ๊ณต
request.setAttribute("username", username); // ์ฑ๊ณต ์ ์ฌ์ฉ์ ์ด๋ฆ ์ ๋ฌ
request.getRequestDispatcher("/page/SignUpOk.jsp").forward(request, response); // ํ์๊ฐ์
์ฑ๊ณต ํ์ด์ง๋ก ํฌ์๋ฉ
} else { // ์ฌ์ฉ์ ์ ์ฅ ์คํจ
handleError(request, response, "ํ์๊ฐ์
์ ์คํจํ์ต๋๋ค. ๋ค์ ์๋ํด์ฃผ์ธ์.");
}
}
// ์ค๋ฅ ๋ฐ์ ์ ์ฒ๋ฆฌ ๋ฉ์๋
private void handleError(HttpServletRequest request, HttpServletResponse response, String message) throws ServletException, IOException {
request.setAttribute("modalMessage", message); // ์ค๋ฅ ๋ฉ์์ง๋ฅผ ์์ฒญ์ ์ ์ฅ
request.getRequestDispatcher("/page/SignUp.jsp").forward(request, response); // ์ค๋ฅ ๋ฐ์ ์ ํ์๊ฐ์
ํ์ด์ง๋ก ํฌ์๋ฉ
}
}
SignUp.jsp
์๋ ์ฝ๋๋ ์ฌ์ฉ์ ํ์๊ฐ์ JSP ์ ๋๋ค.
ํ์๊ฐ์ ํผ์ ์ฌ์ฉ์ ์ด๋ฆ, ์ด๋ฉ์ผ, ๋น๋ฐ๋ฒํธ๋ฅผ ์ ๋ ฅ๋ฐ๊ณ , ์ ์ถ ์ 'signup.do'๋ก ๋ฐ์ดํฐ๋ฅผ ์ ์กํฉ๋๋ค.
ํ์ ์ ๋ ฅ ํญ๋ชฉ์ ๋ํด ์ ํจ์ฑ ๊ฒ์ฌ ๊ธฐ๋ฅ์ด ํฌํจ๋์ด ์์ต๋๋ค.
<%@page import="java.util.Arrays"%>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>
<html>
<head>
<jsp:include page="/template/Config.jsp" />
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
<title>SignUp.jsp</title>
</head>
<body>
<div class="container">
<div class="container-fluid">
<jsp:include page="/template/Header.jsp" />
<!-- ํ์๊ฐ์
์์ ์์ -->
<div class="p-5 bg-success text-white mb-3">
<h1 style="font-weight: bold;">ํ์๊ฐ์
</h1>
</div>
<form action="signup.do" method="post" class="needs-validation" novalidate> // ํ์๊ฐ์
ํผ ์์
<div class="form-group"> // ์ฌ์ฉ์ ์ด๋ฆ ์
๋ ฅ๋
<label for="username">์ฌ์ฉ์ ์ด๋ฆ</label>
<input type="text" class="form-control" id="username" name="username" required>
<div class="invalid-feedback">์ฌ์ฉ์ ์ด๋ฆ์ ์
๋ ฅํ์ธ์.</div>
</div>>
<div class="form-group"> // ์ด๋ฉ์ผ ์
๋ ฅ๋
<label for="email">์ด๋ฉ์ผ</label>
<input type="email" class="form-control" id="email" name="email" required>
<div class="invalid-feedback">์ ํจํ ์ด๋ฉ์ผ์ ์
๋ ฅํ์ธ์.</div>
</div>>
<div class="form-group"> // ๋น๋ฐ๋ฒํธ ์
๋ ฅ๋
<label for="password">๋น๋ฐ๋ฒํธ</label>
<input type="password" class="form-control" id="password" name="password" required>
<div class="invalid-feedback">๋น๋ฐ๋ฒํธ๋ฅผ ์
๋ ฅํ์ธ์.</div>
</div>
<button type="submit" class="btn btn-primary mt-3">ํ์๊ฐ์
</button> // ์ ์ถ ๋ฒํผ
</form>
<!-- ํ์๊ฐ์
์์ ๋ -->
</div>
</div>
</body>
</html>
WriteController.java
์๋ ์ฝ๋๋ ๊ฒ์๊ธ ์์ฑ ์ฒ๋ฆฌํ๋ WriteController ์ ๋๋ค.
์ฌ์ฉ์๊ฐ ๋ก๊ทธ์ธ ์ํ์ผ ๊ฒฝ์ฐ ์ ๋ชฉ๊ณผ ๋ด์ฉ์ ๋ฐ์ ๊ฒ์๊ธ์ ๋ฑ๋กํฉ๋๋ค.
์ ๋ชฉ๊ณผ ๋ด์ฉ์ด ๋น์ด์๋ ๊ฒฝ์ฐ ๊ฒฝ๊ณ ๋ฉ์์ง๋ฅผ ์ถ๋ ฅํ๊ณ ์ด์ ํ์ด์ง๋ก ๋์๊ฐ๋๋ค.
@WebServlet("/WriteController") // URL ๋งคํ
public class WriteController extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
HttpSession session = request.getSession(); // ์ธ์
๊ฐ์ ธ์ค๊ธฐ
String username = (String) session.getAttribute("username"); // ์ฌ์ฉ์ ์ด๋ฆ ๊ฐ์ ธ์ค๊ธฐ
String token = (String) session.getAttribute("token"); // ํ ํฐ ๊ฐ์ ธ์ค๊ธฐ
response.setContentType("text/html; charset=UTF-8");
PrintWriter out = response.getWriter();
// ์ฌ์ฉ์ ์์ด๋๊ฐ ์์ผ๋ฉด ๋ก๊ทธ์ธ ํ์ด์ง๋ก ์ด๋
if (username == null || username.isEmpty() || token == null || token.isEmpty()) {
response.sendRedirect("/YoonSeongBinProj2/page/Login.jsp"); // ๋ก๊ทธ์ธ ํ์ด์ง๋ก ๋ฆฌ๋ค์ด๋ ํธ
} else {
// ์ ๋ชฉ๊ณผ ๋ด์ฉ์ ํ๋ผ๋ฏธํฐ์์ ๊ฐ์ ธ์ค๊ธฐ
String title = request.getParameter("title");
String content = request.getParameter("content");
// ์ ๋ชฉ์ด๋ ๋ด์ฉ์ด ๋น์ด์๋ ๊ฒฝ์ฐ
if (title == null || title.trim().isEmpty() || content == null || content.trim().isEmpty()) {
out.println("<script>");
out.println("alert('์ ๋ชฉ๊ณผ ๋ด์ฉ์ ์
๋ ฅํด์ฃผ์ธ์.');"); // ๊ฒฝ๊ณ ๋ฉ์์ง
out.println("history.back();"); // ์ด์ ํ์ด์ง๋ก ๋์๊ฐ๊ธฐ
out.println("</script>");
} else {
// ๊ฒ์๊ธ ๋ฑ๋ก ๋ก์ง
ServletContext application = getServletContext();
BbsDTO item = new BbsDTO(); // ์๋ก์ด ๊ฒ์๊ธ ๊ฐ์ฒด ์์ฑ
item.setContent(content); // ๋ด์ฉ ์ค์
item.setTitle(title); // ์ ๋ชฉ ์ค์
item.setUsername(username); // ์ฌ์ฉ์ ์ด๋ฆ ์ค์
BbsDAO dao = new BbsDAO(application); // DAO ๊ฐ์ฒด ์์ฑ
int affected = dao.insert(item); // ๊ฒ์๊ธ ์ฝ์
dao.close(); // DAO ์ข
๋ฃ
if (affected > 0) {
out.println("<script>");
out.println("alert('๊ฒ์๊ธ ๋ฑ๋ก์ด ์๋ฃ๋์์ต๋๋ค');"); // ๋ฑ๋ก ์๋ฃ ๋ฉ์์ง
out.println("location.href='/YoonSeongBinProj2/bbspage/BbsList.jsp';"); // ๊ฒ์๊ธ ๋ชฉ๋ก ํ์ด์ง๋ก ์ด๋
out.println("</script>");
} else {
out.println("<script>");
out.println("alert('๊ฒ์๊ธ ๋ฑ๋ก์ ์คํจํ์์ต๋๋ค. ๋ค์ ์๋ํด์ฃผ์ธ์');"); // ์คํจ ๋ฉ์์ง
out.println("history.back();"); // ์ด์ ํ์ด์ง๋ก ๋์๊ฐ๊ธฐ
out.println("</script>");
}
}
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response); // doPost ๋ฉ์๋ ํธ์ถ
}
}
BbsDAO.java
์๋ ์ฝ๋๋ ๊ฒ์ํ DAO(Data Access Object) ์ ๋๋ค.
๋ฐ์ดํฐ์ ์ ๊ทผํด์ CRUD ์์ ์ ์ํํ๋ ์ ๋ฌด ์ฒ๋ฆฌ ๋ก์ง์ ๊ฐ๊ณ ์๋ ๊ฐ์ฒด์ ๋๋ค.
public class BbsDAO2 implements DAOService<BbsDTO> {
// ํ๋
private Connection conn;
private ResultSet rs;
private PreparedStatement psmt;
// ์์ฑ์
public BbsDAO2(ServletContext context) {
try {
Context initContext = new InitialContext();
Context envContext = (Context) initContext.lookup("java:comp/env");
DataSource dataSource = (DataSource) envContext.lookup("jdbc/ICTUSER");
conn = dataSource.getConnection();
} catch (NamingException | SQLException e) {
e.printStackTrace();
}
}
// ์์ ๋ฐ๋ฉ์ฉ
@Override
public void close() {
try {
if (rs != null) rs.close();
if (psmt != null) psmt.close();
if (conn != null) conn.close();
} catch (SQLException e) {}
}
//์ ์ฒด ๋ชฉ๋ก ๊ฐ์ ธ์ค๊ธฐ
/*
* ํ์ด์ง ๋ก์ง ์ถ๊ฐํ๊ธฐ
* DAO์์ ํ ์ผ
* 1. ์ ์ฒด ๋ชฉ๋ก ์ฟผ๋ฆฌ๋ฅผ ๊ตฌ๊ฐ ์ฟผ๋ฆฌ ํน์ RANK() ํจ์๋ก ๋ณ๊ฒฝ
* 2. ์ด ๋ ์ฝ๋ ์ ๊ตฌํ๋ ๋ฉ์๋ ์ถ๊ฐ
* JSP์์๋
* List.jsp์ ํ์ด์ง ๊ด๋ จ ์ฝ๋ ์ถ๊ฐ
*/
public List<BbsDTO> findAll(Map<String, String> map) {
List<BbsDTO> items = new ArrayList<>();
String sql = "SELECT b.id, b.title, b.content, b.hitcount, b.postdate, b.username "
+ "FROM bbs b ";
// ๊ฒ์ ์กฐ๊ฑด ์ถ๊ฐ
if (map.get("searchColumn") != null) {
if ("username".equals(map.get("searchColumn"))) {
sql += "WHERE b.username LIKE '%" + map.get("searchWord") + "%' ";
} else {
sql += "WHERE " + map.get("searchColumn") + " LIKE '%" + map.get("searchWord") + "%' ";
}
}
sql += "ORDER BY b.id DESC";
try {
psmt = conn.prepareStatement(sql);
rs = psmt.executeQuery();
while (rs.next()) {
BbsDTO item = new BbsDTO();
item.setId(rs.getInt("id"));
item.setTitle(rs.getString("title"));
item.setContent(rs.getString("content"));
item.setHitCount(rs.getInt("hitcount"));
item.setPostDate(rs.getDate("postdate"));
item.setUsername(rs.getString("username"));
items.add(item);
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
// ์์ ํด์
close();
}
return items;
}
// ์ด ๋ ์ฝ๋ ์ ์ป๊ธฐ์ฉ
@Override
public int getTotalRecordCount(Map<String,String> map) {
int totalRecordCount=0;
String sql="SELECT COUNT(*) FROM bbs b JOIN users u ON b.username=u.username ";
// ๊ฒ์์ ์๋ ์ฟผ๋ฆฌ ์ถ๊ฐ
if(map !=null && map.get("searchColumn") !=null) {
sql+=" WHERE "+map.get("searchColumn") + " LIKE '%"+map.get("searchWord")+"%' ";
}
try {
psmt = conn.prepareStatement(sql);
rs = psmt.executeQuery();
rs.next();
totalRecordCount= rs.getInt(1);
}
catch(SQLException e) {e.printStackTrace();}
return totalRecordCount;
}
// ์์ธ๋ณด๊ธฐ์ฉ - ๋ ์ฝ๋ ํ๋ ์กฐํ
@Override
public BbsDTO findById(String ... params) {
BbsDTO item=null;
try {
// ๋ชฉ๋ก์์ ๋์ด์จ ๊ฒฝ์ฐ์๋ง ์กฐํ์ ์ฆ๊ฐ
if(params.length >=2 && params[1].toUpperCase().startsWith("BBSLIST")) {
psmt = conn.prepareStatement("UPDATE bbs SET hitcount= hitcount+1 WHERE id=?");
psmt.setString(1, params[0]);
psmt.executeUpdate();
}
// ๋ ์ฝ๋ ํ๋ ์กฐํ
psmt = conn.prepareStatement("SELECT b.*,name FROM bbs b JOIN users u ON b.username=u.username WHERE id=?");
psmt.setString(1, params[0]);
rs = psmt.executeQuery();
if(rs.next()) {
item = new BbsDTO();
item.setContent(rs.getString(4));
item.setHitCount(rs.getInt(5));
item.setId(rs.getInt(1));
item.setPostDate(rs.getDate(6));
item.setTitle(rs.getString(3));
item.setUsername(rs.getString(2));
}
}
catch(SQLException e) {e.printStackTrace();}
return item;
}
// ์ด์ ๊ธ, ๋ค์๊ธ ์กฐํ
public Map<String, BbsDTO> prevNext(String curentId){
Map<String, BbsDTO> map = new HashMap<>();
try {
// ์ด์ ๊ธ ์ป๊ธฐ
psmt = conn.prepareStatement("SELECT id,title FROM bbs WHERE id=(SELECT MAX(id) FROM bbs WHERE id < ?)");
psmt.setString(1,curentId);
rs = psmt.executeQuery();
if(rs.next()) {
map.put("PREV", new BbsDTO(rs.getLong(1), null, rs.getString(2), null, 0, null));
}
// ๋ค์๊ธ ์ป๊ธฐ
psmt = conn.prepareStatement("SELECT id,title FROM bbs WHERE id=(SELECT MIN(id) FROM bbs WHERE id > ?)");
psmt.setString(1,curentId);
rs = psmt.executeQuery();
if(rs.next()) {
map.put("NEXT", new BbsDTO(rs.getLong(1), null, rs.getString(2), null, 0, null));
}
}
catch(SQLException e) {e.printStackTrace();}
return map;
}
// ์
๋ ฅ์ฉ
@Override
public int insert(BbsDTO dto) {
int affected=0;
try {
psmt = conn.prepareStatement("INSERT INTO BBS VALUES(SEQ_BBS.NEXTVAL,?,?,?,DEFAULT,DEFAULT)");
psmt.setString(1, dto.getUsername());
psmt.setString(2, dto.getTitle());
psmt.setString(3, dto.getContent());
affected=psmt.executeUpdate();
rs = psmt.getGeneratedKeys();
if (rs.next()) {
dto.setId(rs.getLong(1)); // ์ฝ์
๋ ID๋ฅผ DTO์ ์ค์
}
}
catch(SQLException e) {e.printStackTrace();}
return affected;
}
@Override
public int update(BbsDTO dto) {
int affected=0;
try {
psmt = conn.prepareStatement("UPDATE bbs SET title=?,content=? WHERE id=?");
psmt.setLong(3, dto.getId());
psmt.setString(1, dto.getTitle());
psmt.setString(2, dto.getContent());
affected=psmt.executeUpdate();
}
catch(SQLException e) {e.printStackTrace();}
return affected;
}
// ์ญ์ ์ฉ
@Override
public int delete(BbsDTO dto) {
int affected=0;
try {
psmt = conn.prepareStatement("DELETE FROM bbs WHERE id=?");
psmt.setLong(1, dto.getId());
affected = psmt.executeUpdate();
}
catch(SQLException e) {e.printStackTrace();}
return affected;
}
// ํ์ ์ฌ๋ถ ํ๋จ์ฉ
public boolean isUser(String username, String password) {
try {
psmt = conn.prepareStatement("SELECT COUNT(*) FROM users WHERE username=? AND password=?");
psmt.setString(1, username);
psmt.setString(2, password);
rs = psmt.executeQuery();
rs.next();
if(rs.getInt(1)==0) return false;
}
catch(SQLException e) {
e.printStackTrace();
return false;
}
return true;
}
}
BbsView.jsp
์๋ ์ฝ๋๋ ๊ฒ์ํ ์์ธ ์กฐํ JSP ๋ก, ๊ฒ์๊ธ์ ๋ด์ฉ๊ณผ ์ด์ ๊ธ, ๋ค์๊ธ์ ์กฐํํ ์ ์์ต๋๋ค.
์ฌ์ฉ์ ์ธ์ฆ์ ํ์ธํ๊ณ , ๊ฒ์๊ธ ์์ , ์ญ์ , ๋ชฉ๋ก ์ด๋ ๊ธฐ๋ฅ์ ์ ๊ณตํฉ๋๋ค.
<%@page import="model.PagingUtil"%>
<%@page import="java.util.Map"%>
<%@page import="model.bbs.BbsDTO"%>
<%@page import="java.util.List"%>
<%@page import="model.bbs.BbsDAO"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!-- ๋ก๊ทธ์ธ ์ฌ๋ถ ํ๋จ:ํํฐ ์ฌ์ฉ์ ์๋ ์ฃผ์์ฒ๋ฆฌ -->
<%-- <jsp:include page="/common/IsUser.jsp" />--%>
<%
// 1.ํ๋ผ๋ฏธํฐ(ํค๊ฐ) ๋ฐ๊ธฐ
long id = Long.parseLong(request.getParameter("id"));
// ํ์ฌ ํ์ด์ง๋ฒํธ ๋ฐ๊ธฐ
String nowPageParam = request.getParameter(PagingUtil.NOWPAGE);
int nowPage = (nowPageParam != null && !nowPageParam.isEmpty()) ? Integer.parseInt(nowPageParam) : 1;
// ํ์ด์ง ์ฌ์ด์ฆ -์ญ์ ์ฉ
String pageSizeParam = request.getParameter(PagingUtil.PAGE_SIZE);
int pageSize = (pageSizeParam != null && !pageSizeParam.isEmpty()) ? Integer.parseInt(pageSizeParam) : 10;
// ๊ฒ์์
String searchColumn = request.getParameter("searchColumn");
String searchWord = request.getParameter("searchWord");
String searchQuery="";
if( searchColumn !=null && searchWord.length() !=0){
searchQuery=String.format("searchColumn=%s&searchWord=%s&", searchColumn,searchWord);
}
// 2.CRUD์์
์ฉ BBSDao ์์ฑ
BbsDAO dao = new BbsDAO(application);
// ์ด์ ํ์ด์ง๋ช
์ป๊ธฐ:List.jsp์์ ๋ทฐ๋ก ์ฌ๋๋ง ์กฐํ์ ์ฆ๊ฐ ํ๊ธฐ ์ํจ
String referer=request.getHeader("referer");
String prevPage = referer.substring(referer.lastIndexOf("/")+1);
// ๋ ์ฝ๋ ํ๋ ๊ฐ์ ธ์ค๊ธฐ
BbsDTO item= dao.findById(String.valueOf(id),prevPage);
if(item==null){
out.println("<script>");
out.println("alert('์ ํจํ์ง ์๋ ๊ธ ๋ฒํธ์
๋๋ค');");
out.println("history.back();");
out.println("</script>");
dao.close();
return;
}
// ๋ด์ฉ ์ค๋ฐ๊ฟ ์ฒ๋ฆฌ
item.setContent(item.getContent().replace("\r\n", "<br/>"));
// ์ด์ ๊ธ, ๋ค์๊ธ ์กฐํ
Map<String,BbsDTO> map= dao.prevNext(String.valueOf(id));
dao.close();
%>
<%
// ์ฟ ํค์์ ํ ํฐ ๊ฐ์ ธ์ค๊ธฐ
Cookie[] cookies = request.getCookies();
String token = null;
if (cookies != null) {
for (Cookie cookie : cookies) {
if ("token".equals(cookie.getName())) {
token = cookie.getValue();
break;
}
}
}
// ์ธ์
์์ ์ฌ์ฉ์ ์ด๋ฆ ๊ฐ์ ธ์ค๊ธฐ
String username = (String) session.getAttribute("username");
// ํ ํฐ ์ ํจ์ฑ ๊ฒ์ฌ
boolean isValidToken = false;
if (username != null && token != null) {
model.user.UserDAO userDAO = new model.user.UserDAO();
isValidToken = userDAO.validateToken(username, token);
if (!isValidToken) {
// ํ ํฐ์ด ์ ํจํ์ง ์๋ค๋ฉด ์ธ์
๋ฌดํจํ ๋ฐ ์ฟ ํค ์ญ์
session.invalidate();
Cookie tokenCookie = new Cookie("token", null);
tokenCookie.setMaxAge(0);
response.addCookie(tokenCookie);
username = null; // ๋น๋ก๊ทธ์ธ ์ํ๋ก ์ค์
}
} else {
// ์ฌ์ฉ์ ์ด๋ฆ์ด๋ ํ ํฐ์ด ์์ผ๋ฉด ๋น๋ก๊ทธ์ธ ์ํ๋ก ์ฒ๋ฆฌ
username = null;
}
%>
<!DOCTYPE html>
<html>
<head>
<%--@ include file="/template/Config.jsp" --%>
<jsp:include page="/template/Config.jsp" />
<title>BbsView.jsp</title>
<style>
th.bg-dark.text-white {
text-align: center;
}
</style>
<script>
function isDelete(){
var pageSize = "<%=pageSize %>";
if(pageSize === null || pageSize === "") {
pageSize = "10"; // ๊ธฐ๋ณธ๊ฐ ์ค์
}
if(confirm("์ ๋ง๋ก ์ญ์ ํ์๊ฒ ์ต๋๊น?")){
location.replace("/YoonSeongBinProj2/bbspage/BbsDelete.jsp?id=<%=item.getId()%>&<%=PagingUtil.NOWPAGE %>=<%=nowPage%>&<%=PagingUtil.PAGE_SIZE %>=" + pageSize);
}
}
</script>
</head>
<body>
<div class="container">
<div class="container-fluid">
<%--@ include file="/template/Header.jsp" --%>
<jsp:include page="/template/Header.jsp" />
<!-- ์ปจํ
์ธ ์์ -->
<div class="p-5 bg-success text-white">
<h1 style="font-weight:bold">์์ฑ๊ธ ์์ธ ๋ณด๊ธฐ</h1>
</div>
<fieldset class="border rounded-3 p-3 text-center mt-2">
<table class="table table-hover">
<tbody>
<tr >
<th class="bg-dark w-25 text-white" >๋ฒํธ</th>
<td><%=item.getId() %></td>
</tr>
<tr>
<th class="bg-dark w-25 text-white">์์ฑ์</th>
<td><%=item.getUsername() %></td>
</tr>
<tr>
<th class="bg-dark w-25 text-white">์์ฑ์ผ</th>
<td><%=item.getPostDate() %></td>
</tr>
<tr>
<th class="bg-dark w-25 text-white">์กฐํ์</th>
<td><%=item.getHitCount() %></td>
</tr>
<tr>
<th class="bg-dark w-25 text-white">์ ๋ชฉ</th>
<td><%=item.getTitle() %></td>
</tr>
<tr>
<th class="bg-dark text-white" colspan="2">๋ด์ฉ</th>
</tr>
<tr>
<td colspan="2"><%=item.getContent()%></td>
</tr>
</tbody>
</table>
<!-- ์ด์ ๊ธ/๋ค์๊ธ -->
<div>
<table class="table" >
<tbody>
<tr>
<td class="text-white bg-dark w-25 text-center" style="font-weight:bold">๋ค์๊ธ</td>
<td>
<%=map.get("NEXT") == null ? "๋ค์๊ธ์ด ์์ต๋๋ค" : String.format("<a href='/YoonSeongBinProj2/bbspage/BbsView.jsp?id=%s&%s=%s&%s=%s'>%s</a>",
map.get("NEXT").getId(), PagingUtil.NOWPAGE, nowPage, PagingUtil.PAGE_SIZE, pageSize, map.get("NEXT").getTitle()) %>
</td>
</tr>
<tr>
<td class="text-white bg-dark w-25 text-center" style="font-weight:bold">์ด์ ๊ธ</td>
<td>
<%=map.get("PREV") == null ? "์ด์ ๊ธ์ด ์์ต๋๋ค" : String.format("<a href='/YoonSeongBinProj2/bbspage/BbsView.jsp?id=%s&%s=%s&%s=%s'>%s</a>",
map.get("PREV").getId(), PagingUtil.NOWPAGE, nowPage, PagingUtil.PAGE_SIZE, pageSize, map.get("PREV").getTitle()) %>
</td>
</tr>
</tbody>
</table>
</div>
<!-- ์์ /์ญ์ /๋ชฉ๋ก ์ปจํธ๋กค ๋ฒํผ -->
<div class="text-center">
<% if (isValidToken && username != null && username.equals(item.getUsername())) { %>
<a href="/YoonSeongBinProj2/bbspage/BbsEdit.jsp?id=<%=item.getId() %>&<%=PagingUtil.NOWPAGE+"="+nowPage %>" class="btn btn-success">์์ </a>
<a href="javascript:isDelete()" class="btn btn-success" >์ญ์ </a>
<a href="/YoonSeongBinProj2/bbspage/BbsList.jsp?<%=PagingUtil.NOWPAGE+"="+nowPage+"&"+searchQuery %>" class="btn btn-success">๋ชฉ๋ก</a>
<% } else { %>
<a href="/YoonSeongBinProj2/bbspage/BbsList.jsp?<%=PagingUtil.NOWPAGE+"="+nowPage+"&"+searchQuery %>" class="btn btn-success">๋ชฉ๋ก</a>
<%}%>
</div>
</fieldset>
<!-- ์ปจํ
์ธ ๋ -->
<%--@ include file="/template/Footer.jsp" --%>
<jsp:include page="/template/Footer.jsp" />
</div>
<!-- container-fluid -->
</div>
<!--container -->
</body>
</html>
BbsEdit.jsp
์๋ ์ฝ๋๋ ๊ฒ์๊ธ ์์ ๊ธฐ๋ฅ์ ์ ๊ณตํ๋ JSP ์ ๋๋ค.
๊ฒ์๊ธ ID๋ก ํด๋น ๋ฐ์ดํฐ๋ฅผ ์กฐํํ๊ณ , ์ ๋ชฉ๊ณผ ๋ด์ฉ์ ์์ ํ ์ ์๋ ํผ์ ์ ๊ณตํฉ๋๋ค.
<%@page import="model.PagingUtil"%>
<%@page import="model.bbs.BbsDTO"%>
<%@page import="java.util.List"%>
<%@page import="model.bbs.BbsDAO"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!-- ๋ก๊ทธ์ธ ์ฌ๋ถ ํ๋จ:ํํฐ ์ฌ์ฉ์ ์๋ ์ฃผ์์ฒ๋ฆฌ -->
<%-- <jsp:include page="/common/IsUser.jsp" />--%>
<%
// ํ๋ผ๋ฏธํฐ(id) ๊ฐ์ด ์กด์ฌํ๊ณ ๋น์ด์์ง ์์ผ๋ฉด long ํ์ผ๋ก ๋ณํ, ์๋๋ฉด ๊ธฐ๋ณธ๊ฐ 0L ์ฌ์ฉ
String idParam = request.getParameter("id");
long id = (idParam != null && !idParam.isEmpty()) ? Long.parseLong(idParam) : 0L;
// ํ์ฌ ํ์ด์ง๋ฒํธ ๋ฐ๊ธฐ
String nowPage = request.getParameter(PagingUtil.NOWPAGE);
// CRUD ์์
์ฉ BbsDao ์์ฑ
BbsDAO dao = new BbsDAO(application);
// ๋ ์ฝ๋ ํ๋ ๊ฐ์ ธ์ค๊ธฐ
BbsDTO item = dao.findById(String.valueOf(id));
// DAO ์ฌ์ฉ ํ ๋ฆฌ์์ค ์ ๋ฆฌ
dao.close();
%>
<!DOCTYPE html>
<html>
<head>
<%--@ include file="/template/Config.jsp" --%>
<jsp:include page="/template/Config.jsp" />
<title>BbsEdit.jsp</title>
</head>
<body>
<div class="container">
<div class="container-fluid">
<%--@ include file="/template/Header.jsp" --%>
<jsp:include page="/template/Header.jsp" />
<!-- ์ปจํ
์ธ ์์ -->
<div class="p-5 bg-success text-white mb-3">
<h1 style="font-weight: bold;">ํ์์ ๊ฒ์ํ ์์ </h1>
</div>
<fieldset class="border rounded-3 p-3 text-center">
<legend class="float-none w-auto px-3" style="font-weight: bold;">์์ ํ
์ ๋ชฉ๊ณผ ๋ด์ฉ์ ์
๋ ฅํ์ธ์</legend>
<form action="/YoonSeongBinProj2/bbspage/BbsEditOk.jsp" method="post">
<input type="hidden" name="id" value="<%=id%>" /> <input
type="hidden" name="<%=PagingUtil.NOWPAGE%>" value="<%=nowPage%>" />
<div class="row justify-content-center">
<div class="col-md-8">
<div class="row mb-3">
<div class="col-md-4 mb-2 mt-5 d-flex align-items-center justify-content-md-end">
<label for="title" class="form-label" style="font-weight: bold;">์ ๋ชฉ</label>
</div>
<div class="col-md-6 mb-3 mt-5">
<input type="text" class="form-control" id="title" placeholder="Enter title" name="title" value="<%=item.getTitle()%>">
</div>
</div>
<div class="row mb-3">
<div class="col-md-4 mb-2 mt-4 d-flex justify-content-md-end">
<label for="content" class="form-label" style="font-weight: bold;">๋ด์ฉ</label>
</div>
<div class="col-md-6 mb-3 mt-3">
<textarea placeholder="Enter content" class="form-control"
rows="18" id="content" name="content"><%=item.getContent()%></textarea>
</div>
</div>
<div class="row mb-3">
<div class="col-md-12">
<button type="submit" class="btn btn-dark ml-auto" style="padding: 10px 30px;">์์ </button>
</div>
</div>
</div>
</div>
</form>
</fieldset>
<!-- ์ปจํ
์ธ ๋ -->
<%--@ include file="/template/Footer.jsp" --%>
<jsp:include page="/template/Footer.jsp" />
</div>
<!-- container-fluid -->
</div>
<!--container -->
</body>
</html>
BbsList.jsp
์๋ ์ฝ๋๋ ๊ฒ์ํ์ ๊ธ ๋ชฉ๋ก์ ํ์ํ๋ JSP ์ ๋๋ค.
๊ฒ์ ๋ฐ ํ์ด์ง ๊ธฐ๋ฅ์ ์ ๊ณตํ๋ฉฐ, ๊ฒ์๊ธ ๋ชฉ๋ก์ ํ ์ด๋ธ ํ์์ผ๋ก ์ถ๋ ฅํฉ๋๋ค.
์ฌ์ฉ์๊ฐ ๋ก๊ทธ์ธํ ๊ฒฝ์ฐ ๊ฒ์๊ธ ๋ฑ๋ก ๋ฒํผ์ ํ์ํ๊ณ , ๊ฒ์ ๊ธฐ๋ฅ์ ํตํด ์ ๋ชฉ, ๋ด์ฉ, ์์ฑ์ ๊ธฐ์ค์ผ๋ก ๊ฒ์๊ธ์ ํํฐ๋งํ ์ ์์ต๋๋ค.
<%@page import="model.PagingUtil"%>
<%@page import="java.util.HashMap"%>
<%@page import="java.util.Map"%>
<%@page import="model.bbs.BbsDTO"%>
<%@page import="java.util.List"%>
<%@page import="model.bbs.BbsDAO"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!-- ๋ก๊ทธ์ธ ์ฌ๋ถ ํ๋จ:ํํฐ ์ฌ์ฉ์ ์๋ ์ฃผ์์ฒ๋ฆฌ -->
<%-- <jsp:include page="/common/IsUser.jsp" />--%>
<%
// ๊ฒ์๊ณผ ๊ด๋ จ๋ ํ๋ผ๋ฏธํฐ ๋ฐ๊ธฐ
String searchColumn = request.getParameter("searchColumn"); // ๊ฒ์ ์ปฌ๋ผ
String searchWord = request.getParameter("searchWord"); // ๊ฒ์์ด
Map<String, String> map = new HashMap<>(); // ๊ฒ์ ์กฐ๊ฑด ๋ด์ ๋งต ์์ฑ
String linkUrl = request.getContextPath() + "/YoonSeongBinProj2/bbspage/BbsList.jsp?"; // ๋งํฌ URL ์ด๊ธฐํ
String searchQuery = ""; // ๊ฒ์ ์ฟผ๋ฆฌ ์ด๊ธฐํ
if (searchColumn != null && searchWord != null && !searchWord.isEmpty()) {
map.put("searchColumn", searchColumn); // ๊ฒ์ ์ปฌ๋ผ ์ถ๊ฐ
map.put("searchWord", searchWord); // ๊ฒ์์ด ์ถ๊ฐ
searchQuery = String.format("searchColumn=%s&searchWord=%s&", searchColumn, searchWord); // ๊ฒ์ ์ฟผ๋ฆฌ ํ์ ์ง์
linkUrl += searchQuery; // ๋งํฌ URL์ ๊ฒ์ ์ฟผ๋ฆฌ ์ถ๊ฐ
}
// ์ ์ฒด ๊ธ ๋ชฉ๋ก ๊ฐ์ ธ์ค๊ธฐ
BbsDAO dao = new BbsDAO(application);
map.put(PagingUtil.PAGE_SIZE, this.getInitParameter("PAGE-SIZE")); // ํ์ด์ง ์ฌ์ด์ฆ ์ค์
map.put(PagingUtil.BLOCK_PAGE, this.getInitParameter("BLOCK-PAGE")); // ํ์ด์ง ๋ธ๋ก ์ฌ์ด์ฆ ์ค์
PagingUtil.setMapForPaging(map, dao, request); // ํ์ด์ง ์ฒ๋ฆฌ ์ค์
int totalRecordCount = Integer.parseInt(map.get(PagingUtil.TOTAL_RECORD_COUNT)); // ์ ์ฒด ๊ธ ๊ฐ์
int pageSize = Integer.parseInt(map.get(PagingUtil.PAGE_SIZE)); // ํ์ด์ง ์ฌ์ด์ฆ
int blockPage = Integer.parseInt(map.get(PagingUtil.BLOCK_PAGE)); // ๋ธ๋ก ํ์ด์ง ์ฌ์ด์ฆ
int nowPage = Integer.parseInt(map.get(PagingUtil.NOWPAGE)); // ํ์ฌ ํ์ด์ง ๋ฒํธ
// ํ์ด์ง์ ์ํ ๋ก์ง ๋
List<BbsDTO> items = dao.findAll(map); // ์ ์ฒด ๊ฒ์๊ธ ๋ชฉ๋ก ๊ฐ์ ธ์ค๊ธฐ
dao.close(); // DB ์ฐ๊ฒฐ ์ข
๋ฃ
%>
<!DOCTYPE html>
<html>
<head>
<%--@ include file="/template/Config.jsp" --%>
<jsp:include page="/template/Config.jsp" />
<title>BbsList.jsp</title>
</head>
<body>
<div class="container">
<div class="container-fluid">
<%--@ include file="/template/Header.jsp" --%>
<jsp:include page="/template/Header.jsp" />
<!-- ์ปจํ
์ธ ์์ -->
<div class="p-5 bg-success text-white mb-3">
<h1 style="font-weight: bold;">๊ฒ์ํ ๋ชฉ๋ก</h1>
</div>
<div class="my-2 text-end">
<% String username = (String) session.getAttribute("username");
String token = (String) session.getAttribute("token");
if (username != null && token != null) { %>
<a href="BbsWrite.jsp" class="btn btn-danger">๊ฒ์๊ธ ๋ฑ๋ก</a>
<% } else {} %>
</div>
<table class="table table-hover text-center">
<thead class="table-dark">
<tr>
<th class="col-1">๋ฒํธ</th>
<th class="col-auto">์ ๋ชฉ</th>
<th class="col-2">์์ฑ์</th>
<th class="col-1">์กฐํ์</th>
<th class="col-2">์์ฑ์ผ</th>
</tr>
</thead>
<tbody>
<%
// ๊ฒ์๊ธ์ด ์์ผ๋ฉด "๋ฑ๋ก๋ ๊ธ์ด ์์ต๋๋ค" ํ์
if (items.isEmpty()) {
%>
<tr>
<td colspan="5">๋ฑ๋ก๋ ๊ธ์ด ์์ต๋๋ค.</td>
</tr>
<%
// ๊ฒ์๊ธ์ด ์์ผ๋ฉด ๋ชฉ๋ก ์ถ๋ ฅ
} else {
int loop = 0;
for (BbsDTO item : items) {
%>
<tr>
<td><%=totalRecordCount - (((nowPage - 1) * pageSize) + loop)%></td>
<td class="text-start"><a
href="BbsView.jsp?id=<%=item.getId() + "&" + PagingUtil.NOWPAGE + "=" + nowPage + "&" + searchQuery + PagingUtil.PAGE_SIZE + "="
+ pageSize%>"><%=item.getTitle()%></a></td>
<td><%=item.getUsername()%></td>
<td><%=item.getHitCount()%></td>
<td><%=item.getPostDate()%></td>
</tr>
<%
loop++;
}
}
%>
</tbody>
</table>
<!-- ํ์ด์ง ์ถ๋ ฅ -->
<%=PagingUtil.pagingBootStrapStyle(totalRecordCount, pageSize, blockPage, nowPage, linkUrl)%>
<!-- ๊ฒ์ UI -->
<form method="post" class="row justify-content-center"> // ๊ฒ์ ํผ
<div class="col-2">
<select class="form-control" name="searchColumn">
<option value="title">์ ๋ชฉ</option>
<option value="content">๋ด์ฉ</option>
<option value="username"> ์์ฑ์</option>
</select>
</div>
<div class="col-5">
<input type="text" class="form-control mx-2"
placeholder="๊ฒ์์ด๋ฅผ ์
๋ ฅํ์ธ์" name="searchWord" />
</div>
<div class="col-auto">
<button type="submit" class="btn btn-primary">๊ฒ์</button>
</div>
</form>
<!-- ์ปจํ
์ธ ๋ -->
<jsp:include page="/template/Footer.jsp" />
</div>
<!-- container-fluid -->
</div>
<!--container -->
</body>
</html>
BbsDelete.jsp
์๋ ์ฝ๋๋ ๊ฒ์๊ธ์ ์ญ์ ํ๋ ๊ธฐ๋ฅ์ ๊ฐ์ง JSP ์ ๋๋ค.
์ฌ์ฉ์๊ฐ ์ญ์ ํ๋ ค๋ ๊ฒ์๊ธ์ ID๋ฅผ ํ๋ผ๋ฏธํฐ๋ก ๋ฐ์ ํด๋น ๊ฒ์๊ธ์ ์ญ์ ํ ํ, ์ญ์ ๊ฐ ์ฑ๊ณต์ ์ผ๋ก ์ด๋ฃจ์ด์ง๋ฉด ๊ฒ์๊ธ ๋ชฉ๋ก ํ์ด์ง๋ก ๋ฆฌ๋๋ ์ ํฉ๋๋ค.
์ญ์ ์ ์คํจํ ๊ฒฝ์ฐ, ์๋ฆผ ์ฐฝ์ ๋์ฐ๊ณ ์ด์ ํ์ด์ง๋ก ๋์๊ฐ๋๋ค.
์ญ์ ํ ์ ์ฒด ํ์ด์ง ์๋ฅผ ์ฌ๊ณ์ฐํ๊ณ , ํ์ฌ ํ์ด์ง๊ฐ ์ญ์ ํ ํ์ด์ง ์๋ณด๋ค ๋ง์ผ๋ฉด ๋ง์ง๋ง ํ์ด์ง๋ก ์ด๋ํ๊ฒ ์ฒ๋ฆฌ๋ฉ๋๋ค.
<%@page import="java.util.HashMap"%>
<%@page import="java.util.Map"%>
<%@page import="model.PagingUtil"%>
<%@page import="model.bbs.BbsDTO"%>
<%@page import="model.bbs.BbsDAO"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!-- Delete.jsp -->
<!-- ๋ก๊ทธ์ธ ์ฌ๋ถ ํ๋จ:ํํฐ ์ฌ์ฉ์ ์๋ ์ฃผ์์ฒ๋ฆฌ -->
<%-- <jsp:include page="/common/IsUser.jsp" />--%>
<%
// 1.ํ๋ผ๋ฏธํฐ(ํค๊ฐ) ๋ฐ๊ธฐ
long id = Long.parseLong(request.getParameter("id"));
//ํ์ฌ ํ์ด์ง๋ฒํธ ๋ฐ๊ธฐ
int nowPage = request.getParameter(PagingUtil.NOWPAGE) == null ? 1 : Integer.parseInt(request.getParameter(PagingUtil.NOWPAGE));
//ํ์ด์ง ์ฌ์ด์ฆ -์ญ์ ์ฉ
int pageSize = request.getParameter(PagingUtil.PAGE_SIZE) == null ? 10 : Integer.parseInt(request.getParameter(PagingUtil.PAGE_SIZE));
// 2.CRUD์์
์ฉ BbsDao์์ฑ
BbsDAO dao = new BbsDAO(application);
BbsDTO dto = new BbsDTO();
dto.setId(id);
int affected=dao.delete(dto);
// ์ญ์ ํ์ ์ด ํ์ด์ง ์ ๊ตฌํจ
int totalRecordCount = dao.getTotalRecordCount(null); // ๊ฒ์์๋ ์ ์ฉ ์๋ ๋ฐ๋์ ๋งต ์ ๋ฌ
int totalPage=(int)Math.ceil((double)totalRecordCount/pageSize);
dao.close();
if(totalPage < nowPage) nowPage=totalPage;
if(affected==1){
response.sendRedirect("/YoonSeongBinProj2/bbspage/BbsList.jsp?"+PagingUtil.NOWPAGE+"="+nowPage);
}
else{
out.println("<script>");
out.println("alert('์ญ์ ์คํจํ์ด์');");
out.println("history.back();");
out.println("</script>");
}
%>
BbsWrite.jsp
์๋ ์ฝ๋๋ ๊ฒ์๊ธ์ ์์ฑํ๋ JSP ๋ก, ์ฌ์ฉ์์๊ฒ ์ ๋ชฉ๊ณผ ๋ด์ฉ์ ์ ๋ ฅ๋ฐ๋ ํผ์ ์ ๊ณตํฉ๋๋ค.
ํผ์ ์ ๋ ฅ๋ ๋ฐ์ดํฐ๋ฅผ 'WriteController'๋ก POST ๋ฐฉ์์ผ๋ก ์ ์กํ์ฌ ๊ฒ์๊ธ์ ๋ฑ๋กํ๊ฒ ๋ฉ๋๋ค.
ํผ ๋ด์๋ ์ ๋ชฉ๊ณผ ๋ด์ฉ ์ ๋ ฅ ํ๋๊ฐ ์์ผ๋ฉฐ, ์ฌ์ฉ์๊ฐ ์ ๋ ฅ์ ์๋ฃํ ํ '๋ฑ๋ก' ๋ฒํผ์ ํด๋ฆญํ๋ฉด ๋ฐ์ดํฐ๊ฐ ์๋ฒ๋ก ์ ๋ฌ๋์ด ๊ฒ์๊ธ์ด ์์ฑ๋ฉ๋๋ค.
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>
<html>
<head>
<jsp:include page="/template/Config.jsp" />
<title>BbsWrite.jsp</title>
</head>
<body>
<div class="container">
<div class="container-fluid">
<jsp:include page="/template/Header.jsp" />
<!-- ์ปจํ
์ธ ์์ -->
<div class="p-5 bg-success text-white mb-3">
<h1 style="font-weight: bold;">๊ฒ์๊ธ ๋ฑ๋ก</h1>
</div>
<fieldset class="border rounded-3 p-3 text-center">
<legend class="float-none w-auto px-3" style="font-weight: bold;">๋ฑ๋กํ ์ ๋ชฉ๊ณผ ๋ด์ฉ์ ์
๋ ฅํ์ธ์</legend> // ํผ ์ ๋ชฉ
<form action="${pageContext.request.contextPath}/WriteController" method="post"> // ํผ ์ ์ถ ์ก์
<div class="row justify-content-center">
<div class="col-md-8">
<div class="row mb-3"> // ์ ๋ชฉ ์
๋ ฅ ํผ
<div class="col-md-4 mb-2 mt-5 d-flex align-items-center justify-content-md-end">
<label for="title" class="form-label" style="font-weight: bold;">์ ๋ชฉ</label>
</div>
<div class="col-md-6 mb-3 mt-5"> // ์ ๋ชฉ ์
๋ ฅ ํ๋
<input type="text" class="form-control" id="title" placeholder="์ ๋ชฉ์ ์
๋ ฅํ์ธ์" name="title">
</div>
</div>
<div class="row mb-3"> // ๊ธ ๋ด์ฉ ์
๋ ฅ ํผ
<div class="col-md-4 mb-2 mt-4 d-flex justify-content-md-end">
<label for="content" class="form-label" style="font-weight: bold;">๊ธ ๋ด์ฉ</label>
</div>
<div class="col-md-6 mb-3 mt-3"> // ๋ด์ฉ ์
๋ ฅ ํ๋
<textarea class="form-control" rows="18" id="content" name="content" placeholder="๊ธ์ ์
๋ ฅํ์ธ์"></textarea>
</div>
</div>
<div class="row mb-3"> // ๋ฑ๋ก ๋ฒํผ
<div class="col-md-12">
<button type="submit" class="btn btn-dark ml-auto" style="padding: 10px 30px;">๋ฑ๋ก</button>
</div>
</div>
</div>
</div>
</form>
</fieldset>
<!-- ์ปจํ
์ธ ๋ -->
<jsp:include page="/template/Footer.jsp" />
</div>
<!-- container-fluid -->
</div>
<!--container -->
</body>
</html>