1. 오라클 database에 sample_board_users 테이블 추가
CREATE TABLE SAMPLE_BOARD_USERS (
USER_ID VARCHAR2(20) PRIMARY KEY,
USER_PASSWORD VARCHAR2(20) NOT NULL,
USER_NAME VARCHAR2(100) NOT NULL,
USER_EMAIL VARCHAR2(255) UNIQUE,
USER_DELETED CHAR(1) DEFAULT 'N',
USER_CREATED_DATE DATE DEFAULT SYSDATE,
USER_UPDATED_DATE DATE DEFAULT SYSDATE
);
boards 테이블의 board_writer를 users 테이블의 user_id와 외래키 연결
reviews 테이블의 review_writer를 users 테이블의 user_id와 외래키 연결
ALTER TABLE SAMPLE_BOARDS ADD CONSTRAINT BOARD_WRITER_FK
FOREIGN KEY (BOARD_WRITER) REFERENCES SAMPLE_BOARD_USERS (USER_ID);
ALTER TABLE SAMPLE_BOARD_REVIEWS ADD CONSTRAINT BOARD_REVIEW_WRITER_FK
FOREIGN KEY (REVIEW_WRITER) REFERENCES SAMPLE_BOARD_USERS (USER_ID);
2. User 객체, UserDao, userxml 등을 모두 생성
3. 공통되는 헤더 부분을 따로 뺌
-> 맨위의 공통되는 바 부분을 common/header.jsp에 적음
각 JSP (detail.jsp, form.jsp, list.jsp, modifyform.jsp, home.jsp) 의 헤더부분 변경
ex) home.jsp
<%@page import="com.sample.vo.User"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/js/bootstrap.bundle.min.js"></script>
<title>익명 게시판</title>
</head>
<body>
<%-- common폴더의 header.jsp를 이 jsp페이지에 포함시킨다. --%>
<jsp:include page="common/header.jsp">
<jsp:param name="menu" value="home"/>
</jsp:include>
<div class="container my-3">
<div class="row mb-3">
<div class="col">
<div class="border p-3 bg-light">
<h1 class="mb-4">샘플 애플리케이션 입니다.</h1>
<p class="">익명 게시판, 회원가입, 로그인 기능을 지원합니다.</p>
</div>
</div>
</div>
</div>
</body>
</html>
- home.jsp
<jsp:param name="menu" value="home"/>
- board폴더의
detail.jsp, form.jsp, list.jsp, modifyform.jsp에는
<jsp:param name="menu" value="board"/>
- user폴더의
completed.jsp
<jsp:param name="menu" value="register"/>
form.jsp
<jsp:param name="menu" value="register"/>
loginform.jsp
<jsp:param name="menu" value="login"/>
- header.jsp
1) name에 담긴 value 값을 header.jsp 에서 받아서 menu변수에 저장
2) 메뉴를 클릭할 때마다 활성화 효과 주기
- menu가 "home"이면 "홈"에 활성화
- menu가 "board"면 "게시물"에 활성화
<%
/*
home, detail, list, modifyform 각 JSP에서 include할 때 각 JSP로부터 받은 이름이 "menu"인 것의 값 추출
<jsp:include page="common/header.jsp">
<jsp:param name="menu" value="home"/>
</jsp:include>
*/
String menu = request.getParameter("menu");
%>
<nav class="navbar navbar-expand-sm bg-dark navbar-dark">
<div class="container">
<ul class="navbar-nav me-auto">
<li class="nav-item"><a class="nav-link <%="home".equals(menu) ? "active bg-danger" : "" %>" href="/web-board/home.jsp">홈</a></li>
<li class="nav-item"><a class="nav-link <%="board".equals(menu) ? "active bg-danger" : "" %>" href="/web-board/board/list.jsp">게시판</a></li>
</ul>
</div>
</nav>
4. 회원가입
- user / form.jsp (회원가입 폼)
* 회원가입 jsp에서 보낸 error 라는 이름의 값을 받아서 errorCode에 저장
-> 전달받은 errorCode의 이름이 "invalid"이면 -> 존재하는 아이디, 이메일이 있다는 뜻
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/js/bootstrap.bundle.min.js"></script>
<title>익명 게시판</title>
<style type="text/css">
textarea {
resize: none;
}
</style>
</head>
<body>
<jsp:include page="../common/header.jsp">
<jsp:param name="menu" value="register"/>
</jsp:include>
<div class="container my-3">
<h1 class="mb-3 fs-4 border p-2 bg-light">회원가입 폼</h1>
<%
// register.jsp에서 회원가입 실패로 form.jsp?error=invalid로 재요청했을 때 errorCode에 "error"의 값인 invalid 저장
String errorCode = request.getParameter("error");
%>
<p>아이디, 비밀번호, 이름, 이메일을 입력해서 회원가입을 신청하세요</p>
<%
if("invalid".equals(errorCode)){
%>
<div class="alert alert-danger">
<strong>회원가입 오류</strong> 아이디 혹은 이메일이 이미 사용중입니다.
</div>
<%
}
%>
<form class="bg-light border p-3" method="post" action="register.jsp"> <%-- 같은 폴더에 있는 register.jsp --%>
<div class="mb-3">
<label class="form-label">아이디</label>
<input type="text" class="form-control" name="id" />
</div>
<div class="mb-3">
<label class="form-label">비밀번호</label>
<input type="password" class="form-control" name="password" />
</div>
<div class="mb-3">
<label class="form-label">이름</label>
<input type="text" class="form-control" name="name" />
</div>
<div class="mb-3">
<label class="form-label">이메일</label>
<input type="text" class="form-control" name="email" />
</div>
<div class="text-end">
<a href="../home.jsp" class="btn btn-secondary">취소</a> <%-- 상위 폴더에 있는 home.jsp --%>
<button type="submit" class="btn btn-primary">회원가입</button>
</div>
</form>
</div>
</body>
</html>
- user / register.jsp (회원가입)
* 아이디, 이메일이 null이 아니다 = 일치하는 아이디, 이메일이 있다 -> 이미 등록된 회원 -> 회원가입 오류
-> 회원가입폼에 오류페이지를 재요청 response.sendRedirect("form.jsp?error=invalid");
(이름은 error, 값은 invalid인 것을 전달해줌)
-> return 반드시 붙임 !!!
-> 회원가입폼에서 전달받음
<%@page import="com.sample.dao.UserDao"%>
<%@page import="com.sample.vo.User"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
// 회원가입 폼에서 register.jsp를 실행요청할 때 제출한 폼 입력값을 요청객체에서 조회한다.
String id = request.getParameter("id");
String password = request.getParameter("password");
String name = request.getParameter("name");
String email = request.getParameter("email");
// User객체를 생성해서 조회된 값을 저장한다.
User user = new User();
user.setId(id);
user.setPassword(password);
user.setName(name);
user.setEmail(email);
// UserDao 객체를 생성한다.
UserDao userDao = new UserDao();
// 아이디로 사용자정보를 조회한다. 사용자정보가 null이 아니면 form.jsp를 재요청하는 URL을 응답으로 보낸다. error라는 이름의 값이 invalid
User savedUser = userDao.getUserById(id);
if(savedUser != null){
response.sendRedirect("form.jsp?error=invalid");
return;
}
// 이메일로 사용자정보를 조회한다. 사용자정보가 null이 아니면 form.jsp를 재요청하는 URL을 응답으로 보낸다. error라는 이름의 값이 invalid
savedUser = userDao.getUserByEmail(email);
if(savedUser != null){
response.sendRedirect("form.jsp?errer=invalid");
return;
}
// insertUser(user)를 실행해서 데이터베이스에 저장시킨다.
userDao.insertUser(user);
// 재요청 URL을 응답으로 보낸다.
response.sendRedirect("completed.jsp");
%>
4. 로그인
- user / loginform.jsp (로그인 폼)
* 로그인 jsp에서 보낸 error 라는 이름의 값을 받아서 errorCode에 저장
-> 전달받은 errorCode의 이름이 "fail"이면 -> 아이디가 없거나, 비밀번호가 틀리다는 뜻
* 회원가입 안했는데 url에 직접적으로 board / form.jsp 또는 board / register.jsp를 입력해서 들어올 경우를 고려
-> form.jsp 와 register.jsp 에서 loginform.jsp?error=deny 요청
-> 전달받은 errorCode의 이름이 "deny"이면 -> 로그인 필요 -> 로그인 폼 재요청
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/js/bootstrap.bundle.min.js"></script>
<title>익명 게시판</title>
<style type="text/css">
textarea {
resize: none;
}
</style>
</head>
<body>
<jsp:include page="../common/header.jsp">
<jsp:param name="menu" value="login"/>
</jsp:include>
<div class="container my-3">
<h1 class="mb-3 fs-4 border p-2 bg-light">로그인 폼</h1>
<p>아이디, 비밀번호 입력해서 로그인하세요</p>
<%
String errorCode = request.getParameter("error");
if("fail".equals(errorCode)){
%>
<div class="alert alert-danger">
<strong>로그인 실패</strong> 아이디 혹은 비밀번호가 일치하지 않습니다.
</div>
<%
} else if ("deny".equals(errorCode)) {
%>
<div class="alert alert-danger">
<strong>요청 거부</strong> 로그인이 필요한 접근입니다.
</div>
<%
}
%>
<form class="bg-light border p-3" method="post" action="login.jsp">
<div class="mb-3">
<label class="form-label">아이디</label>
<input type="text" class="form-control" name="id" />
</div>
<div class="mb-3">
<label class="form-label">비밀번호</label>
<input type="password" class="form-control" name="password" />
</div>
<div class="text-end">
<button type="submit" class="btn btn-primary">로그인</button>
<a href="form.jsp" class="btn btn-secondary">회원가입</a>
</div>
</form>
</div>
</body>
</html>
- user / login.jsp (로그인)
* 로그인 폼에서 요청받은 값들을 받아서 변수에 저장
-> 아이디에 해당하는 사용자정보 조회
-> 사용자정보가 null이거나, 비밀번호가 일치하지 않으면 로그인 폼으로 error=fail 재요청
-> 인증이 완료된 사용자정보를 "loginedUser"라는 이름으로 세션객체에 저장
-> 세션아이디를 쿠키에 담아서 응답으로 보냄
-> 브라우저를 껐다 켜도 유지
-> 아예 다른 브라우저를 이용해야 세션객체가 새로 생김 ( 크롬/ 웨일 )
<%@page import="com.sample.vo.User"%>
<%@page import="com.sample.dao.UserDao"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
// 로그인 폼에서 login.jsp를 실행요청할 때 제출한 폼 입력값을 요청객체에서 조회한다.
String id = request.getParameter("id");
String password = request.getParameter("password");
// UserDao 객체 생성
UserDao userDao = new UserDao();
// 아이디로 사용자 정보를 조회해서 사용자정보가 null이면 가입된 아이디가 아니므로 로그인화면을 재요청하는 URL을 응답으로 보낸다.
// 조회된 사용자정보의 비밀번호와 입력한 비밀번호가 일치하지 않으면 로그인화면을 재요청하는 URL을 응답으로 보낸다.
User savedUser = userDao.getUserById(id);
if(savedUser == null){
response.sendRedirect("loginform.jsp?error=fail");
return;
}
if(!savedUser.getPassword().equals(password)){
response.sendRedirect("loginform.jsp?error=fail");
return;
}
// 사용자 인증이 완료된 경우, 세션객체에 사용자정보를 저장한다.
// HttpSession의 setAttribute(String name, Object value) 메소드를 사용해서 세션객체에 사용자 정보를 저장한다.
session.setAttribute("loginedUser", savedUser);
// 재요청 URL을 응답으로 보낸다.
response.sendRedirect("../home.jsp");
%>
- logout.jsp (로그아웃)
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
// 로그아웃은 기존 세션객체를 무효화시킨다.
session.invalidate();
// 재요청 URL을 응답으로 보낸다.
response.sendRedirect("../home.jsp");
%>
5. 로그인 후 글 작성, 수정, 삭제 -> 본인만 할 수 있도록 하기
- home.jsp (홈화면) 요청
* 요청할 때마다 세션아이디 전달
* 로그인.jsp에서 인증완료된 사용자 정보를 "logintedUser" 이름으로 세션 객체에 저장했음
-> "loginedUser" 정보를 얻음
* 등록된 사용자 정보가 아니면 -> 로그인, 회원가입 표시
* 등록된 사용자 정보이면 -> 로그아웃만 표시
<%@page import="com.sample.vo.User"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
/*
home, detail, list, modifyform 각 JSP에서 include할 때 각 JSP로부터 받은 이름이 "menu"인 것의 값 추출
<jsp:include page="common/header.jsp">
<jsp:param name="menu" value="home"/>
</jsp:include>
*/
String menu = request.getParameter("menu");
/*
HttpSession 객체에 저장된 인증된 사용자 정보를 조회한다.
login.jsp에서 인증이 완료된 사용자정보를 아래와 같이 HttpSession 객체에 저장했다.
User savedUser = userDao.getUserById(id);
session.setAttribute("loginedUser", savedUser);
*/
User user = (User) session.getAttribute("loginedUser");
%>
<nav class="navbar navbar-expand-sm bg-dark navbar-dark">
<div class="container">
<ul class="navbar-nav me-auto">
<li class="nav-item"><a class="nav-link <%="home".equals(menu) ? "active bg-danger" : "" %>" href="/web-board/home.jsp">홈</a></li>
<li class="nav-item"><a class="nav-link <%="board".equals(menu) ? "active bg-danger" : "" %>" href="/web-board/board/list.jsp">게시판</a></li>
</ul>
<%
if(user == null){
%>
<ul class="navbar-nav">
<li class="nav-item"><a class="nav-link <%="login".equals(menu) ? "active bg-danger" : "" %>" href="/web-board/user/loginform.jsp">로그인</a></li>
<li class="nav-item"><a class="nav-link <%="register".equals(menu) ? "active bg-danger" : "" %>" href="/web-board/user/form.jsp">회원가입</a></li>
</ul>
<%
} else {
%>
<span class="navbar-text"><strong class="text-white"><%=user.getName() %></strong>님 환영합니다.</span>
<ul class="navbar-nav">
<li class="nav-item"><a class="nav-link" href="/web-board/user/logout.jsp">로그아웃</a></li>
</ul>
<%
}
%>
</div>
</nav>
- list.jsp (게시물 목록) 요청
* 인증된 사용자 정보가 존재하면 -> 새글 등록 링크 출력
<%@page import="com.sample.vo.User"%>
<%@page import="java.util.HashMap"%>
<%@page import="java.util.Map"%>
<%@page import="com.sample.util.StringUtils"%>
<%@page import="com.sample.vo.Board"%>
<%@page import="java.util.List"%>
<%@page import="com.sample.dao.BoardDao"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/js/bootstrap.bundle.min.js"></script>
<title>익명 게시판</title>
</head>
<body>
<jsp:include page="../common/header.jsp">
<jsp:param name="menu" value="board"/>
</jsp:include>
<div class="container my-3">
<h1 class="mb-3 fs-4 border p-2 bg-light">게시글 리스트</h1>
<p>게시글 목록을 확인하세요.
<%
// HttpSession 객체에 저장된 인증된 사용자 정보를 조회한다.
User user = (User) session.getAttribute("loginedUser");
// 인증된 사용자 정보가 존재하면, 새글 등록 링크를 출력한다.
if(user != null){
%>
<a href="form.jsp" class="btn btn-primary btn-sm float-end">새 글 등록</a>
<%
}
%>
</p>
<%
// < 최신순 10개씩 보이기 >
// 1. 한 페이지에 게시물 10개씩 보이기 결정
// 2. 현재 페이지 번호 조회
// 3. 현재 페이지에 해당하는 게시물 범위 (1~10, 11~20)
// 4. map에 조회범위 담기 ( pageNo가 begin과 end 사이 )
// 5. 해당 범위의 게시물 조회하는 메소드 만들어서 담기
int rows = 10;
int currentPage = StringUtils.stringToInt(request.getParameter("page"),1);
int begin = (currentPage-1)*rows + 1;
int end = currentPage*rows;
Map<String, Object> param = new HashMap<>();
param.put("begin", begin);
param.put("end", end);
BoardDao boardDao = new BoardDao();
List<Board> boardList = boardDao.getBoards(param);
%>
<table class="table">
<thead>
<tr>
<th>번호</th>
<th>제목</th>
<th>작성자</th>
<th>조회수</th>
<th>등록일</th>
</tr>
</thead>
<tbody>
<%
if(boardList.isEmpty()){
%>
<tr>
<td colspan="5" class="text-center">등록된 게시글이 없습니다.</td>
</tr>
<%
} else {
for(Board board : boardList) {
%>
<tr>
<td><%=board.getNo() %></td>
<td><a href="detail.jsp?boardNo=<%=board.getNo() %>" class="text-decoration-none text-dark"><%=board.getTitle() %></a></td>
<td><%=board.getWriter() %></td>
<td><%=board.getReadCount() %></td>
<td><%=StringUtils.dateToText(board.getCreatedDate()) %></td>
</tr>
<%
}
}
%>
</tbody>
</table>
<%
// 1. 한 화면에 표시할 페이지 개수 결정 - 5개 (이전,1,2,3,4,5,다음)
// 2. 전체 행 개수 조회 ( 메소드 )
// 3. 전체 페이지 수 계산
// 4. 총 페이지 블럭 개수
// 5. 현재 페이지 블럭 계산
// 6. 페이지 블럭의 범위
int pages = 5;
int totalRows = boardDao.getTotalRows();
int totalPages = (int) Math.ceil((double)totalRows/rows);
int totalPageBlocks = (int) Math.ceil((double)totalPages/pages);
int currentPageBlock = (int) Math.ceil((double)currentPage/pages);
int beginPage = (currentPageBlock - 1)*pages + 1;
int endPage = currentPageBlock == totalPageBlocks ? totalPages : currentPageBlock*pages ;
%>
<div aria-label="navigation">
<ul class="pagination justify-content-center">
<li class="page-item <%=currentPage<=1 ? "disabled" : ""%>">
<a class="page-link" href="list.jsp?page=<%=currentPage - 1%>">이전</a>
</li>
<%
for(int number=beginPage; number<=endPage; number++) {
%>
<li class="page-item <%=number == currentPage ? "active" : ""%>">
<a class="page-link" href="list.jsp?page=<%=number%>"><%=number %></a>
</li>
<%
}
%>
<li class="page-item <%=currentPage >= totalPages ? "disabled" : ""%>">
<a class="page-link" href="list.jsp?page=<%=currentPage + 1%>">다음</a>
</li>
</ul>
</div>
</div>
</body>
</html>
- form.jsp (게시글 등록 폼 ) 요청
* (URL에 직접 입력하는 경우) 인증된 사용자 정보가 존재하지 않으면 -> 로그인 폼 재요청
<%@page import="com.sample.vo.User"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
// HttpSession 객체에 저장된 인증된 사용자 정보를 조회한다.
User user = (User) session.getAttribute("loginedUser");
// 인증된 사용자 정보가 존재하지 않으면, 로그인 폼을 재요청하게 한다.
if(user == null){
response.sendRedirect("../user/loginform.jsp?error=deny");
return;
}
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/js/bootstrap.bundle.min.js"></script>
<title>익명 게시판</title>
<style type="text/css">
textarea {
resize: none;
}
</style>
</head>
<body>
<jsp:include page="../common/header.jsp">
<jsp:param name="menu" value="board"/>
</jsp:include>
<div class="container my-3">
<h1 class="mb-3 fs-4 border p-2 bg-light">게시글 등록폼</h1>
<p>제목, 작성자, 내용을 입력해서 새 게시글을 등록하세요</p>
<form class="bg-light border p-3" method="post" action="register.jsp">
<div class="mb-3">
<label class="form-label">제목</label>
<input type="text" class="form-control" name="title" />
</div>
<div class="mb-3">
<label class="form-label">내용</label>
<textarea class="form-control" rows="6" name="content"></textarea>
</div>
<div class="text-end">
<a href="list.jsp" class="btn btn-secondary">취소</a>
<button type="submit" class="btn btn-primary">등록</button>
</div>
</form>
</div>
</body>
</html>
- register.jsp (게시글 등록 ) 요청
* (URL에 직접 입력하는 경우) 인증된 사용자 정보가 존재하지 않으면 -> 로그인 폼 재요청
* 작성자 -> 로그인한 사용자의 아이디 전달
=> 작성자를 직접 전달받지 않는다 ! (세션객체에 들어있는 정보를 빼서 쓰는 것임 !!!)
<%@page import="com.sample.vo.User"%>
<%@page import="com.sample.vo.Board"%>
<%@page import="com.sample.dao.BoardDao"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
//HttpSession 객체에 저장된 인증된 사용자 정보를 조회한다.
User user = (User) session.getAttribute("loginedUser");
// 인증된 사용자 정보가 존재하지 않으면, 로그인 폼을 재요청하게 한다.
if(user == null){
response.sendRedirect("../user/loginform.jsp?error=deny");
return;
}
String title = request.getParameter("title");
String content = request.getParameter("content");
Board board = new Board();
board.setTitle(title);
board.setWriter(user.getId()); // 작성자에 로그인한 사용자의 아이디를 넣는다.
board.setContent(content);
BoardDao boardDao = new BoardDao();
boardDao.insertBoard(board);
response.sendRedirect("list.jsp");
%>
- delete.jsp (게시글 삭제) 요청
* 인증된 사용자 정보가 존재하지 않으면 로그인폼 재요청
* 로그인한 사용자의 아이디와 게시글 작성자의 아이디가 다르면 게시글 삭제 불가 -> detail.jsp를 재요청
<%@page import="com.sample.util.StringUtils"%>
<%@page import="com.sample.vo.User"%>
<%@page import="com.sample.vo.Board"%>
<%@page import="com.sample.dao.BoardDao"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
// 인증된 사용자 정보를 조회 -> 인증된 사용자정보가 존재하지 않으면 loginform.jsp를 재요청하는 응답을 보낸다.
User user = (User) session.getAttribute("loginedUser");
if(user == null){
response.sendRedirect("../user/loginform.jsp?error=deny");
return;
}
// 게시글 정보를 삭제하세요. sample_boards의 board_delete를 'Y'으로 변경하세요
int no = StringUtils.stringToInt(request.getParameter("no"));
BoardDao boardDao = new BoardDao();
Board board = boardDao.getBoardByNo(no);
// 로그인한 사용자의 아이디와 게시글 작성자의 아이디가 다르면 게시글 삭제 불가
// detail.jsp를 재요청하는 URL을 응답
if(!user.getId().equals(board.getWriter())){
response.sendRedirect("detail.jsp?boardNo=" + no + "&error=deny");
return;
}
board.setDeleted("Y");
boardDao.updateBoard(board);
response.sendRedirect("list.jsp");
%>
- detail.jsp (상세정보) 요청
* 로그인한 정보가 작성자 정보와 다르면 -> 수정, 삭제 불가
<%@page import="com.sample.vo.User"%>
<%@page import="com.sample.dao.ReviewDao"%>
<%@page import="com.sample.vo.Review"%>
<%@page import="java.util.List"%>
<%@page import="com.sample.util.StringUtils"%>
<%@page import="com.sample.vo.Board"%>
<%@page import="com.sample.dao.BoardDao"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.9.1/font/bootstrap-icons.css">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/js/bootstrap.bundle.min.js"></script>
<title>익명 게시판</title>
<style>
textarea {
resize: none;
}
</style>
</head>
<body>
<jsp:include page="../common/header.jsp">
<jsp:param name="menu" value="board"/>
</jsp:include>
<div class="container my-3">
<h1 class="mb-3 fs-4 border p-2 bg-light">게시글 상세정보</h1>
<p>
게시글 상세정보를 확인하세요
<button type="button" class="btn btn-outline-dark btn-sm float-end" data-bs-toggle="modal" data-bs-target="#review-modal">리뷰쓰기</button>
</p>
<%
String errorCode = request.getParameter("error");
if("deny".equals(errorCode)){
%>
<div class="alert alert-danger">
<strong>수정/삭제 불가</strong> 다른 사용자가 작성한 게시글은 수정/삭제할 수 없습니다.
</div>
<%
}
%>
<%
// 인증된 사용자 정보를 조회한다.
User user = (User) session.getAttribute("loginedUser");
int no = StringUtils.stringToInt(request.getParameter("boardNo"));
BoardDao boardDao = new BoardDao();
Board board = boardDao.getBoardByNo(no);
board.setReadCount(board.getReadCount() + 1);
boardDao.updateBoard(board);
%>
<table class="table table-bordered">
<tbody>
<tr>
<th>번호</th><td><%=board.getNo() %></td>
<th>등록일</th><td><%=StringUtils.dateToText(board.getCreatedDate()) %></td>
</tr>
<tr>
<th>제목</th><td><%=board.getTitle() %></td>
<th>작성자</th><td><%=board.getWriter() %></td>
</tr>
<tr>
<th>조회수</th><td><%=board.getReadCount() %></td>
<th>리뷰갯수</th><td><%=board.getReviewCount() %></td>
</tr>
<tr>
<th>내용</th>
<td colspan="3"><textarea rows="6" class="form-control border-0" readonly="readonly"><%=board.getContent() %></textarea> </td>
</tr>
</tbody>
</table>
<div class="mb-3">
<%
// 인증된(로그인된) 사용자 정보가 존재하고, 인증된 사용자의 아이디와 게시물 작성자가 동일할 때만 삭제, 수정 가능
if(user != null && user.getId().equals(board.getWriter())) {
%>
<a href="delete.jsp?no=<%=board.getNo() %>" class="btn btn-danger">삭제</a>
<a href="modifyform.jsp?no=<%=board.getNo() %>" class="btn btn-warning">수정</a>
<%
}
%>
<a href="list.jsp" class="btn btn-outline-primary float-end">목록</a>
</div>
<!--
게시글 리뷰 리스트 시작
-->
<%
ReviewDao reviewDao = new ReviewDao();
List<Review> reviewList = reviewDao.getReviewsByBoardNo(board.getNo());
%>
<ul class="list-group">
<%
if(reviewList.isEmpty()){
%>
<li class="list-group-item">
<div class="row">
<div class="col-12" class="text-center">리뷰가 존재하지 않습니다. </div>
</div>
</li>
<%
} else {
for(Review review : reviewList){
%>
<li class="list-group-item">
<div class="row">
<div class="col-12">
<span class="fw-bold"><%=review.getWriter() %></span> <small class="float-end"><%=StringUtils.dateToText(review.getCreatedDate()) %> </small>
</div>
<div class="col-10"><%=review.getContent() %> </div>
<div class="col-2 text-end">
<a href="deleteReview.jsp?no=<%=review.getBoardNo() %>&rno=<%=review.getNo() %>" class="text-danger">
<i class="bi bi-trash"></i>
</a>
</div>
</div>
</li>
<%
}
}
%>
</ul>
</div>
<!--
게시글 리뷰 리스트 끝
-->
<!--
리뷰 등록폼이 포함된 모달창 시작
-->
<div class="modal fade" id="review-modal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog">
<form method="post" action="addReview.jsp">
<!--
이 리뷰가 몇번 게시글의 리뷰인지를 저장하기 위해서 hidden 필드에 이 게시글의 번호를 지정한다.
이 입력폼을 서버로 제출하면 게시글번호(boardNo), 작성자(writer), 내용(content)이 전달된다.
-->
<input type="hidden" name="boardNo" value="<%=board.getNo()%>">
<div class="modal-content">
<div class="modal-header py-2">
<h1 class="modal-title fs-6" id="exampleModalLabel">리뷰 작성폼</h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body py-1">
<!--
작성자, 내용 입력요소를 확인하세요.
-->
<div class="mb-3">
<label class="form-label">작성자</label>
<input type="text" class="form-control form-control-sm" name="writer" />
</div>
<div class="mb-3">
<label class="form-label">내용</label>
<textarea class="form-control" rows="3" name="content"></textarea>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary btn-sm" data-bs-dismiss="modal">닫기</button>
<button type="submit" class="btn btn-primary btn-sm">리뷰등록</button>
</div>
</div>
</form>
</div>
</div>
<!--
리뷰 등록폼이 포함된 모달창 끝
-->
</div>
</body>
</html>
'수업내용 > Web' 카테고리의 다른 글
[2022.11.17.목] 장바구니 추가기능, 비밀번호 암호화 (0) | 2022.11.17 |
---|---|
[2022.11.16.수] 국내도서, 장바구니 (0) | 2022.11.16 |
[2022.11.14.월] HTTP의 쿠키 (0) | 2022.11.14 |
[2022.11.11.금] 게시판 구현 (0) | 2022.11.13 |
[2022.11.10.목] 도서 수정, 삭제, 페이징 처리하기 (0) | 2022.11.10 |