구현
회원 가입
회원 가입을 처리하는 signUp_proc.jsp 파일을 아래와 같이 완성한다.
/bbs/signUp_proc.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ page import="net.java_school.user.*" %> <% /* 회원 가입을 처리하는 페이지로 모델 2에서는 삭제해야 할 페이지다. -구현- 자동으로 로그인하지 않는다. 회원 가입이 완료되면 환영페이지로 이동한다. */ request.setCharacterEncoding("UTF-8"); String email = request.getParameter("email"); String passwd = request.getParameter("passwd"); String name = request.getParameter("name"); String mobile = request.getParameter("mobile"); //email,passwd,name,mobile 순으로 User user = new User(email, passwd, name, mobile); UserService service = new UserService(); service.addUser(user); response.sendRedirect("welcome.jsp"); %>
http://localhost:8080/users/signUp.jsp를 방문하여 테스트한다.
환영 페이지를 보았다면 SQL*PLUS로 접속하여 member 테이블에 데이터가 삽입되었는지 확인한다.
환영 페이지를 보지 못했다면 WEB-INF/debug.log 파일에서 로그 메시지를 확인한다.
리눅스 시스템인 경우 chmod o+w debug.log와 같은 권한 설정이 필요하다.
로그 메시지는 CATALINA_HOME/logs 디렉터리에 있는 파일에도 쌓이니 참고한다.
테스트가 성공했다면 signUp.jsp 의 텍스트 필드에서 value 속성을 제거한다.
참고로, 프로젝트를 간단하게 하도록 회원을 관리하는 관리자 페이지는 만들지 않는다.
로그인 처리
로그인 처리 페이지인 login_proc.jsp를 완성한다.
/users/login_proc.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ page import="net.java_school.user.User" %> <%@ page import="net.java_school.user.UserService" %> <% request.setCharacterEncoding("UTF-8"); String url = request.getParameter("url"); String email = request.getParameter("email"); String passwd = request.getParameter("passwd"); UserService service = new UserService(); User user = service.login(email, passwd); if (user == null) { //로그인이 실패하면 다시 로그인 화면으로 되돌아간다. response.sendRedirect("login.jsp?url=" + url + "&msg=Login-Failed"); } else { session.setAttribute("user", user); if (url != null && !url.equals("")) { response.sendRedirect(url); } else { response.sendRedirect("../bbs/list.jsp?boardCd=chat&curPage=1"); } } %>
로그인 페이지 login.jsp는 이제 msg라는 파라미터가 전달되는지 확인해야 한다.
다음 코드 조각을 로그인 페이지에 추가한다.
login.jsp
<!-- 본문 시작 --> <h2>로그인</h2> <% String msg = request.getParameter("msg"); if (msg != null) { %> <p style="color: red;">로그인에 실패했습니다.</p> <% } %>
프로젝트에서 사용하는 문자열을 전담하는 클래스를 만든다.
WebContants.java
package net.java_school.commons; public class WebContants { //Session key public final static String USER_KEY = "user"; }
"user"는 세션에 담을 User 객체의 킷값이다.
login_proc.jsp를 열고 "user"를 WebContants.USER_KEY로 수정한다.
내 정보 수정 처리
먼저 로그인하지 않음을 나타내는 다음 문자열을 WebContants.java에 추가한다.
public final static String NOT_LOGIN = "Not Login";
/users/editAccount_proc.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ page import="net.java_school.user.User" %> <%@ page import="net.java_school.user.UserService" %> <%@ page import="net.java_school.commons.WebContants" %> <% /* 회원정보를 수정하는 페이지로 모델 2에서는 삭제해야 할 페이지다. -구현- 로그인되어 있지 않으면 response.sendError(HttpServletResponse.SC_FORBIDDEN, "Not Login"); return; 회원정보를 수정한 후 다시 로그인하고 비밀번호 변경화면으로 이동한다. 비밀번호 변경 화면에서는 비밀번호 외에 회원정보를 모두 볼 수 있기 때문이다. */ User user = (User) session.getAttribute(WebContants.USER_KEY); if (user == null) { response.sendError(HttpServletResponse.SC_FORBIDDEN, WebContants.NOT_LOGIN); return; } request.setCharacterEncoding("UTF-8"); //전달되는 파라미터 name, mobile, passwd String name = request.getParameter("name"); String mobile = request.getParameter("mobile"); String passwd = request.getParameter("passwd"); String email = user.getEmail(); UserService service = new UserService(); user = service.login(email, passwd); if (user == null) { response.sendError(HttpServletResponse.SC_FORBIDDEN, WebContants.AUTHENTICATION_FAILED); session.removeAttribute(WebContants.USER_KEY);//비밀번호가 틀리면 세션을 끊는다. return; } user = new User(email, passwd, name, mobile); service.editAccount(user); session.setAttribute(WebContants.USER_KEY, user); response.sendRedirect("changePasswd.jsp"); %>
비밀번호 변경 처리
/users/changePasswd_proc.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ page import="net.java_school.user.User" %> <%@ page import="net.java_school.user.UserService" %> <%@ page import="net.java_school.commons.WebContants" %> <% /* 비밀번호를 수정하는 페이지로 모델 2에서는 삭제해야 할 페이지다. -구현- 로그인이 되어 있지 않으면 response.sendError(HttpServletResponse.SC_FORBIDDEN, "Not Login"); return; 비밀번호 변경 후 비밀번호 변경 확인 페이지로 이동한다. */ User user = (User) session.getAttribute(WebContants.USER_KEY); if (user == null) { response.sendError(HttpServletResponse.SC_FORBIDDEN, WebContants.NOT_LOGIN); return; } //전달되는 파라미터 currentPasswd(현재 비밀번호),newPasswd(변경할 비밀번호) String currentPasswd = request.getParameter("currentPasswd"); String newPasswd = request.getParameter("newPasswd"); String email = user.getEmail(); UserService service = new UserService(); int check = service.changePasswd(currentPasswd, newPasswd, email); if (check < 1) { response.sendError(HttpServletResponse.SC_FORBIDDEN, WebContants.AUTHENTICATION_FAILED); return; } response.sendRedirect("changePasswd_confirm.jsp"); %>
탈퇴 처리
WebContants.java에 다음 문자열 클래스 상수를 추가한다.
public final static String AUTHENTICATION_FAILED = "Authentication Failed";
/users/bye_proc.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ page import="net.java_school.user.User" %> <%@ page import="net.java_school.user.UserService" %> <%@ page import="net.java_school.commons.WebContants" %> <% /* 회원 탈퇴를 처리하는 페이지로 모델 2에서는 삭제해야 한다. -구현- 로그인 사용자가 아니면 response.sendError(HttpServletResponse.SC_FORBIDDEN, "Not Login"); return; 회원 테이블에서 회원정보를 지운다. 세션을 지운다. 탈퇴 확인 페이지로 이동한다. */ User user = (User) session.getAttribute(WebContants.USER_KEY); if (user == null) { response.sendError(HttpServletResponse.SC_FORBIDDEN, WebContants.NOT_LOGIN); return; } //전달되는 파라미터 email,passwd String email = request.getParameter("email"); String passwd = request.getParameter("passwd"); //email과 passwd가 맞으면 회원 테이블에서 회원 정보 삭제하고 세션 제거 UserService service = new UserService(); User check = service.login(email, passwd); if (check == null) { response.sendError(HttpServletResponse.SC_FORBIDDEN, WebContants.AUTHENTICATION_FAILED); return; } //회원 테이블에서 회원 정보 삭제 service.bye(user.getEmail(), passwd); //세션 제거 session.removeAttribute(WebContants.USER_KEY); //탈퇴 확인 페이지로 이동 response.sendRedirect("bye_confirm.jsp"); %>
목록
목록 /bbs/list.jsp를 구현한다. 내용이 많으니 나누어 진행하겠다. 전달된 파라미터를 받아서 목록에서 보일 데이터를 만든다.
/bbs/list.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ page import="net.java_school.board.*" %> <%@ page import="net.java_school.commons.NumbersForPaging" %> <%@ page import="java.util.ArrayList" %> <%@ include file="../inc/loginCheck.jsp" %> <% request.setCharacterEncoding("UTF-8"); String boardCd = request.getParameter("boardCd"); int curPage = Integer.parseInt(request.getParameter("curPage")); String searchWord = request.getParameter("searchWord"); if (searchWord == null) searchWord = ""; BoardService service = new BoardService(); //PaginHelper 생성 //1. 총 레코드 계산 int totalRecord = service.getTotalRecord(boardCd, searchWord); //2. numPerPage, pagePerBlock 설정 int numPerPage = 10; int pagePerBlock = 10; int startRecord = (curPage - 1) * numPerPage; int endRecord = curPage * numPerPage; //3. 목록 구하기 List<Article> articleList = service.getArticleList(boardCd, searchWord, startRecord, endRecord); //4. 게시판 이름 구하기 String boardName = service.getBoardName(boardCd); //5. 페이징 처리를 위한 숫자 구하기 NumbersForPaing numbers = service.getNumbersForPaging(totalRecord, curPage, numPerPage, pagePerBlock); %>
게시판 이름을 출력하는 코드를 삽입한다.
<!-- 본문 시작 --> <h1><%=boardName %></h1>
검색 폼에서 다음 강조된 부분을 수정한다.
<form action="list.jsp" method="get"> <input type="hidden" name="curPage" value="1" /> <input type="hidden" name="boardCd" value="<%=boardCd %>" /> <div> <input type="text" name="searchWord" size="15" maxlength="30" /> <input type="submit" value="검색" /> </div> </form>
하단의 #form-group에서 input 엘리먼트 속성값을 아래와 같이 수정한다.
<div id="form-group" style="display: none"> <form id="listForm" action="list.jsp" method="get"> <p> <input type="hidden" name="boardCd" value="<%=boardCd %>" /> <input type="hidden" name="curPage" /> <input type="hidden" name="searchWord" value="<%=searchWord %>" /> </p> </form> <form id="viewForm" action="view.jsp" method="get"> <p> <input type="hidden" name="articleNo" /> <input type="hidden" name="boardCd" value="<%=boardCd %>" /> <input type="hidden" name="curPage" value="<%=curPage %>" /> <input type="hidden" name="searchWord" value="<%=searchWord %>" /> </p> </form> <form id="writeForm" action="write_form.jsp" method="get"> <p> <input type="hidden" name="boardCd" value="<%=boardCd %>" /> <input type="hidden" name="curPage" value="<%=curPage %>" /> <input type="hidden" name="searchWord" value="<%=searchWord %>" /> </p> </form> </div>
페이징 처리 로직을 구현한다.
<!-- 반복 구간 시작 --> <% int listItemNo = numbers.getListItemNo(); int size = articleList.size(); for (int i = 0; i < size; i++) { Article article = articleList.get(i); int articleNo = article.getArticleNo(); String title = article.getTitle(); java.util.Date regdate = article.getRegdate(); int attachFileNum = article.getAttachFileNum(); int commentNum = article.getCommentNum(); int hit = article.getHit(); %> <tr> <td style="text-align: center;"><%=listItemNo %></td> <td> <a href="javascript:goView('<%=articleNo %>')"><%=title %></a> <% if (attachFileNum > 0) { %><img src="images/attach.png" alt="첨부 파일" style="vertical-align: middle;" /><% } %> <% if (commentNum > 0) { %><span class="bbs-strong">[<%=commentNum %>]</span><% } %> </td> <td style="text-align: center;"><%=regdate %></td> <td style="text-align: center;"><%=hit %></td> </tr> <% listItemNo--; } // for 문의 끝 %> <!-- 반복 구간 끝 --> </table> <div id="paging"> <% if (numbers.getPrevPage() != 0) { %> <a href="javascript:goList('<%=numbers.getPrevPage() %>')">[이전]</a> <% } // if 문 끝 int firstPage = numbers.getFirstPage(); int lastPage = numbers.getLastPage(); for (int i = firstPage; i <= lastPage; i++) { if (curPage == i) { %> <span class="bbs-strong"><%=i %></span> <% } else { %> <a href="javascript:goList('<%=i %>')"><%=i %></a> <% } }// for문 끝 // [다음]링크 구현 if (numbers.getNextPage() != 0) { %> <a href="javascript:goList('<%=numbers.getNextPage() %>')">[다음]</a> <% }// if문 끝 %> </div>
글쓰기 폼
/bbs/write_form.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %> <%@ page import="net.java_school.board.*" %> <%@ page import="java.util.*" %> <%@ include file="../inc/loginCheck.jsp" %> <% request.setCharacterEncoding("UTF-8"); String articleNo = request.getParameter("articleNo"); String boardCd = request.getParameter("boardCd"); String curPage = request.getParameter("curPage"); String searchWord = request.getParameter("searchWord"); BoardService service = new BoardService(); String boardName = service.getBoardName(boardCd); %> <!DOCTYPE html> <html lang="ko"> <head> <meta charset="UTF-8" /> <meta name="Keywords" content="글쓰기 화면" /> <meta name="Description" content="글쓰기 화면" /> <title><%=boardName %></title> <link rel="stylesheet" href="/css/screen.css" type="text/css" /> <script type="text/javascript"> function goList() { var form = document.getElementById("listForm"); form.submit(); } function goView() { var form = document.getElementById("viewForm"); form.submit(); } </script> </head> <body> <div id="wrap"> <div id="header"> <%@ include file="../inc/header.jsp" %> </div> <div id="main-menu"> <%@ include file="../inc/main-menu.jsp" %> </div> <div id="container"> <div id="content"> <!-- 본문 시작 --> <div id="content-categories"><%=boardName %></div> <h3>새 글쓰기</h3> <form id="writeForm" action="write_proc.jsp" method="post" enctype="multipart/form-data"> <input type="hidden" name="boardCd" value="<%=boardCd %>" /> <table id="write-form" class="bbs-table"> <tr> <td>제목</td> <td><input type="text" name="title" style="width: 90%;" /></td> </tr> <tr> <td colspan="2"> <textarea name="content" rows="17" cols="50"></textarea> </td> </tr> <tr> <td>첨부 파일</td> <td><input type="file" name="attachFile" /></td> </tr> </table> <div style="text-align: center;padding-bottom: 15px;"> <input type="submit" value="전송" /> <input type="button" value="목록" onclick="goList()" /> <% if (articleNo != null) { %> <input type="button" value="상세보기" onclick="goView()" /> <% } //if문 끝 %> </div> </form> <!-- 본문 끝 --> </div> </div> <div id="sidebar"> <%@ include file="bbs-sub.jsp" %> </div> <div id="extra"> <%@ include file="../inc/extra.jsp" %> </div> <div id="footer"> <%@ include file="../inc/footer.jsp" %> </div> </div> <div id="form-group" style="display: none"> <form id="viewForm" action="view.jsp" method="get"> <input type="hidden" name="articleNo" value="<%=articleNo %>" /> <input type="hidden" name="boardCd" value="<%=boardCd %>" /> <input type="hidden" name="curPage" value="<%=curPage %>" /> <input type="hidden" name="searchWord" value="<%=searchWord %>" /> </form> <form id="listForm" action="list.jsp" method="get"> <input type="hidden" name="boardCd" value="<%=boardCd %>" /> <input type="hidden" name="curPage" value="<%=curPage %>" /> <input type="hidden" name="searchWord" value="<%=searchWord %>" /> </form> </div> </body> </html>
글쓰기 처리
글쓰기 처리 페이지 write_proc.jsp를 구현한다. 파일 업로드를 위한 라이브러리가 필요하다. http://www.servlets.com/cos/cos-26Dec2008.zip를 내려받고 압축을 푼다. 웹 애플리케이션의 WEB-INF/lib에 cos.jar를 복사한다. 도큐먼트 베이스 아래 upload라는 폴더를 만든다. 유닉스 계열 시스템이면 upload 폴더에 권한 설정이 필요하다.
/bbs/write_proc.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %> <%@ page import="java.io.*" %> <%@ page import="net.java_school.commons.WebContants" %> <%@ page import="net.java_school.user.User" %> <%@ page import="net.java_school.user.UserService" %> <%@ page import="net.java_school.board.*" %> <%@ page import="com.oreilly.servlet.MultipartRequest" %> <%@ page import="com.oreilly.servlet.multipart.DefaultFileRenamePolicy" %> <% /* 새 게시글을 등록하는 페이지로 모델 2에서는 삭제해야 할 페이지다. -구현- 로그인 사용자가 아니면 response.sendError(HttpServletResponse.SC_FORBIDDEN, "Not Login"); return; 로그인 체크를 통과하면 boardCd, title, content, attachFile 파라미터를 가지고 새로운 게시글을 인서트 한다. form이 enctype="multipart/form-data"인 경우 request.getParameter()로 파라미터의 값을 얻을 수 없다. 프로그래밍을 손쉽게 하도록 외부 라이브러리를 이용한다. (아파치 commons.fileupload 또는 cos) 새 글을 등록한 후 목록의 첫 번째 페이지로 돌아간다. */ User user = (User) session.getAttribute(WebContants.USER_KEY); if (user == null) { response.sendError(HttpServletResponse.SC_FORBIDDEN, WebContants.NOT_LOGIN); return; } String dir = application.getRealPath("/upload"); MultipartRequest multi = new MultipartRequest( request, dir, 5*1024*1024, "UTF-8", new DefaultFileRenamePolicy()); String title = multi.getParameter("title"); String content = multi.getParameter("content"); String filename = multi.getFilesystemName("attachFile"); String filetype = multi.getContentType("attachFile"); File f = multi.getFile("attachFile"); long filesize = 0L; AttachFile attachFile = null; if (f != null) { filesize = f.length(); attachFile = new AttachFile(); attachFile.setFilename(filename); attachFile.setFiletype(filetype); attachFile.setFilesize(filesize); attachFile.setEmail(user.getEmail()); } String boardCd = multi.getParameter("boardCd"); Article article = new Article(); article.setEmail(user.getEmail()); article.setTitle(title); article.setContent(content); article.setBoardCd(boardCd); BoardService service = new BoardService(); service.addArticle(article, attachFile); response.sendRedirect("list.jsp?boardCd=" + boardCd + "&curPage=1"); %>
상세보기
/bbs/view.jsp 파일을 아래를 참조하여 수정한다.
/bbs/view.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ page import="java.util.*" %> <%@ page import="net.java_school.user.*" %> <%@ page import="net.java_school.board.*" %> <%@ page import="net.java_school.commons.*" %> <%@ include file="../inc/loginCheck.jsp" %> <% request.setCharacterEncoding("UTF-8"); int articleNo = Integer.parseInt(request.getParameter("articleNo")); String boardCd = request.getParameter("boardCd"); int curPage = Integer.parseInt(request.getParameter("curPage")); String searchWord = request.getParameter("searchWord"); if (searchWord == null) searchWord = ""; BoardService service = new BoardService(); int totalRecord = service.getTotalRecord(boardCd, searchWord);//총 레코드 int numPerPage = 10; int pagePerBlock = 10; int startRecord = (curPage - 1) * numPerPage + 1; int endRecord = curPage * numPerPage; service.increaseHit(articleNo);//목록을 구하기 전에 조회 수를 1 증가시킨다. Article detailedArticle = service.getArticle(articleNo);//상세보기에서 볼 게시글 List<AttachFile> attachFileList = service.getAttachFileList(articleNo);//첨부 파일 목록 Article nextArticle = service.getNextArticle(articleNo, boardCd, searchWord);//다음 글 Article prevArticle = service.getPrevArticle(articleNo, boardCd, searchWord);//이전 클 List<Article> articleList = service.getArticleList(boardCd, searchWord, startRecord, endRecord);//게시글 목록 List<Comment> commentList = service.getCommentList(articleNo);//댓글 목록 String boardName = service.getBoardName(boardCd);//게시판 이름 String articleOwnerName = detailedArticle.getName();//게시글 작성자 이름 %> <!DOCTYPE html> <html lang="ko"> <head> <meta charset="UTF-8" /> <meta name="Keywords" content="게시판 상세보기" /> <meta name="Description" content="게시판 상세보기" /> <title><%=boardName %></title> <link rel="stylesheet" href="/css/screen.css" type="text/css" /> <script type="text/javascript"> function modifyCommentToggle(articleNo) { var p_id = "comment" + articleNo; var form_id = "modifyCommentForm" + no; var p = document.getElementById(p_id); var form = document.getElementById(form_id); var p_display; var form_display; if (p.style.display) { p_display = ''; form_display = 'none'; } else { p_display = 'none'; form_display = ''; } p.style.display = p_display; form.style.display = form_display; } function goList(curPage) { var form = document.getElementById("listForm"); form.curPage.value = curPage; form.submit(); } function goView(articleNo) { var form = document.getElementById("viewForm"); form.articleNo.value = articleNo; form.submit(); } function goWrite() { var form = document.getElementById("writeForm"); form.submit(); } function goModify() { var form = document.getElementById("modifyForm"); form.submit(); } function goDelete() { var check = confirm("정말로 삭제하시겠습니까?"); if (check) { var form = document.getElementById("delForm"); form.submit(); } } function deleteAttachFile(attachFileNo) { var check = confirm("첨부 파일을 정말로 삭제하시겠습니까?"); if (check) { var form = document.getElementById("deleteAttachFileForm"); form.attachFileNo.value = attachFileNo; form.submit(); } } function deleteComment(commentNo) { var check = confirm("댓글을 정말로 삭제하시겠습니까?"); if (check) { var form = document.getElementById("deleteCommentForm"); form.commentNo.value = commentNo; form.submit(); } } </script> </head> <body> <div id="wrap"> <div id="header"> <%@ include file="../inc/header.jsp" %> </div> <div id="main-menu"> <%@ include file="../inc/main-menu.jsp" %> </div> <div id="container"> <div id="content"> <!-- 본문 시작 --> <div id="content-categories"><%=boardName %></div> <div class="view-menu" style="margin-top: 15px;margin-bottom: 5px;"> <div class="fl"> <% if (user.getEmail().equals(detailedArticle.getEmail())) { %> <input type="button" value="수정" onclick="goModify();" /> <input type="button" value="삭제" onclick="goDelete()" /> <% } %> </div> <div class="fr"> <% if (nextArticle != null) { %> <input type="button" value="다음 글" onclick="goView('<%=nextArticle.getArticleNo() %>')" /> <% } if (prevArticle != null) { %> <input type="button" value="이전 글" onclick="goView('<%=prevArticle.getArticleNo() %>')" /> <% } %> <input type="button" value="목록" onclick="goList('<%=curPage %>')" /> <input type="button" value="새 글쓰기" onclick="goWrite()" /> </div> </div> <table class="bbs-table"> <tr> <th style="width: 47px;text-align: left;vertical-align: top;font-size: 1em;">TITLE</th> <th style="text-align: left;color: #555;font-size: 1em;"><%=detailedArticle.getTitle() %></th> </tr> </table> <div id="detail"> <div id="date-writer-hit">edited <%=detailedArticle.getRegdate() %> by <%=articleOwnerName %> hit <%=detailedArticle.getHit() %></div> <% String content = detailedArticle.getContent(); content = content.replaceAll(System.getProperty("line.separator"), "<br />"); %> <div id="article-content"><%=content %></div> <% int size = attachFileList.size(); if (size > 0) { %> <div id="file-list" style="text-align: right"> <% String path = request.getContextPath(); String uploadPath = path + "/upload/"; for (int i = 0; i < size; i++) { AttachFile attachFile = attachFileList.get(i); String filename = attachFile.getFilename(); int attachFileNo = attachFile.getAttachFileNo(); String fileFullPath = uploadPath + filename; %> <div id="attach-file"> <a href="<%=fileFullPath %>"><%=filename %></a> <% if (user.getEmail().equals(detailedArticle.getEmail())) { %> <a href="javascript:deleteAttachFile('<%=attachFileNo %>')">x</a> <% }//if문 끝 %> </div> <% }//for문 끝 %> </div> <% }//if문 끝 %> </div> <!-- 댓글 쓰기 --> <form id="addCommentForm" action="addComment.jsp" method="post"> <input type="hidden" name="articleNo" value="<%=articleNo %>" /> <input type="hidden" name="boardCd" value="<%=boardCd %>" /> <input type="hidden" name="curPage" value="<%=curPage %>" /> <input type="hidden" name="searchWord" value="<%=searchWord %>" /> <div id="addComment"> <textarea name="memo" rows="7" cols="50"></textarea> </div> <div style="text-align: right;"> <input type="submit" value="댓글 남기기" /> </div> </form> <% size = commentList.size(); for (int i = 0; i < size; i++ ) { Comment comment = commentList.get(i); int commentNo = comment.getCommentNo(); String email = comment.getEmail(); String memo = comment.getMemo(); String commentOwnerName = comment.getName(); Date regdate = comment.getRegdate(); %> <div class="comments"> <span class="writer"><%=commentOwnerName %></span> <span class="date"><%=regdate %></span> <% if (user.getEmail().equals(email)) { %> <span class="modify-del"> <a href="javascript:modifyCommentToggle('<%=commentNo %>')">수정</a> | <a href="javascript:deleteComment('<%=commentNo %>')">삭제</a> </span> <% }//if문 끝 %> <p id="comment<%=commentNo %>"><%=memo %></p> <form id="modifyCommentForm<%=commentNo %>" class="comment-form" action="updateComment_proc.jsp" method="post" style="display: none;"> <input type="hidden" name="commentNo" value="<%=commentNo %>" /> <input type="hidden" name="boardCd" value="<%=boardCd %>" /> <input type="hidden" name="articleNo" value="<%=articleNo %>" /> <input type="hidden" name="curPage" value="<%=curPage %>" /> <input type="hidden" name="searchWord" value="<%=searchWord %>" /> <div class="fr"> <a href="javascript:document.forms.modifyCommentForm<%=commentNo %>.submit()">수정하기</a> | <a href="javascript:goCommentModify('<%=commentNo %>')">취소</a> </div> <div> <textarea class="comment-textarea" name="memo" rows="7" cols="50"><%=memo %></textarea> </div> </form> </div> <% }//for문 끝 %> <!-- 댓글 반복 끝 --> <div id="next-prev"> <% if (nextArticle != null) { %> <p>다음 글 : <a href="javascript:goView('<%=nextArticle.getArticleNo() %>')"><%=nextArticle.getTitle() %></a></p> <% } if (prevArticle != null) { %> <p>이전 글 : <a href="javascript:goView('<%=prevArticle.getArticleNo() %>')"><%=prevArticle.getTitle() %></a></p> <% } %> </div> <div class="view-menu" style="margin-bottom: 47px;"> <div class="fl"> <% if (user.getEmail().equals(detailedArticle.getEmail())) { %> <input type="button" value="수정" onclick="goModify();" /> <input type="button" value="삭제" onclick="goDelete()" /> <% } %> </div> <div class="fr"> <% if (nextArticle != null) { %> <input type="button" value="다음 글" onclick="goView('<%=nextArticle.getArticleNo() %>')" /> <% } if (prevArticle != null) { %> <input type="button" value="이전 글" onclick="goView('<%=prevArticle.getArticleNo() %>')" /> <% } %> <input type="button" value="목록" onclick="goList('<%=curPage %>')" /> <input type="button" value="새 글쓰기" onclick="goWrite()" /> </div> </div> <!-- 목록 --> <table> <tr> <th style="width: 60px">NO</th> <th>TITLE</th> <th style="width: 84px;">DATE</th> <th style="width: 60px;">HIT</th> </tr> <% int listItemNo = service.getListItemNo(); size = articleList.size(); for (int i = 0; i < size; i++) { Article article = articleList.get(i); int aNo = article.getArticleNo(); String title = article.getTitle(); Date regdate = article.getRegdate(); int hit = article.getHit(); int attachFileNum = article.getAttachFileNum(); int commentNum = article.getCommentNum(); %> <tr> <td style="text-align: center;"> <% if (articleNo == aNo) { %> <img src="../images/arrow.gif" alt="현재 글" /> <% } else { %> <%=listItemNo %> <% } %> </td> <td> <a href="javascript:goView('<%=aNo %>')"><%=title %></a> <% if (attachFileNum > 0) { %> <img src="../images/attach.png" alt="첨부 파일" style="vertical-align: middle;" /> <% } if (commentNum > 0 ) { %> <span class="bbs-strong">[<%=commentNum %>]</span> <% } %> </td> <td style="text-align: center;"><%=regdate %></td> <td style="text-align: center;"><%=hit %></td> </tr> <% listItemNo--; }//for문 끝 %> </table> <div id="paging"> <% if (service.getPrevPage() != 0 ) { %> <a href="javascript:goList('<%=service.getPrevPage() %>')">[이전]</a> <% } int firstPage = service.getFirstPage(); int lastPage = service.getLastPage(); for (int i = firstPage; i <= lastPage; i++) { if (curPage == i) { %> <span class="bbs-strong"><%=i %></span> <% } else { %> <a href="javascript:goList('<%=i %>')"><%=i %></a> <% } }//for 문 끝 // [다음] 링크 구현 if (service.getNextPage() != 0) { %> <a href="javascript:goList('<%=service.getNextPage() %>')">[다음]</a> <% } %> </div> <div id="list-menu"> <input type="button" value="새 글쓰기" onclick="goWrite()" /> </div> <div id="search"> <form action="list.jsp" method="get"> <input type="hidden" name="curPage" value="1" /> <input type="hidden" name="boardCd" value="<%=boardCd %>" /> <div> <input type="text" name="searchWord" size="15" maxlength="30" /> <input type="submit" value="검색" /> </div> </form> </div> <!-- 본문 끝 --> </div><!-- content 끝 --> </div><!-- container 끝 --> <div id="sidebar"> <%@ include file="bbs-sub.jsp" %> </div> <div id="extra"> <%@ include file="../inc/extra.jsp" %> </div> <div id="footer"> <%@ include file="../inc/footer.jsp" %> </div> </div> <div id="form-group" style="display: none"> <form id="listForm" action="list.jsp" method="get"> <input type="hidden" name="boardCd" value="<%=boardCd %>" /> <input type="hidden" name="curPage" /> <input type="hidden" name="searchWord" value="<%=searchWord %>" /> </form> <form id="viewForm" action="view.jsp" method="get"> <input type="hidden" name="articleNo" /> <input type="hidden" name="boardCd" value="<%=boardCd %>" /> <input type="hidden" name="curPage" value="<%=curPage %>" /> <input type="hidden" name="searchWord" value="<%=searchWord %>" /> </form> <form id="writeForm" action="write_form.jsp" method="get"> <input type="hidden" name="articleNo" value="<%=articleNo %>" /> <input type="hidden" name="boardCd" value="<%=boardCd %>" /> <input type="hidden" name="curPage" value="<%=curPage %>" /> <input type="hidden" name="searchWord" value="<%=searchWord %>" /> </form> <form id="modifyForm" action="modify_form.jsp" method="get"> <input type="hidden" name="articleNo" value="<%=articleNo %>" /> <input type="hidden" name="boardCd" value="<%=boardCd %>" /> <input type="hidden" name="curPage" value="<%=curPage %>" /> <input type="hidden" name="searchWord" value="<%=searchWord %>" /> </form> <form id="delForm" action="del_proc.jsp" method="post"> <input type="hidden" name="articleNo" value="<%=articleNo %>" /> <input type="hidden" name="boardCd" value="<%=boardCd %>" /> <input type="hidden" name="curPage" value="<%=curPage %>" /> <input type="hidden" name="searchWord" value="<%=searchWord %>" /> </form> <form id="deleteCommentForm" action="deleteComment_proc.jsp" method="post"> <input type="hidden" name="commentNo" /> <input type="hidden" name="articleNo" value="<%=articleNo %>" /> <input type="hidden" name="boardCd" value="<%=boardCd %>" /> <input type="hidden" name="curPage" value="<%=curPage %>" /> <input type="hidden" name="searchWord" value="<%=searchWord %>" /> </form> <form id="deleteAttachFileForm" action="deleteAttachFile.jsp" method="post"> <input type="hidden" name="attachFileNo" /> <input type="hidden" name="articleNo" value="<%=articleNo %>" /> <input type="hidden" name="boardCd" value="<%=boardCd %>" /> <input type="hidden" name="curPage" value="<%=curPage %>" /> <input type="hidden" name="searchWord" value="<%=searchWord %>" /> </form> </div> </body> </html>
댓글 쓰기 처리
/bbs/addComment_proc.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ page import="net.java_school.commons.WebContants" %> <%@ page import="net.java_school.user.User" %> <%@ page import="net.java_school.board.*" %> <% /* 새로운 댓글을 인서트 하는 페이지로 모델 2에서는 삭제한다. -구현- 로그인 사용자가 아니면 response.sendError(HttpServletResponse.SC_FORBIDDEN, "Not Login"); return; 로그인 체크를 통과하면 먼저 요청의 캐릭터 셋을 UTF-8으로 설정한다. boardCd, articleNo, curPage, searchWord, memo 파라미터를 받아서 댓글을 인서트 한다. 댓글을 인서트 한 후 상세보기로 돌아가기 위해 검색어 searchWord를 URLEncoder의 encode() 메소드로 UTF-8으로 인코딩한다. */ User user = (User) session.getAttribute(WebContants.USER_KEY); if (user == null) { response.sendError(HttpServletResponse.SC_FORBIDDEN, WebContants.NOT_LOGIN); return; } request.setCharacterEncoding("UTF-8"); String boardCd = request.getParameter("boardCd"); int articleNo = Integer.parseInt(request.getParameter("articleNo")); int curPage = Integer.parseInt(request.getParameter("curPage")); String searchWord = request.getParameter("searchWord"); String memo = request.getParameter("memo"); Comment comment = new Comment(); comment.setArticleNo(articleNo); comment.setEmail(user.getEmail()); comment.setMemo(memo); BoardService service = new BoardService(); service.addComment(comment); searchWord = java.net.URLEncoder.encode(searchWord, "UTF-8"); response.sendRedirect("view.jsp?articleNo=" + articleNo + "&boardCd=" + boardCd + "&curPage=" + curPage + "&searchWord=" + searchWord); %>
댓글 수정 처리
/bbs/updateComment_proc.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ page import="net.java_school.commons.WebContants" %> <%@ page import="net.java_school.user.User" %> <%@ page import="net.java_school.board.*" %> <% /* 댓글 업데이트를 실행하는 페이지로 모델 2에서는 삭제한다. -구현- 작성자인지 검사하고 작성자가 아니면 response.sendError(HttpServletResponse.SC_FORBIDDEN, "Authentication Failed"); return; 작성자 체크를 통과하면 요청의 캐릭터 셋을 UTF-8으로 설정한다. commentNo, boardCd, articleNo, curPage, searchWord, memo 파라미터를 받아서 댓글을 업데이트한다. 댓글을 업데이트한 후 상세보기로 돌아가기 위해 검색어 searchWord를 URLEncoder의 encode() 메소드로 UTF-8으로 인코딩한다. */ User user = (User) session.getAttribute(WebContants.USER_KEY); request.setCharacterEncoding("UTF-8"); int commentNo = Integer.parseInt(request.getParameter("commentNo")); //로그인 사용자가 댓글의 소유자인지 검사 BoardService service = new BoardService(); Comment comment = service.getComment(commentNo); if (user == null || !user.getEmail().equals(comment.getEmail())) { response.sendError(HttpServletResponse.SC_FORBIDDEN, WebContants.AUTHENTICATION_FAILED); return; } String boardCd = request.getParameter("boardCd"); int articleNo = Integer.parseInt(request.getParameter("articleNo")); int curPage = Integer.parseInt(request.getParameter("curPage")); String searchWord = request.getParameter("searchWord"); String memo = request.getParameter("memo"); //생성된 Comment 객체를 재사용한다. comment.setCommentNo(commentNo); comment.setArticleNo(articleNo); comment.setEmail(user.getEmail()); comment.setMemo(memo); service.modifyComment(comment); searchWord = java.net.URLEncoder.encode(searchWord,"UTF-8"); response.sendRedirect("view.jsp?articleNo=" + articleNo + "&boardCd=" + boardCd + "&curPage=" + curPage + "&searchWord=" + searchWord); %>
댓글 삭제 처리
/bbs/deleteComment_proc.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ page import="net.java_school.commons.WebContants" %> <%@ page import="net.java_school.user.User" %> <%@ page import="net.java_school.board.*" %> <% /* 댓글 삭제를 실행하는 페이지로 모델 2에서는 삭제한다. -구현- 작성자인지를 검사하고 작성자가 아니면 response.sendError(HttpServletResponse.SC_FORBIDDEN, "작성자가 아닙니다."); return; 요청의 캐릭터 셋을 UTF-8으로 설정해야 한다. 요청에서 참조해야 하는 파라미터는 commentNo, boardCd, articleNo, curPage, searchWord 이다. 댓글을 삭제 후 상세보기를 돌아가기 위해선 searchWord를 URLEncoder의 encode() 메소드로 UTF-8으로 인코딩한다. */ User user = (User) session.getAttribute(WebContants.USER_KEY); request.setCharacterEncoding("UTF-8"); int commentNo = Integer.parseInt(request.getParameter("commentNo")); //로그인 사용자가 댓글의 소유자인지를 검사 BoardService service = new BoardService(); Comment comment = service.getComment(commentNo); if (user == null || !user.getEmail().equals(comment.getEmail())) { response.sendError(HttpServletResponse.SC_FORBIDDEN, WebContants.AUTHENTICATION_FAILED); return; } String boardCd = request.getParameter("boardCd"); int articleNo = Integer.parseInt(request.getParameter("articleNo")); int curPage = Integer.parseInt(request.getParameter("curPage")); String searchWord = request.getParameter("searchWord"); service.removeComment(commentNo); searchWord = java.net.URLEncoder.encode(searchWord, "UTF-8"); response.sendRedirect("view.jsp?articleNo=" + articleNo + "&boardCd=" + boardCd + "&curPage=" + curPage + "&searchWord=" + searchWord); %>
첨부 파일 삭제 처리
/bbs/deleteAttachFile_proc.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ page import="net.java_school.user.User" %> <%@ page import="net.java_school.board.*" %> <%@ page import="net.java_school.commons.WebContants" %> <% /* 첨부 파일 삭제를 실행하는 페이지로 모델 2에서는 삭제한다. -구현- 작성자인지를 검사하고 작성자가 아니면 response.sendError(HttpServletResponse.SC_FORBIDDEN, "작성자가 아닙니다."); return; 요청의 캐릭터 셋을 UTF-8으로 설정해야 한다. 요청에서 참조해야 하는 파라미터는 attachFileNo, articleNo, boardCd, curPage, searchWord이다. 첨부 파일을 삭제 후 상세보기를 돌아가기 위해 searchWord를 URLEncoder의 encode() 메소드로 UTF-8으로 인코딩한다. */ User user = (User) session.getAttribute(WebContants.USER_KEY); request.setCharacterEncoding("UTF-8"); int attachFileNo = Integer.parseInt(request.getParameter("attachFileNo")); //로그인 사용자가 첨부 파일 소유자인지를 검사 BoardService service = new BoardService(); AttachFile attachFile = service.getAttachFile(attachFileNo); if (user == null || !user.getEmail().equals(attachFile.getEmail())) { response.sendError(HttpServletResponse.SC_FORBIDDEN, WebContants.AUTHENTICATION_FAILED); return; } String boardCd = request.getParameter("boardCd"); int articleNo = Integer.parseInt(request.getParameter("articleNo")); int curPage = Integer.parseInt(request.getParameter("curPage")); String searchWord = request.getParameter("searchWord"); service.removeAttachFile(attachFileNo); searchWord = java.net.URLEncoder.encode(searchWord, "UTF-8"); response.sendRedirect("view.jsp?articleNo=" + articleNo + "&boardCd=" + boardCd + "&curPage=" + curPage + "&searchWord=" + searchWord); %>
글 수정 폼
/bbs/modify_form.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %> <%@ page import="net.java_school.commons.WebContants" %> <%@ page import="net.java_school.board.*" %> <%@ page import="java.util.*" %> <% request.setCharacterEncoding("UTF-8"); int articleNo = Integer.parseInt(request.getParameter("articleNo")); String boardCd = request.getParameter("boardCd"); int curPage = Integer.parseInt(request.getParameter("curPage")); String searchWord = request.getParameter("searchWord"); //articleNo로 게시글 객체를 얻어서 현재 로그인된 사용자가 소유자인지 검사 User user = (User) session.getAttribute("user"); BoardService service = new BoardService(); Article article = service.getArticle(articleNo); //글 소유자와 로그인 사용자가 다르면 에러 페이지로 보낸다. if (user == null || !user.getEmail().equals(article.getEmail())) { response.sendError(HttpServletResponse.SC_FORBIDDEN, WebContants.AUTHENTICATION_FAILED); return; } //수정 폼의 초깃값 String title = article.getTitle(); String content = article.getContent(); if (content == null) content = ""; //게시판 이름 String boardName = service.getBoardName(boardCd); %> <!DOCTYPE html> <html lang="ko"> <head> <meta charset="UTF-8" /> <meta name="Keywords" content="게시판 수정하기 폼" /> <meta name="Description" content="게시판 수정하기 폼" /> <title><%=boardName %></title> <link rel="stylesheet" href="/css/screen.css" type="text/css" /> <script type="text/javascript"> function goView() { var form = document.getElementById("viewForm"); form.submit(); } </script> </head> <body> <div id="wrap"> <div id="header"> <%@ include file="../inc/header.jsp" %> </div> <div id="main-menu"> <%@ include file="../inc/main-menu.jsp" %> </div> <div id="container"> <div id="content"> <!-- 본문 시작 --> <div id="content-categories"><%=boardName %></div> <h3>수정</h3> <form id="modifyForm" action="modify_proc.jsp" method="post" enctype="multipart/form-data"> <input type="hidden" name="articleNo" value="<%=articleNo %>" /> <input type="hidden" name="boardCd" value="<%=boardCd %>" /> <input type="hidden" name="curPage" value="<%=curPage %>" /> <input type="hidden" name="searchWord" value="<%=searchWord %>" /> <table id="write-form" class="bbs-table"> <tr> <td>제목</td> <td><input type="text" name="title" style="width: 90%;" value="<%=title %>" /></td> </tr> <tr> <td colspan="2"> <textarea name="content" rows="17" cols="50"><%=content %></textarea> </td> </tr> <tr> <td>첨부 파일</td> <td><input type="file" name="attachFile" /></td> </tr> </table> <div style="text-align: center;padding-bottom: 15px;"> <input type="submit" value="전송" /> <input type="button" value="상세보기" onclick="goView()" /> </div> </form> <!-- 본문 끝 --> </div><!-- content 끝 --> </div><!-- container 끝 --> <div id="sidebar"> <%@ include file="bbs-sub.jsp" %> </div> <div id="extra"> <%@ include file="../inc/extra.jsp" %> </div> <div id="footer"> <%@ include file="../inc/footer.jsp" %> </div> </div> <div id="form-group" style="display: none;"> <form id="viewForm" action="view.jsp" method="get"> <input type="hidden" name="articleNo" value="<%=articleNo %>" /> <input type="hidden" name="boardCd" value="<%=boardCd %>" /> <input type="hidden" name="curPage" value="<%=curPage %>" /> <input type="hidden" name="searchWord" value="<%=searchWord %>" /> </form> </div> </body> </html>
글 수정 처리
/bbs/modify_proc.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ page import="java.io.*" %> <%@ page import="net.java_school.commons.WebContants" %> <%@ page import="net.java_school.user.User" %> <%@ page import="net.java_school.user.UserService" %> <%@ page import="net.java_school.board.*" %> <%@ page import="com.oreilly.servlet.MultipartRequest" %> <%@ page import="com.oreilly.servlet.multipart.DefaultFileRenamePolicy" %> <% /* 게시글을 수정하는 페이지로 모델 2에서는 삭제해야 할 페이지다. -구현- 작성자인지 검사하고 작성자가 아니면 response.sendError(HttpServletResponse.SC_FORBIDDEN, "Authentication Failed"); return; articleNo, boardCd, curPage, searchWord, title, content, attachFile 파라미터를 받고 게시글을 수정한다. form이 enctype="multipart/form-data"인 경우 request.getParameter()로 파라미터의 값을 얻을 수 없다. 쉽게 프로그래밍하기 위해 외부 라이브러리를 이용한다. (아파치 commons.fileupload 또는 cos) 게시글을 수정한 후 상세보기를 돌아가기 위해 검색어 searchWord를 URLEncoder의 encode() 메소드로 UTF-8으로 인코딩한다. */ User user = (User) session.getAttribute(WebContants.USER_KEY); String dir = application.getRealPath("/upload"); MultipartRequest multi = new MultipartRequest( request, dir, 5*1024*1024, "UTF-8", new DefaultFileRenamePolicy()); BoardService service = new BoardService(); int articleNo = Integer.parseInt(multi.getParameter("articleNo")); //글 소유자인지 검사 if (!service.getArticle(articleNo).getEmail().equals(user.getEmail())) { response.sendError(HttpServletResponse.SC_FORBIDDEN, WebContants.AUTHENTICATION_FAILED); return; } String boardCd = multi.getParameter("boardCd"); int curPage = Integer.parseInt(multi.getParameter("curPage")); String searchWord = multi.getParameter("searchWord"); searchWord = java.net.URLEncoder.encode(searchWord, "UTF-8"); String title = multi.getParameter("title"); String content = multi.getParameter("content"); String filename = multi.getFilesystemName("attachFile"); String filetype = multi.getContentType("attachFile"); File f = multi.getFile("attachFile"); long filesize = 0L; AttachFile attachFile = null; if (f != null) { filesize = f.length(); attachFile = new AttachFile(); attachFile.setFilename(filename); attachFile.setFiletype(filetype); attachFile.setFilesize(filesize); attachFile.setEmail(user.getEmail()); attachFile.setArticleNo(articleNo); } Article article = new Article(); article.setArticleNo(articleNo); article.setBoardCd(boardCd); article.setTitle(title); article.setContent(content); article.setEmail(user.getEmail()); service.modifyArticle(article, attachFile); response.sendRedirect("view.jsp?articleNo=" + articleNo + "&boardCd=" + boardCd + "&curPage=" + curPage + "&searchWord=" + searchWord); %>
게시글 삭제 처리
/bbs/del_proc.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ page import="net.java_school.commons.WebContants" %> <%@ page import="net.java_school.user.User" %> <%@ page import="net.java_school.board.*" %> <% /* 게시글을 삭제하는 페이지로 모델 2에서는 삭제한다. -구현- 작성자인지 검사하고 작성자가 아니면 response.sendError(HttpServletResponse.SC_FORBIDDEN, "Authentication Failed"); return; 작성자 체크를 통과하면 요청의 캐릭터 셋을 UTF-8으로 설정한다. articleNo, boardCd, curPage, searchWord 파라미터를 받고 articleNo로 게시글을 삭제한다. 게시글 삭제 후 목록을 돌아가기 위해 검색어 searchWord를 URLEncoder의 encode() 메소드로 UTF-8으로 인코딩한다. */ User user = (User) session.getAttribute(WebContants.USER_KEY); request.setCharacterEncoding("UTF-8"); //전달된 파라미터 articleNo,boardCd,curPage,searchWord int articleNo = Integer.parseInt(request.getParameter("articleNo")); //글 소유자 검사 BoardService service = new BoardService(); Article article = service.getArticle(articleNo); if (user == null || !user.getEmail().equals(article.getEmail())) { response.sendError(HttpServletResponse.SC_FORBIDDEN, WebContants.AUTHENTICATION_FAILED); return; } service.removeArticle(articleNo); String boardCd = request.getParameter("boardCd"); String curPage = request.getParameter("curPage"); String searchWord = request.getParameter("searchWord"); searchWord = java.net.URLEncoder.encode(searchWord, "UTF-8"); response.sendRedirect("list.jsp?boardCd=" + boardCd + "&curPage=" + curPage + "&searchWord=" + searchWord); %>