java-school logo

프로토타입(prototype)

프로토타입이란 개발 초기에 만드는 일종의 모형이다.
웹 애플리케이션의 프로토타입은 화면에 해당하는 JSP를 위주로 작성한다.
프로그램 로직은 테스트에 필요하거나 개발 종료까지 변경되지 않는 명확한 부분만 작성한다.

메인 페이지, 서브 페이지

메인 페이지와 서브 페이지 디자인이 웹사이트 프로토타입의 첫 번째 작업이다.
메인 페이지는 웹사이트를 방문할 때 보이는 페이지를 말하는데, 홈페이지라고도 한다.
서브 페이지는 메인 페이지 외의 모든 페이지다.
Prototype Directory Structure

여기서 도큐먼트 베이스(DocumentBase)는 C:\www\JSPProject\WebContent 이다.

스타일 시트과 이미지

스타일 시트와 이미지 파일은 CSS Layout 최종 결과물을 사용한다.
CSS Layout 최종 소스
내려받은 압축 파일을 풀고 스타일 시트와 이미지 파일을 css와 images 폴더에 복사하고 HTML 파일은 도큐먼트 베이스에 복사한다.

메인 페이지

로그인 로직을 프로토타입에 추가하겠다.
따라서 메인 페이지를 작성하기 전에 다음 User 클래스가 먼저 생성한다.

User.java
package net.java_school.user;

public class User {
    private String email;
    private String passwd;
    private String name;
    private String mobile;
    
    public User() {}

    public User(String email, String passwd) {
        this.email = email;
        this.passwd = passwd;
    }
    
    public User(String email, String passwd, String name, String mobile) {
        this.email = email;
        this.passwd = passwd;
        this.name = name;
        this.mobile = mobile;
    }

    public String getEmail() {
        return email;
    }
    
    public void setEmail(String email) {
        this.email = email;
    }

    public String getPasswd() {
        return passwd;
    }
    
    public void setPasswd(String passwd) {
        this.passwd = passwd;
    }
    
    public String getName() {
        return name;
    }
    
    public void setName(String name) {
        this.name = name;
    }
    
    public String getMobile() {
        return mobile;
    }
    
    public void setMobile(String mobile) {
        this.mobile = mobile;
    }

}

User 클래스에 아이디가 없다.
아이디로 이메일을 사용할 것이다.

로그인 정책

도큐먼트베이스의 index.html을 index.jsp로 파일명을 변경한 후 아래와 같이 수정한다.

/index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="net.java_school.user.User" %>
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8" />
<meta name="Keywords" content="메인 페이지" />
<meta name="Description" content="메인 페이지" />
<title>메인 페이지</title>
<link rel="stylesheet" href="css/screen.css" type="text/css" />
</head>
<body>

<div id="wrap">

    <div id="header">
        <h1 style="float: left; width: 150px;"><a href="./"><img src="images/ci.gif" alt="java-school" /></a></h1>
        <div id="memberMenu" style="float: right; position: relative; top: 7px;">
<%
User loginUser = (User) session.getAttribute("user");
if (loginUser == null) {
%>   
            <input type="button" value="로그인" onclick="location.href='./users/login.jsp'" />
            <input type="button" value="회원 가입" onclick="location.href='./users/signUp.jsp'" />
<%
} else {
%>
            <input type="button" value="로그아웃" onclick="location.href='./users/logout_proc.jsp'" />
            <input type="button" value="내 정보 수정" onclick="location.href='./users/editAccount.jsp'" />
<%
}
%>
        </div>
    </div>

    <div id="main-menu">
        <ul id="nav"><!-- 이전 메뉴와 다르다. -->
            <li><a href="java/">Java</a></li>
            <li><a href="jdbc/">JDBC</a></li>
            <li><a href="jsp/">JSP</a></li>
            <li><a href="css-layout/">CSS Layout</a></li>
            <li><a href="jsp-project/">JSP Project</a></li>
            <li><a href="spring/">Spring</a></li>
            <li><a href="javascript/">JavaScript</a></li>
            <li><a href="bbs/list.jsp?boardCd=free&curPage=1">BBS</a></li><!-- 자유 게시판 첫 페이지 -->
        </ul>
    </div>

    <div id="container">
        <div id="content" style="min-height: 800px;">

<!-- 본문 시작 -->
<div id="url-navi">Main</div>
            
<h1>수정</h1>
<h2>JSP Project 전반적인 내용 수정 2014.9.26</h2>
프로토타입을 만든 후에 진행하는 것으로 내용 수정<br />
프로토타입에 로그인 구현<br />

<h2>CSS Layout 수정 2014.9.26</h2>
카테고리 정리<br />
스타일 시트 파일 체계적으로 갱신<br />
<!--  본문 끝 -->
        </div><!-- content 끝 -->
    </div><!--  container 끝 -->
    
    <div id="sidebar">
        <h1>Main</h1>
    </div>
    
    <div id="extra">
        <a href="http://www.youtube.com"><img src="images/youtube.png" alt="youtube.com" /></a>
        <a href="http://www.twitter.com"><img src="images/twitter.png" alt="twitter.com" /></a>
        <a href="http://www.facebook.com"><img src="images/facebook.png" alt="facebook.com" /></a>
        <a href="http://www.gmail.com"><img src="images/gmail.png" alt="gmail.com" /></a>
        <a href="http://www.java-school.net"><img src="images/java-school.png" alt="java-school.net" /></a>
    </div>

    <div id="footer">
        <ul>
            <li><a href="#">이용약관</a></li>
            <li><a href="#">개인정보보호정책</a></li>
            <li><a href="#">이메일무단수집거부</a></li>
            <li id="company-info">전화 : 02-123-5678, FAX : 02-123-5678<br />
            people@ggmail.org<br />
            Copyright java-school.net All Rights Reserved.</li>
            <li><a href="#">찾아오시는 길</a></li>
        </ul>
    </div>

</div>
</body>
</html>

서브 페이지

홈페이지 /index.jsp를 Save As... 메뉴를 이용하여 java 서브 디렉터리에 index.jsp 파일을 만든 후 아래와 같이 수정한다. 홈페이지와 달리 이 페이지는 서브 디렉터리에 있으므로 상대 경로를 수정해야 한다.

/java/index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" %>
<%@ page import="net.java_school.user.User" %>    
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8" />
<meta name="Keywords" content="자바 홈" />
<meta name="Description" content="자바 홈" />
<title>자바 홈</title>
<link rel="stylesheet" href="../css/screen.css" type="text/css"  />
</head>
<body>

<div id="wrap">

    <div id="header">
        <h1 style="float: left; width: 150px;" ><a href="../"><img src="../images/ci.gif" alt="java-school" /></a></h1>
        <div id="memberMenu" style="float: right; position: relative; top: 7px;">
<%
User loginUser = (User) session.getAttribute("user");
if (loginUser == null) {
%>   
            <input type="button" value="로그인" onclick="location.href='../users/login.jsp'" />
            <input type="button" value="회원 가입" onclick="location.href='../users/signUp.jsp'" />
<%
} else {
%>
            <input type="button" value="로그아웃" onclick="location.href='../users/logout_proc.jsp'" />
            <input type="button" value="내 정보 수정" onclick="location.href='../users/editAccount.jsp'" />
<%
}
%>
        </div>
    </div>

    <div id="main-menu">
        <ul id="nav">
            <li><a href="../java/">Java</a></li>
            <li><a href="../jdbc/">JDBC</a></li>
            <li><a href="../jsp/">JSP</a></li>
            <li><a href="../css-layout/">CSS Layout</a></li>
            <li><a href="../jsp-project/">JSP Project</a></li>
            <li><a href="../spring/">Spring</a></li>
            <li><a href="../javascript/">JavaScript</a></li>
            <li><a href="../bbs/list.jsp?boardCd=free&curPage=1">BBS</a></li>
        </ul>
    </div>


    <div id="container">
        <div id="content" style="min-height: 800px;">

<!-- 본문 시작 -->
<div id="url-navi">Java Home</div>
            
<h1>JDK 설치</h1>
<p>
www.oracle.com을 방문하여 JDK를 내려받는다.<br />
설치는 다음 버튼을 클릭하는 것으로 완료할 수 있다.<br />  
설치 후 PATH 환경 변수에 JDK의 bin 디렉터리를 추가한다.<br />
PATH의 기존 설정값 제일 뒤에 윈도 환경 변수의 구분자 ;를 추가하고 JDK의 bin까지의 경로를 붙여넣는다.<br />
이때 기존값은 지우지 않도록 주의한다.<br /> 
</p>

<h2>PATH</h2>
<p>
PATH는 운영체제가 실행 프로그램을 찾을 때 참조하는 환경 변수이다.<br />
명령 프롬프트에서 <strong>echo %PATH%</strong>를 실행하면 PATH의 설정값을 확인할 수 있다.<br />
PATH에 JDK의 bin디렉터리를 추가하는 이유는 어느 디렉터리에서나 JDK의 bin에 있는 
실행 프로그램(javac.exe,java.exe,jar.exe 등)을 실행할 수 있도록 하기 위해서이다.<br />
</p>

<h2>테스트</h2>
<p>
아래 내용을 메모장에 작성하고 파일명을 Test.java로 저장한다.<br />
</p>

<pre>
public class Test {
  public static void main(String[] args) {
    System.out.println("Hello World!");
  }
}
</pre>

<ol>
    <li>명령 프롬프트에서 Test.java 파일이 있는 디렉터리로 이동한다.</li>
    <li>javac Test.java로 컴파일한다. Test.class가 현재 디렉터리에 만들어진다.</li>
    <li>java Test로 실행한다.</li>
</ol>

<pre>
C:\>javac Test.java

C:\>java Test
Hello World!
</pre>

<!-- 본문 끝 -->
        </div><!-- content 끝 -->
    </div><!--  container 끝 -->
    
    <div id="sidebar">
        <h1>Java</h1>
    </div>
    
    <div id="extra">
        <a href="http://www.youtube.com"><img src="../images/youtube.png" alt="youtube.com" /></a>
        <a href="http://www.twitter.com"><img src="../images/twitter.png" alt="twitter.com" /></a>
        <a href="http://www.facebook.com"><img src="../images/facebook.png" alt="facebook.com" /></a>
        <a href="http://www.gmail.com"><img src="../images/gmail.png" alt="gmail.com" /></a>
        <a href="http://www.java-school.net"><img src="../images/java-school.png" alt="java-school.net" /></a>
    </div>

    <div id="footer">
        <ul>
            <li><a href="#">이용약관</a></li>
            <li><a href="#">개인정보보호정책</a></li>
            <li><a href="#">이메일무단수집거부</a></li>
            <li id="company-info">전화 : 02-123-5678, FAX : 02-123-5678<br />
            people@ggmail.org<br />
            Copyright java-school.net All Rights Reserved.</li>
            <li><a href="#">찾아오시는 길</a></li>
        </ul>
    </div>

</div>

</body>
</html>

공통 JSP 페이지

화면 배치가 같으면 JSP 인클루드 지시어를 사용하여 코드를 분리할 수 있다.
페이지를 분리하면 유지 보수가 편해진다.
#header에 있는 로고와 로그인/로그아웃 버튼, #main-menu의 메인 메뉴, #extra의 외부 링크, #footer의 글로벌 메뉴는 모든 페이지에서 공통이다.
inc 서브 디렉터리에 다음 JSP 파일을 생성한다.
/java/index.jsp 파일을 참고하여 다음 파일을 생성한다.

/inc/header.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="net.java_school.user.User" %>
<h1 style="float: left; width: 150px;"><a href="../"><img src="../images/ci.gif" alt="java-school" /></a></h1>
<div id="memberMenu" style="float: right; position: relative; top: 7px;">
<%
User loginUser = (User) session.getAttribute("user");
if (loginUser == null) {
%>
    <input type="button" value="로그인" onclick="location.href='../users/login.jsp'" />
    <input type="button" value="회원 가입" onclick="location.href='../users/signUp.jsp'" />
<%
} else {
%>   
    <input type="button" value="로그아웃" onclick="location.href='../users/logout_proc.jsp'" />
    <input type="button" value="내 정보 수정" onclick="location.href='../users/editAccount.jsp'" />
<%
}
%>
</div>
/inc/main-menu.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<ul id="nav">
    <li><a href="../java/">Java</a></li>
    <li><a href="../jdbc/">JDBC</a></li>
    <li><a href="../jsp/">JSP</a></li>
    <li><a href="../css-layout/">CSS Layout</a></li>
    <li><a href="../jsp-project/">JSP Project</a></li>
    <li><a href="../spring/">Spring</a></li>
    <li><a href="../javascript/">JavaScript</a></li>
    <li><a href="../bbs/list.jsp?boardCd=free&curPage=1">BBS</a></li>
</ul>
/inc/extra.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<a href="http://www.youtube.com"><img src="../images/youtube.png" alt="youtube.com" /></a>
<a href="http://www.twitter.com"><img src="../images/twitter.png" alt="twitter.com" /></a>
<a href="http://www.facebook.com"><img src="../images/facebook.png" alt="facebook.com" /></a>
<a href="http://www.gmail.com"><img src="../images/gmail.png" alt="gmail.com" /></a>
<a href="http://www.java-school.net"><img src="../images/java-school.png" alt="java-school.net" /></a>
/inc/footer.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<ul>
    <li><a href="#">이용약관</a></li>
    <li><a href="#">개인정보보호정책</a></li>
    <li><a href="#">이메일무단수집거부</a></li>
    <li id="company-info">전화 : 02-123-5678, FAX : 02-123-5678<br />
    people@ggmail.org<br />
    Copyright java-school.net All Rights Reserved.</li>
    <li><a href="#">찾아오시는 길</a></li>
</ul>

공통 JSP 파일을 만들 때 페이지 지시어의 contentType 속성은 포함하는 페이지와 같아야 한다.
같지 않다면 서블릿으로 변환되지 않는다.
따라서 공통 JSP 파일의 contentType은 다음과 같아야 한다.

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>

공통 JSP 파일을 이용하여 서브 페이지 수정

/java/index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" %>
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8" />
<meta name="Keywords" content="자바 홈" />
<meta name="Description" content="자바 홈" />
<title>자바 홈</title>
<link rel="stylesheet" href="../css/screen.css" type="text/css" />
</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" style="min-height: 800px;">

<!-- 본문 시작 -->
<div id="url-navi">Java Home</div>
            

<!--..중간 생략..-->


<!-- 본문 끝 -->

        </div><!-- content 끝 -->
    </div><!--  container 끝 -->
    
    <div id="sidebar">
        <h1>Java</h1>
    </div>
    
    <div id="extra">
        <%@ include file="../inc/extra.jsp" %>
    </div>

    <div id="footer">
        <%@ include file="../inc/footer.jsp" %>
    </div>

</div>

</body>
</html>

홈페이지까지 인클루드 지시어를 이용하여 분리하려는 생각은 좋은 생각이 아니다.
대부분 홈페이지는 서브 페이지와 디자인이 다르며 또한 하나만 존재하기 때문이다.
게다가 지금 만든 파일은 상대 경로 문제로 홈페이지에서 인클루드 할 수 없다.

웹 브라우저로 홈페이지와 서브 페이지 /java/index.jsp를 방문하여 테스트한다.

로그인 폼, 로그인 처리, 로그아웃 처리 페이지 생성

로그인 테스트를 위해 로그인 폼, 로그인 처리, 로그아웃 처리 페이지를 생성한다.
먼저 로그인 폼 페이지가 인클루드하는 notLoginUsers-menu.jsp를 /users 디렉터리에 만든다.
이 페이지는 로그인 하지 않은 사용자가 사용할 수 있는 회원 메뉴(로그인, 회원 가입, ID 찾기, 비밀번호 찾기)를 보여준다.

/users/notLoginUsers-menu.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<h1>회원</h1>
<ul>
    <li>
        <ul>
            <li><a href="login.jsp">로그인</a></li>
            <li><a href="signUp.jsp">회원 가입</a></li>
            <li><a href="#">ID 찾기</a></li>
            <li><a href="#">비밀번호 찾기</a></li>
        </ul>
    </li>
</ul>

로그인 폼 페이지를 만든다.
/java/index.jsp를 연 상태에서 Save As... 메뉴를 이용하여 login.jsp라는 이름의 새 파일을 /users 디렉터리에 만든 후 아래와 같이 수정한다.

/users/login.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
request.setCharacterEncoding("UTF-8");
String url = request.getParameter("url");
if (url == null) url = "";
%>
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8" />
<meta name="Keywords" content="로그인" />
<meta name="Description" content="로그인" />
<title>로그인</title>
<link rel="stylesheet" href="../css/screen.css" type="text/css" />
<script type="text/javascript">
function check() {
    //var form = document.getElementById("loginForm");
    //TODO 유효성 검사
    return true;
}        
</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" style="min-height: 800px;">

<!-- 본문 시작 -->
<div id="url-navi">회원</div>

<h1>로그인</h1>
<form id="loginForm" action="login_proc.jsp" method="post" onsubmit="return check()">
<p style="margin: 0; padding: 0;">
<input type="hidden" name="url" value="<%=url %>" />
</p>
<table>
<tr>
    <td style="width: 200px;">Email</td>
    <td style="width: 390px"><input type="text" name="email" style="width: 99%;" value="captain@heist.com" /></td>
</tr>
<tr>
    <td>비밀번호(Password)</td>
    <td><input type="password" name="passwd" style="width: 99%;" value="1111" /></td>
</tr>
</table>
<div style="text-align: center;padding-top: 15px;">
    <input type="submit" value="확인" />
    <input type="button" value="회원 가입" onclick="location.href='signUp.jsp'" />
</div>
</form>
<!--  본문 끝 -->
        </div><!-- content 끝 -->
    </div><!--  container 끝 -->
    
    <div id="sidebar">
        <%@ include file="notLoginUsers-menu.jsp" %>
    </div>
    
    <div id="extra">
        <%@ include file="../inc/extra.jsp" %>
    </div>

    <div id="footer">
        <%@ include file="../inc/footer.jsp" %>
    </div>

</div>

</body>
</html>

로그인을 처리하는 페이지를 만든다.

/users/login_proc.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="net.java_school.user.User"%>
<%
String url = request.getParameter("url");
String email = request.getParameter("email");
String passwd = request.getParameter("passwd");

session.setAttribute("user", new User(email, passwd, "홍길동", "010-1234-5678"));
if (url != null && !url.equals("")) {
    response.sendRedirect(url);
} else {
    response.sendRedirect("../bbs/list.jsp?boarCd=free&curPage=1");
}
%>

로그아웃을 처리하는 페이지를 만든다.
로그아웃 후 홈페이지로 이동하도록 구현한다.

/users/logout_proc.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
session.removeAttribute("user");

response.sendRedirect("../");
%>

웹 브라우저로 로그인과 로그아웃을 테스트한다.
로그인하면 아직 만들지 않은 게시판으로 이동하여 404 에러를 보게 된다.
다시 상단의 로고를 클릭하여 홈페이지로 이동, 홈페이지에서 Java 메인 메뉴를 클릭하여 서브 페이지로 이동한 후 로그아웃하면 홈페이지로 이동한다.

JSP 에러 핸들링

web.xml 파일을 열고 </web-app> 직전에 다음을 추가한다.

web.xml
<error-page>
    <error-code>403</error-code>
    <location>/error.jsp</location>
</error-page>
<error-page>
    <error-code>404</error-code>
    <location>/error.jsp</location>
</error-page>
<error-page>
    <error-code>500</error-code>
    <location>/error.jsp</location>
</error-page>
<error-page>
    <exception-type>java.lang.Throwable</exception-type>
    <location>/error.jsp</location>
</error-page>

주요 에러를 모두 /error.jsp가 담당하도록 하는 설정이다.

에러 페이지

홈페이지를 연 상태에서 Save As... 메뉴를 이용하여 error.jsp라는 새 파일을 도큐먼트 베이스에 만든 후 아래와 같이 수정한다.

/error.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="net.java_school.user.User" %>
<%
String contextPath = request.getContextPath();
%>
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8" />
<meta name="Keywords" content="Error" />
<meta name="Description" content="Error" />
<title>Error</title>
<link rel="stylesheet" href="<%=contextPath %>/css/screen.css" type="text/css" />
</head>
<body>
<%
//Analyze the servlet exception
Throwable throwable = (Throwable) request.getAttribute("javax.servlet.error.exception");
Integer statusCode = (Integer) request.getAttribute("javax.servlet.error.status_code");
String servletName = (String) request.getAttribute("javax.servlet.error.servlet_name");

if (servletName == null) {
    servletName = "Unknown";
}

String requestUri = (String) request.getAttribute("javax.servlet.error.request_uri");

if (requestUri == null) {
    requestUri = "Unknown";
}
%>
<div id="wrap">

    <div id="header">
        <h1 style="float: left; width: 150px;"><a href="<%=contextPath %>"><img src="<%=contextPath %>/images/ci.gif" alt="java-school" /></a></h1>
        <div id="memberMenu" style="float: right; position: relative; top: 7px;">
<%
User loginUser = (User) session.getAttribute("user");
if (loginUser == null) {
%>
    <input type="button" value="로그인" onclick="location.href='<%=contextPath %>/users/login.jsp'" />
    <input type="button" value="회원 가입" onclick="location.href='<%=contextPath %>/users/signUp.jsp'" />
<%
} else {
%>   
    <input type="button" value="로그아웃" onclick="location.href='<%=contextPath %>/users/logout_proc.jsp'" />
    <input type="button" value="내 정보 수정" onclick="location.href='<%=contextPath %>/users/editAccount.jsp'" />
<%
}
%>
        </div>
    </div>

    <div id="main-menu">
        <ul id="nav">
            <li><a href="<%=contextPath %>/java/">Java</a></li>
            <li><a href="<%=contextPath %>/jdbc/">JDBC</a></li>
            <li><a href="<%=contextPath %>/jsp/">JSP</a></li>
            <li><a href="<%=contextPath %>/css-layout/">CSS Layout</a></li>
            <li><a href="<%=contextPath %>/jsp-project/">JSP Project</a></li>
            <li><a href="<%=contextPath %>/spring/">Spring</a></li>
            <li><a href="<%=contextPath %>/javascript/">JavaScript</a></li>
            <li><a href="<%=contextPath %>/bbs/list.jsp?boardCd=free&curPage=1">BBS</a></li>
        </ul>
    </div>

    <div id="container">
        <div id="content" style="min-height: 820px;">

<!-- 본문 시작 -->
<div id="url-navi">Error</div>
            
<h1>Error Page</h1>
<%
if(statusCode != 500){
    out.write("<h3>Error Details</h3>");
    out.write("<strong>Status Code</strong>:" + statusCode + "<br>");
    out.write("<strong>Requested URI</strong>:"+requestUri);
}    
if (throwable != null) {
    out.write("<h3>Exception Details</h3>");
    out.write("<ul><li>Servlet Name:" + servletName + "</li>");
    out.write("<li>Exception Name:" + throwable.getClass().getName() + "</li>");
    out.write("<li>Requested URI:" + requestUri + "</li>");
    out.write("<li>Exception Message:" + throwable.getMessage() + "</li>");
    out.write("</ul>");
}
%>
<!--  본문 끝 -->
        </div><!-- content 끝 -->
    </div><!--  container 끝 -->
    
    <div id="sidebar">
        <h1>Error</h1>
    </div>
    
    <div id="extra">
        <a href="http://www.youtube.com"><img src="<%=contextPath %>/images/youtube.png" alt="youtube.com" /></a>
        <a href="http://www.twitter.com"><img src="<%=contextPath %>/images/twitter.png" alt="twitter.com" /></a>
        <a href="http://www.facebook.com"><img src="<%=contextPath %>/images/facebook.png" alt="facebook.com" /></a>
        <a href="http://www.gmail.com"><img src="<%=contextPath %>/images/gmail.png" alt="gmail.com" /></a>
        <a href="http://www.java-school.net"><img src="<%=contextPath %>/images/java-school.png" alt="java-school.net" /></a>
    </div>

    <div id="footer">
        <%@ include file="./inc/footer.jsp" %>
    </div>

</div>

</body>
</html>

error.jsp 소스에서 컨텍스트 패스를 구해 모든 경로를 재지정해 주어야 하는데, 이렇게 하지 않으면 상대 경로 문제를 겪게 된다.
다시 로그인을 시도한다. 아직 만들지 않는 페이지를 요청하게 된다. 에러 페이지가 작동하는지 확인한다.

게시판

게시판 관련 페이지를 작성한다.

게시판 메뉴(bbs-sub.jsp) 페이지

게시판 모듈에서 화면을 담당하는 모든 페이지가 인클루드해야 하는 페이지부터 작성한다.
도큐먼트 베이스에 bbs라는 서브 디렉터리를 만들고, /bbs에 bbs-sub.jsp 파일을 만든다.
bbs-sub.jsp 파일은 게시판에 대한 링크를 제공한다.

/bbs/bbs-sub.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<h1>게시판</h1>
<ul>
    <li>
        <ul>
            <li><a href="list.jsp?boardCd=free&curPage=1">자유 게시판</a></li>
            <li><a href="list.jsp?boardCd=qna&curPage=1">QnA게시판</a></li>
            <li><a href="list.jsp?boardCd=data&curPage=1">자료실</a></li>
        </ul>
    </li>
</ul>

로그인 체크(loginCheck.jsp) 페이지

이 페이지는 사용자가 로그인했는지를 검사하고, 로그인하지 않은 사용자는 로그인 페이지로 리다이렉트시킨다.
이때 로그인 후 다시 사용자가 요청한 원래 페이지로 이동하기 위해 url 정보를 로그인 페이지에 전달한다.
공통 인클루드 파일 디렉터리인 /inc에 loginCheck.jsp 파일을 만든다.
이 파일을 공통 인클루드 파일 디렉터리에 생성하는 이유는 게시판 모듈 외에도 사용될 수 있기 때문이다.

/inc/loginCheck.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="net.java_school.user.*"%>
<%@ page import="java.net.URLEncoder"%>
<%   
User user = (User) session.getAttribute("user");
if (user == null) {
    //로그인 후 되돌아갈 URL를 구한다.
    String uri = request.getRequestURI();
    String query = request.getQueryString();
    String url = uri;
    if (query != null) url += "?" + query;
    //로그인 페이지로 리다이렉트
    String contextPath= request.getContextPath();
    url = URLEncoder.encode(url, "UTF-8");
    response.sendRedirect(contextPath + "/users/login.jsp?url=" + url);
    return;
}
%>

목록 페이지

게시판 목록을 보여주는 페이지를 만든다.
CSS 포지셔닝에서의 만든 list.html 파일을 연 상태에서 Save As... 메뉴를 이용하여 list.jsp라는 이름의 새 파일을 /bbs 디렉터리에 만든 후 아래와 같이 수정한다.

/bbs/list.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ include file="../inc/loginCheck.jsp" %>
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8" />
<meta name="Keywords" content="게시판 목록" />
<meta name="Description" content="게시판 목록" />
<title>BBS</title>
<link rel="stylesheet" href="../css/screen.css" type="text/css" />
<script type="text/javascript">
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();
}
</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" style="min-height: 800px;">

<!-- 본문 시작 -->
<div id="url-navi">BBS</div>
            
<h1>자유 게시판</h1>
    <table class="bbs-table">
    <!--  게시판 목록 머리말 -->
    <tr>
        <th style="width: 60px">NO</th>
        <th>TITLE</th>
        <th style="width: 84px;">DATE</th>
        <th style="width: 60px;">HIT</th>
    </tr>
    <!--  반복 구간 시작 -->
    <tr>
        <td style="text-align: center;">11</td>
        <td>
            <a href="javascript:goView('1')">제목</a>
            <img src="../images/attach.png" alt="첨부 파일" />
            <span class="bbs-strong">[5]</span>
        </td>
        <td style="text-align: center;">2011.11.15</td>
        <td style="text-align: center;">4555</td>
    </tr>
    <!--  반복 구간 끝 -->
    </table>
        
    <div id="paging">
        <a href="javascript:goList('5')">[이전]</a>
        <span class="bbs-strong">6</span>
        <a href="javascript:goList('7')">7</a>
        <a href="javascript:goList('8')">8</a>
        <a href="javascript:goList('9')">9</a>
        <a href="javascript:goList('10')">10</a>
        <a href="javascript:goList('11')">[다음]</a>  
    </div>

    <div id="list-menu">
        <input type="button" value="새 글쓰기" onclick="goWrite()" />
    </div>

    <div id="search">
        <form action="list.jsp" method="get">
            <p style="margin: 0;padding: 0;">
                <input type="hidden" name="boardCd" value="free" />
                <input type="hidden" name="curPage" value="1" />
                <input type="text" name="searchWord" size="15" maxlength="30" />
                <input type="submit" value="검색" />
            </p>
        </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">
    <p>
        <input type="hidden" name="boardCd" value="free" />
        <input type="hidden" name="curPage" />
        <input type="hidden" name="searchWord" value="무궁화꽃" />
    </p>
    </form>
    <form id="viewForm" action="view.jsp" method="get">
    <p>
        <input type="hidden" name="articleNo" />
        <input type="hidden" name="boardCd" value="free" />
        <input type="hidden" name="curPage" value="1" />
        <input type="hidden" name="searchWord" value="무궁화꽃" />
    </p>
    </form>
    <form id="writeForm" action="write_form.jsp" method="get">
    <p>
        <input type="hidden" name="boardCd" value="free" />
        <input type="hidden" name="curPage" value="1" />
        <input type="hidden" name="searchWord" value="무궁화꽃" />
    </p>
    </form>
</div>

</body>
</html>

글쓰기 폼 페이지

다음은 게시판 글쓰기 폼 페이지를 작성한다.
CSS 포지셔닝에서 만든 write_form.html 파일을 연 상태에서 Save As... 메뉴를 이용하여 write_form.jsp라는 이름의 새 파일을 /bbs 디렉터리에 만든 후 아래와 같이 수정한다.

/bbs/write_form.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ include file="../inc/loginCheck.jsp" %>
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8" />
<meta name="Keywords" content="글쓰기 화면" />
<meta name="Description" content="글쓰기 화면" />
<title>BBS</title>
<link rel="stylesheet" href="../css/screen.css" type="text/css" />
<script type="text/javascript">
function check() {
    //var form = document.getElementById("writeForm");
    //유효성 검사 로직 추가
    return true;
}

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" style="min-height: 800px;">
        
<!--  본문 시작 -->
<div id="url-navi">BBS</div>
<h1>자유 게시판</h1>
<h2>글쓰기</h2>
<form id="writeForm" action="write_proc.jsp" method="post" enctype="multipart/form-data" onsubmit="return check();">
<p style="margin: 0;padding: 0;">
<input type="hidden" name="boardCd" value="free" />
</p>
<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()" />
    <input type="button" value="상세보기" onclick="goView()" />
</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">
    <p>
        <input type="hidden" name="articleNo" value="5" />
        <input type="hidden" name="boardCd" value="free" />
        <input type="hidden" name="curPage" value="1" />
        <input type="hidden" name="searchWord" value="무궁화꽃" />
    </p>
    </form>
    <form id="listForm" action="list.jsp" method="get">
    <p>
        <input type="hidden" name="boardCd" value="free" />
        <input type="hidden" name="curPage" value="1" />
        <input type="hidden" name="searchWord" value="무궁화꽃" />
    </p>
    </form>   
</div>

</body>
</html>

글쓰기 처리 페이지

글쓰기 처리 페이지를 작성한다.
이 페이지는 글쓰기 폼에서 전달받는 파라미터로 실제로 데이터베이스에 인서트를 담당한다.

/bbs/write_proc.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
/*
새 게시글을 등록하는 페이지로 모델 2에서는 삭제해야 할 페이지다.
-구현-
로그인 사용자가 아니면
response.sendError(HttpServletResponse.SC_FORBIDDEN, "Not Login"); return;
로그인 체크를 통과하면
boardCd, title, content, attachFile 파라미터를 가지고 새 글을 인서트한다.

form의 enctype 속성이 "multipart/form-data"인 경우 request.getParameter();로 파라미터의 값을 얻을 수 없다.
이 경우 프로그래밍을 손쉽게 하려면 아파치 commons-fileupload 또는 cos와 같은 외부 라이브러리를 이용한다.

새 글을 등록한 후 목록의 첫 번째 페이지로 되돌아가야 한다.
*/
response.sendRedirect("list.jsp?boardCd=free&curPage=1");
%>

상세보기 페이지

목록에서 제목을 클릭하면 보이게 되는 게시글 상세보기 페이지를 만든다.
CSS 포지셔닝에서 만든 view.html 파일을 연 상태에서 Save As... 메뉴를 이용하여 view.jsp 이름의 새 파일을 /bbs 디렉터리에 만든 후 아래와 같이 수정한다.

/bbs/view.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ include file="../inc/loginCheck.jsp" %>
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8" />
<meta name="Keywords" content="게시판 상세보기" />
<meta name="Description" content="게시판 상세보기" />
<title>BBS</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" + articleNo;
    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" style="min-height: 800px;">

<!-- 본문 시작 -->
<div id="url-navi">BBS</div>
<h1>자유 게시판</h1>
<table class="bbs-table">
<tr>
    <th style="width: 37px;text-align: left;vertical-align: top;">TITLE</th>
    <th style="text-align: left;color: #555;">무궁화꽃이피었습니다</th>
</tr> 
</table>
<div id="gul-content">
    <span id="date-writer-hit">edited 2014-10-09 17:55:30 by 홍길동 hit 1330</span>
    <p>
    무궁화꽃이피었습니다무궁화꽃이피었습니다무궁화꽃이피었습니다<br />
    무궁화꽃이피었습니다무궁화꽃이피었습니다무궁화꽃이피었습니다<br />
    </p>
    <p id="file-list" style="text-align: right">
        <a href="#">abc.zip</a>
        <a href="javascript:deleteAttachFile('23')">x</a>
    </p>
</div>

<!--  댓글 반복 시작 -->
<div class="comments">
    <span class="writer">xman</span>
    <span class="date">2011.12.11 12:14:32</span>
    <span class="modify-del">
        <a href="javascript:modifyCommentToggle('5')">수정</a>
         | <a href="javascript:deleteComment('5')">삭제</a>
    </span>
    <p id="comment5">무궁화꽃이피었습니다</p>
    <form id="modifyCommentForm5" class="modify-comment" action="updateComment_proc.jsp" method="post" style="display: none;">
    <p>
        <input type="hidden" name="commentNo" value="5" />
        <input type="hidden" name="boardCd" value="free" />
        <input type="hidden" name="articleNo" value="12" />
        <input type="hidden" name="curPage" value="1" />
        <input type="hidden" name="searchWord" value="무궁화꽃" />
    </p>
    <div class="fr">
            <a href="javascript:document.forms.modifyCommentForm5.submit()">수정하기</a>
            | <a href="javascript:modifyCommentToggle('5')">취소</a>
    </div>
    <div>
        <textarea class="modify-comment-ta" name="memo" rows="7" cols="50">무궁화꽃이 피었습니다.</textarea>
    </div>
    </form>
</div>
<!--  댓글 반복 끝 -->

<form id="addCommentForm" action="addComment_proc.jsp" method="post">
    <p style="margin: 0; padding: 0;">
        <input type="hidden" name="articleNo" value="5"/>
        <input type="hidden" name="boardCd" value="free" />
        <input type="hidden" name="curPage" value="1" />
        <input type="hidden" name="searchWord" value="무궁화꽃" />
    </p>
    <div id="addComment">
        <textarea name="memo" rows="7" cols="50"></textarea>
    </div>
    <div style="text-align: right;">
        <input type="submit" value="댓글 남기기" />
    </div>
</form>

<div id="next-prev">
    <p>다음 글 : <a href="javascript:goView('6')">무궁화꽃이 피었습니다.</a></p>
    <p>이전 글 : <a href="javascript:goView('4')">무궁화꽃이 피었습니다.</a></p>
</div>

<div id="view-menu">
    <div class="fl">
        <input type="button" value="수정" onclick="goModify()" />
        <input type="button" value="삭제" onclick="goDelete()"/>
    </div>
    <div class="fr">
        <input type="button" value="다음 글" onclick="goView('6')" />
        <input type="button" value="이전 글" onclick="goView('4')" />
        <input type="button" value="목록" onclick="goList('1')" />
        <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>
    
<tr>
    <td style="text-align: center;"><img src="../images/arrow.gif" alt="현재 글" /></td>
    <td>
        <a href="javascript:goView('1')">제목</a>
        <img src="../images/attach.png" alt="첨부 파일" />
        <span class="bbs-strong">[5]</span>
    </td>
    <td style="text-align: center;">2011.11.15</td>
    <td style="text-align: center;">4555</td>
</tr>
</table>
    
<div id="paging">
    <a href="javascript:goList('5')">[이전]</a>
    <span class="bbs-strong">6</span>
    <a href="javascript:goList('7')">7</a>
    <a href="javascript:goList('8')">8</a>
    <a href="javascript:goList('9')">9</a>
    <a href="javascript:goList('10')">10</a>
    <a href="javascript:goList('11')">[다음]</a>
</div>

<div id="list-menu">
    <input type="button" value="새 글쓰기" onclick="goWrite()" />
</div>

<div id="search">
    <form action="list.jsp" method="get">
        <p style="margin: 0;padding: 0;">
            <input type="hidden" name="boardCd" value="free" />
            <input type="hidden" name="curPage" value="1" />
            <input type="text" name="searchWord" size="15" maxlength="30" />
            <input type="submit" value="검색" />
        </p>
    </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">
    <p>
        <input type="hidden" name="boardCd" value="free" />
        <input type="hidden" name="curPage" />
        <input type="hidden" name="searchWord" value="무궁화꽃" />
    </p>
    </form>
    <form id="viewForm" action="view.jsp" method="get">
    <p>
        <input type="hidden" name="articleNo" />
        <input type="hidden" name="boardCd" value="free" />
        <input type="hidden" name="curPage" value="1" />
        <input type="hidden" name="searchWord" value="무궁화꽃" />
    </p>
    </form>
    <form id="writeForm" action="write_form.jsp" method="get">
    <p>
        <input type="hidden" name="articleNo" value="5" />
        <input type="hidden" name="boardCd" value="free" />
        <input type="hidden" name="curPage" value="12" />
        <input type="hidden" name="searchWord" value="무궁화꽃" />
    </p>
    </form>
    <form id="modifyForm" action="modify_form.jsp" method="get">
    <p>
        <input type="hidden" name="articleNo" value="5" />
        <input type="hidden" name="boardCd" value="free" />
        <input type="hidden" name="curPage" value="1" />
        <input type="hidden" name="searchWord" value="무궁화꽃" />
    </p>
    </form>
    <form id="delForm" action="del_proc.jsp" method="post">
    <p>
        <input type="hidden" name="articleNo" value="5" />
        <input type="hidden" name="boardCd" value="free" />
        <input type="hidden" name="curPage" value="1" />
        <input type="hidden" name="searchWord" value="무궁화꽃" />
    </p>
    </form>
    <form id="deleteCommentForm" action="deleteComment_proc.jsp" method="post">
    <p>
        <input type="hidden" name="commentNo" />
        <input type="hidden" name="articleNo" value="12" />
        <input type="hidden" name="boardCd" value="free" />
        <input type="hidden" name="curPage" value="1" />
        <input type="hidden" name="searchWord" value="무궁화꽃" />
    </p>
    </form>   
    <form id="deleteAttachFileForm" action="deleteAttachFile_proc.jsp" method="post">
    <p>
        <input type="hidden" name="attachFileNo" />
        <input type="hidden" name="articleNo" value="23" />
        <input type="hidden" name="boardCd" value="free" />
        <input type="hidden" name="curPage" value="1" />
        <input type="hidden" name="searchWord" value="무궁화꽃" />
    </p>
    </form>       
</div>

</body>
</html>

댓글 쓰기 처리 페이지

댓글 쓰기 처리 페이지는 상세보기 페이지에서 새 댓글을 쓰고 확인을 클릭하면 실제 댓글을 데이터베이스에 인서트 하는 페이지이다.

/bbs/addComment_proc.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
/*
새로운 댓글을 인서트하는 페이지로 모델 2에서는 삭제해야 할 페이지이다.
-구현-
로그인 사용자가 아니면 
response.sendError(HttpServletResponse.SC_FORBIDDEN, "Not Login"); return;
로그인 체크를 통과하면 
먼저 요청의 캐릭터 셋을 UTF-8로 설정한다.
boardCd, articleNo, curPage, searchWord, memo 파라미터를 받아서 댓글을 인서트한다.
댓글을 인서트한 후 상세보기를 돌아가기 위해선
검색어 searchWord를 URLEncoder의 encode 메서드로 UTF-8로 인코딩해야 한다.
*/
response.sendRedirect("view.jsp?articleNo=5&boardCd=free&curPage=1&searchWord=무궁화꽃");
%>

댓글 수정 처리 페이지

이 페이지는 상세 보기에서 댓글의 작성자가 자신의 댓글 내용을 수정한 후 확인을 클릭하면 데이터베이스에 있는 댓글의 내용을 수정하는 페이지이다.

/bbs/updateComment_proc.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
/*
댓글 업데이트를 실행하는 페이지로 모델 2에서는 삭제해야 할 페이지이다.
-구현-
작성자인지를 검사하여 작성자가 아니면
response.sendError(HttpServletResponse.SC_FORBIDDEN, "Authentication Failed"); return;
작성자 체크를 통과하면
요청의 캐릭터 셋을 UTF-8로 설정한다.
commentNo, boardCd, articleNo, curPage, searchWord, memo 파라미터를 받아서
댓글을 업데이트한다.
댓글을 업데이트 처리한 후 상세보기를 돌아가기 위해선
검색어 searchWord를 URLEncoder의 encode 메서드로 UTF-8로 인코딩해야 한다.
*/
response.sendRedirect("view.jsp?articleNo=5&boardCd=free&curPage=1&searchWord=무궁화꽃");
%>

댓글 삭제 처리 페이지

이 페이지는 상세 보기에서 댓글 삭제를 클릭하면 데이터베이스에 있는 해당 댓글을 삭제하는 페이지이다.

/bbs/deleteComment_proc.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
/*
댓글 삭제를 실행하는 페이지로 모델 2에서는 삭제해야 할 페이지이다.

-구현-
작성자인지를 검사하여 작성자가 아니면
response.sendError(HttpServletResponse.SC_FORBIDDEN, "작성자가 아닙니다"); return;
요청의 캐릭터 셋을 UTF-8로 설정해야 한다.
요청에서 참조해야 하는 파라미터는
commentNo, boardCd, articleNo, curPage, searchWord 이다.
댓글을 삭제 후 상세보기를 돌아가기 위해선
searchWord를 URLEncoder의 encode 메서드로 UTF-8로 인코딩한다.
*/
response.sendRedirect("view.jsp?articleNo=5&boardCd=free&curPage=1&searchWord=무궁화꽃");
%>

첨부 파일 삭제 처리 페이지

이 페이지는 상세 보기에서 첨부 파일 옆의 x 링크를 클릭하면 데이터베이스에 있는 첨부 파일을 삭제하는 페이지이다.
파일시스템의 파일은 삭제하지 않는다.

/bbs/deleteAttachFile_proc.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
/*
첨부 파일 삭제를 실행하는 페이지로 모델 2에서는 삭제해야 할 페이지이다.

-구현-
작성자인지를 검사하여 작성자가 아니면
response.sendError(HttpServletResponse.SC_FORBIDDEN, "작성자가 아닙니다"); return;
요청의 캐릭터 셋을 UTF-8로 설정해야 한다.
요청에서 참조해야 하는 파라미터는
attachFileNo,articleNo,boardCd,curPage,searchWord 이다.
첨부 파일를 삭제 후 상세보기를 돌아가기 위해선
searchWord를 URLEncoder의 encode 메서드로 UTF-8로 인코딩한다.
*/
response.sendRedirect("view.jsp?articleNo=5&boardCd=free&curPage=1&searchWord=무궁화꽃");
%>

게시글 삭제 처리 페이지

이 페이지는 상세보기 페이지에서 게시글을 삭제하는 삭제 버튼을 클릭하면 실제 게시글을 데이터베이스에서 삭제 처리한다.

/bbs/del_proc.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
/*
게시글을 삭제하는 페이지로 모델 2에서는 삭제해야 할 페이지이다.
-구현-
작성자가 아니면 
response.sendError(HttpServletResponse.SC_FORBIDDEN, "Authentication Failed"); return;
작성자 체크를 통과하면
요청의 캐릭터 셋을 UTF-8로 설정한다.
articleNo, boardCd, curPage, searchWord 파라미터를 받고
articleNo로 게시글을 삭제한다.
게시글 삭제 후 목록를 돌아가기 위해선
검색어 searchWord를 URLEncoder의 encode 메서드로 UTF-8로 인코딩해야 한다.
*/
response.sendRedirect("list.jsp?boardCd=free&curPage=1&searchWord=무궁화꽃");
%>

게시글 수정 폼 페이지

글 소유자가 자신의 글을 수정하기 위한 페이지를 만든다.
CSS 포지셔닝에서 만든 write_form.jsp 파일을 연 상태에서 Save As... 메뉴를 이용하여 modify_form.jsp라는 이름의 새 파일을 /bbs 폴더에 만든 후 아래와 같이 수정한다.

/bbs/modify_form.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" %>
<%
User user = (User) session.getAttribute("user");
if (user == null) {
    response.sendError(HttpServletResponse.SC_FORBIDDEN, "Not Login User");
    return;
}
request.setCharacterEncoding("UTF-8");
int articleNo = Integer.parseInt(request.getParameter("articleNo"));
String boardCd = request.getParameter("boardCd");
String curPage = request.getParameter("curPage");
String searchWord = request.getParameter("searchWord");
//TODO articleNo로 게시글 객체를 얻어서 현재 로그인된 사용자가 글 소유자인지를 검사한다.
%>
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8" />
<meta name="Keywords" content="게시판 수정하기 폼" />
<meta name="Description" content="게시판 수정하기 폼" />
<title>자유 게시판</title>
<link rel="stylesheet" href="../css/screen.css" type="text/css"  />
<script type="text/javascript">
function check() {
    //var form = document.getElementById("writeForm");
    //유효성 검사 로직 추가
    return true;
}

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" style="min-height: 800px;">

<!-- 본문 시작 -->
<div id="url-navi">BBS</div>
<h1>자유 게시판</h1>
<h2>수정</h2>
<form id="writeForm" action="modify_proc.jsp" method="post" enctype="multipart/form-data" onsubmit="return check();">
<p style="margin: 0;padding: 0;">
<input type="hidden" name="articleNo" value="5" />
<input type="hidden" name="boardCd" value="free" />
<input type="hidden" name="curPage" value="1" />
<input type="hidden" name="searchWord" value="무궁화꽃" />
</p>
<table id="write-form" class="bbs-table">
<tr>
    <td>제목</td>
    <td><input type="text" name="title" style="width: 90%;" value="무궁화꽃" /></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="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">
    <p>
        <input type="hidden" name="articleNo" value="5" />
        <input type="hidden" name="boardCd" value="free" />
        <input type="hidden" name="curPage" value="1" />
        <input type="hidden" name="searchWord" value="무궁화꽃" />
    </p>
    </form>
</div>

</body>
</html>

게시글 수정 처리 페이지

게시글 수정 폼에서 전달받은 파라미터를 가지고 실제로 게시글 수정을 처리하는 페이지이다.

/bbs/modify_proc.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
/*
게시글을 수정하는 페이지로 모델 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로 인코딩한다.
*/
response.sendRedirect("view.jsp?articleNo=5&curPage=1&boardCd=free&searchWord=무궁화꽃");
%>

게시판 관련 프로토타입 작업을 완료했다.
충분히 테스트해야 한다.
테스트 후 회원 관련 프로토타입을 작업한다.

회원

회원 관련 페이지를 작성한다.

로그인 사용자를 위한 회원 메뉴 페이지

이미 로그인하지 않은 사용자가 사용할 수 있는 회원 메뉴 페이지인 notLoginUsers-menu.jsp는 작성했다.
로그인 사용자가 이용할 수 있는 회원 메뉴 페이지인 loginUsers-menu.jsp 파일을 아래와 같이 작성한다.

/users/loginUsers-menu.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<h1>회원</h1>
<ul>
    <li>
        <ul>
            <li><a href="logout_proc.jsp">로그아웃</a></li>
            <li><a href="editAccount.jsp">내 정보 수정</a></li>
            <li><a href="changePasswd.jsp">비밀번호 변경</a></li>
            <li><a href="bye.jsp">탈퇴</a></li>
        </ul>
    </li>
</ul>

회원 가입 폼 페이지

회원 가입 폼 페이지를 만든다.
CSS 포지셔닝에서 만든 singUp.html 파일을 연 상태에서 Save As... 메뉴를 이용하여 signUp.jsp라는 이름의 새 파일을 /users 디렉터리에 만든 후 아래와 같이 수정한다.

/users/signUp.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8" />
<meta name="Keywords" content="회원 가입" />
<meta name="Description" content="회원 가입" />
<title>회원 가입</title>
<link rel="stylesheet" href="../css/screen.css" type="text/css" />
<script type="text/javascript">
function check() {
    //var form = document.getElementById("signUpForm");
    //TODO 유효성 검사
    return true;
}
</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" style="min-height: 800px;">

<!-- 본문 시작 -->
<div id="url-navi">회원</div>
<h1>회원 가입</h1>
<form id="signUpForm" action="signUp_proc.jsp" method="post" onsubmit="return check()">
<table>
<tr>
    <td style="width: 200px;">이름(Full Name)</td>
    <td style="width: 390px"><input type="text" name="name" style="width: 99%;" value="홍길동" /></td>
</tr>
<tr>
    <td>비밀번호(Password)</td>
    <td><input type="password" name="passwd" style="width: 99%;" value="1111" /></td>
</tr>
<tr>
    <td colspan="2" style="text-align: center;font-weight: bold;">
    Email이 아이디로 쓰이므로 비밀번호는 Email 계정 비밀번호와 같게 하지 마세요.
    </td>
</tr>
<tr>
    <td>비밀번호 확인(Confirm)</td>
    <td><input type="password" name="confirm" style="width: 99%;" value="1111" /></td>
</tr>
<tr>
    <td>Email</td>
    <td><input type="text" name="email" style="width: 99%;" value="captain@heist.com" /></td>
</tr>
<tr>
    <td>이동전화(Mobile)</td>
    <td><input type="text" name="mobile" style="width: 99%;" value="010-1234-5678" /></td>
</tr>
</table>
<div style="text-align: center;padding-bottom: 15px;">
    <input type="submit" value="확인" />
</div>
</form>
<!--  본문 끝 -->
        </div><!-- content 끝 -->
    </div><!--  container 끝 -->
    
    <div id="sidebar">
        <%@ include file="notLoginUsers-menu.jsp" %>
    </div>
    
    <div id="extra">
        <%@ include file="../inc/extra.jsp" %>
    </div>

    <div id="footer">
        <%@ include file="../inc/footer.jsp" %>
    </div>

</div>

</body>
</html>

회원 가입 처리 페이지

실제로 회원 가입을 처리하는 페이지이다.
회원을 데이터베이스에 등록 후 환영 페이지(welcome.jsp)로 이동하게 구현했다.

/users/signUp_proc.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
/*
회원 가입을 처리하는 페이지로 모델 2에서는 삭제해야 할 페이지다.
-구현-
자동으로 로그인하지 않는다.
회원 가입이 완료되면 환영페이지로 이동한다.
*/
response.sendRedirect("welcome.jsp");
%>

회원 가입 환영 페이지

이 페이지는 사용자에게 회원 가입이 성공했음을 알려준다.
실제 회원 가입이 되지 않았는데 이 페이지를 보게 해서는 안 된다.
signUp.jsp 파일을 연 상태에서 Sava As.. 메뉴를 이용하여 welcome.jsp라는 새 파일을 /users 디렉터리에 만든 후 아래와 같이 수정한다.

/users/welcome.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8" />
<meta name="Keywords" content="회원 가입 환영" />
<meta name="Description" content="회원 가입 환영" />
<title>회원 가입이 완료되었습니다.</title>
<link rel="stylesheet" href="../css/screen.css" type="text/css"  />
</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" style="min-height: 800px;">
        
<!-- 본문 시작 -->
<div id="url-navi">회원</div>

<h1>환영합니다.</h1>
회원 가입시 입력한 Email이 아이디로 사용됩니다.<br />
<input type="button" value="로그인" onclick="javascript:location.href='login.jsp'" />
<!--  본문 끝 -->
        </div><!-- content 끝 -->
    </div><!--  container 끝 -->
    
    <div id="sidebar">
        <h1>Welcome</h1>
    </div>
    
    <div id="extra">
        <%@ include file="../inc/extra.jsp" %>
    </div>

    <div id="footer">
        <%@ include file="../inc/footer.jsp" %>
    </div>

</div>

</body>
</html>

내 정보 수정 폼 페이지

로그인한 사용자가 자신의 정보를 수정할 수 있도록 양식을 보여주는 페이지이다.
signUp.jsp 파일을 연 상태에서 Save As... 메뉴를 이용하여 editAccount.jsp라는 이름의 새 파일을 /users 디렉터리에 만든 후 아래와 같이 수정한다.

/users/editAccount.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ include file="../inc/loginCheck.jsp" %>
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8" />
<meta name="Keywords" content="내 정보 수정" />
<meta name="Description" content="내 정보 수정" />
<title>내 정보 수정</title>
<link rel="stylesheet" href="../css/screen.css" type="text/css"  />
<script type="text/javascript">
function check() {
    //var form = document.getElementById("editAccountForm");
    //TODO 유효성 검사
    return true;
}
</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" style="min-height: 800px;">

<!-- 본문 시작 -->
<div id="url-navi">회원</div>

<h1>내 정보 수정</h1>
<p>
비밀번호외의 자신의 계정 정보를 수정할 수 있습니다.<br />
비밀번호는 <a href="changePasswd.jsp">비밀번호 변경</a>메뉴를 이용하세요.<br />
</p>
<form id="editAccountForm" action="editAccount_proc.jsp" method="post" onsubmit="return check()">
<table>
<tr>
    <td>이름(Full Name)</td>
    <td><input type="text" name="name" value="<%=user.getName() %>" /></td>
</tr>
<tr>
    <td>이동전화(Mobile)</td>
    <td><input type="text" name="mobile" value="<%=user.getMobile() %>" /></td>
</tr>
<tr>
    <td>현재 비밀번호(Password)</td>
    <td><input type="password" name="passwd" /></td>
</tr>
<tr>
    <td colspan="2"><input type="submit" value="전송" /></td>
</tr>
</table>
</form>
<!--  본문 끝 -->
        </div><!-- content 끝 -->
    </div><!--  container 끝 -->
    
    <div id="sidebar">
        <%@ include file="loginUsers-menu.jsp" %>
    </div>
    
    <div id="extra">
        <%@ include file="../inc/extra.jsp" %>
    </div>

    <div id="footer">
        <%@ include file="../inc/footer.jsp" %>
    </div>

</div>

</body>
</html>

내 정보 수정 처리 페이지

내 정보 수정 폼 페이지에서 전달된 정보로 회원정보를 실제로 수정하는 페이지이다.

/users/editAccount_proc.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
/*
회원정보를 수정하는 페이지로 모델 2에서는 삭제해야 할 페이지다.
-구현-
로그인되어 있지 않으면
response.sendError(HttpServletResponse.SC_FORBIDDEN, "Not Login"); return;
회원정보를 수정한 후 다시 로그인하고 비밀번호 변경화면으로 이동한다.
비밀번호 변경 화면에서는 비밀번호 외에 회원정보를 모두 볼 수 있기 때문이다.
*/
response.sendRedirect("changePasswd.jsp");
%>

비밀번호 변경 폼 페이지

비밀번호를 변경하는 페이지를 만든다.
editAccount.jsp 파일을 연 상태에서 Save As... 메뉴를 이용하여 changePasswd.jsp라는 이름의 새 파일을 /users 디렉터리에 만든 후 아래와 같이 수정한다.

/users/changePasswd.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ include file="../inc/loginCheck.jsp" %>
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8" />
<meta name="Keywords" content="비밀번호 변경" />
<meta name="Description" content="비빌번호 변경" />
<title>비밀번호 변경</title>
<link rel="stylesheet" href="../css/screen.css" type="text/css"  />
<script type="text/javascript">
           
function check() {
    var form = document.getElementById("changePasswordForm");
    if (form.newPasswd.value == form.confirm.value) {
        return true;    
    } else {
        alert("[변경 비밀번호]와 [변경 비밀번호 확인] 값이 같지 않습니다.");
        return false;
    }
}

</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" style="min-height: 800px;">

<!-- 본문 시작 -->
<div id="url-navi">회원</div>

<h1>비밀번호 변경</h1>
<%=user.getName() %><br />
이동전화 <%=user.getMobile() %><br />
<form id="changePasswordForm" action="changePasswd_proc.jsp" method="post" onsubmit="return check()">
<table>
<tr>
    <td>현재 비밀번호</td>
    <td><input type="password" name="currentPasswd" /></td>   
</tr>
<tr>
    <td>변경 비밀번호</td>
    <td><input type="password" name="newPasswd" /></td>   
</tr>
<tr>
    <td>변경 비밀번호 확인</td>
    <td><input type="password" name="confirm" /></td> 
</tr>
<tr>
    <td colspan="2"><input type="submit" value="확인" /></td>
</tr>
</table>
</form>
<!--  본문 끝 -->
        </div><!-- content 끝 -->
    </div><!--  container 끝 -->
    
    <div id="sidebar">
        <%@ include file="loginUsers-menu.jsp" %>
    </div>
    
    <div id="extra">
        <%@ include file="../inc/extra.jsp" %>
    </div>

    <div id="footer">
        <%@ include file="../inc/footer.jsp" %>
    </div>

</div>

</body>
</html>

비밀번호 변경 처리 페이지

비밀번호 변경 폼 페이지에서 전달된 비밀번호로 회원 테이블의 비밀번호를 수정하는 페이지이다.

/users/changePasswd_proc.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
/*
비밀번호를 변경하는 페이지로 모델 2에서는 삭제해야 할 페이지다.
-구현-
로그인 사용자가 아니면
response.sendError(HttpServletResponse.SC_FORBIDDEN, "Not Login"); return;
비밀번호 변경 후 비밀번호 변경 확인 페이지로 이동한다.
*/
response.sendRedirect("changePasswd_confirm.jsp");
%>

비밀번호 변경 확인 페이지

비밀번호 변경이 완료되었음을 알려주는 역할만을 담당하는 페이지를 만든다.
비밀번호 변경이 실패했는데 이 페이지가 보여서는 안 된다.
welcome.jsp 파일을 연 상태에서 Save As... 메뉴를 이용하여 changePasswd_confirm.jsp라는 이름의 새 파일을 /users 디렉터리에 만든 후 아래와 같이 수정한다.

/users/changePasswd_confirm.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8" />
<meta name="Keywords" content="비밀번호 변경 확인" />
<meta name="Description" content="비밀번호 변경 확인" />
<title>비밀번호 변경 확인</title>
<link rel="stylesheet" href="../css/screen.css" type="text/css"  />
</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" style="min-height: 800px;">

<!-- 본문 시작 -->
<div id="url-navi">회원</div>

<h1>비밀번호가 변경되었습니다.</h1>
변경된 비밀번호로 다시 로그인하실 수 있습니다.<br />
<input type="button" value="로그인" onclick="javascript:location.href='login.jsp'" />
<!--  본문 끝 -->
        </div><!-- content 끝 -->
    </div><!--  container 끝 -->
    
    <div id="sidebar">
        <%@ include file="loginUsers-menu.jsp" %>
    </div>
    
    <div id="extra">
        <%@ include file="../inc/extra.jsp" %>
    </div>

    <div id="footer">
        <%@ include file="../inc/footer.jsp" %>
    </div>

</div>

</body>
</html>

회원 탈퇴 폼 페이지

회원 탈퇴를 위한 이메일과 비밀번호 폼을 보여주는 페이지를 만든다.
editAccount.jsp 파일을 연 상태에서 Save As... 메뉴를 이용하여 bye.jsp라는 이름의 새 파일을 /users 디렉터리에 만든 후 아래와 같이 수정한다.

/users/bye.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ include file="../inc/loginCheck.jsp" %>
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8" />
<meta name="Keywords" content="탈퇴" />
<meta name="Description" content="탈퇴" />
<title>탈퇴</title>
<link rel="stylesheet" href="../css/screen.css" type="text/css"  />
<script type="text/javascript">
function check() {
    //var form = document.getElementById("byeForm");
    //유효성 검사
    return true;
}
</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" style="min-height: 800px;">

<!-- 본문 시작 -->
<div id="url-navi">회원</div>

<h1>탈퇴</h1>
<form id="byeForm" action="bye_proc.jsp" method="post" onsubmit="return check()">
<table>
<tr>
    <td>이메일</td>
    <td><input type="text" name="email" /></td>   
</tr>
<tr>
    <td>비밀번호</td>
    <td><input type="password" name="passwd" /></td>  
</tr>
<tr>
    <td colspan="2"><input type="submit" value="확인" /></td>
</tr>
</table>
</form>
<!--  본문 끝 -->
        </div><!-- content 끝 -->
    </div><!--  container 끝 -->

    <div id="sidebar">
        <%@ include file="loginUsers-menu.jsp" %>
    </div>

    <div id="extra">
        <%@ include file="../inc/extra.jsp" %>
    </div>

    <div id="footer">
        <%@ include file="../inc/footer.jsp" %>
    </div>

</div>

</body>
</html>

회원 탈퇴 처리 페이지

회원 탈퇴를 처리하는 페이지를 만든다.

/users/bye_proc.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
/*
회원탈퇴를 처리하는 페이지로 모델 2에서는 삭제해야 한다.
-구현-
로그인 사용자가 아니면
response.sendError(HttpServletResponse.SC_FORBIDDEN, "Not Login"); return;
회원테이블에서 회원정보를 지운다.
세션을 지운다.
탈퇴 확인 페이지로 이동한다.
*/
response.sendRedirect("bye_confirm.jsp");
%>

회원 탈퇴 확인 페이지

회원 탈퇴가 완료되었음을 확인시켜주는 페이지를 만든다.
welcome.jsp 파일을 연 상태에서 Save As... 메뉴를 이용하여 bye_confirm.jsp라는 이름의 새 파일을 /users 디렉터리에 만든 후 아래와 같이 수정한다.

/users/bye_confirm.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8" />
<meta name="Keywords" content="탈퇴 확인" />
<meta name="Description" content="탈퇴 확인" />
<title>탈퇴 확인</title>
<link rel="stylesheet" href="../css/screen.css" type="text/css"  />
</head>
<body>

<div id="wrap">

    <div id="header">
        
    </div>

    <div id="main-menu">
        <%@ include file="../inc/main-menu.jsp" %>
    </div>

    <div id="container">
        <div id="content" style="min-height: 800px;">

<!-- 본문 시작 -->
<div id="url-navi">회원</div>

<h1>회원 탈퇴 확인</h1>
회원님의 모든 정보가 삭제되었습니다.<br />
<!--  본문 끝 -->
        </div><!-- content 끝 -->
    </div><!--  container 끝 -->
    
    <div id="sidebar">
        <h1>Goodbye</h1>
    </div>
    
    <div id="extra">
        <%@ include file="../inc/extra.jsp" %>
    </div>

    <div id="footer">
        <%@ include file="../inc/footer.jsp" %>
    </div>

</div>

</body>
</html>

게시판 화면에 해당하는 페이지는 list.jsp, view.jsp, write_form.jsp, modify_form.jsp이다.
이 중에 modify_form.jsp를 제외하고 모두 loginCheck.jsp 파일을 인클루드하는데, modify_form.jsp만 빠진 이유는 로그인뿐 아니라 글 소유자인지 검사하는 로직이 필요하기 때문이다.
(이 로직은 구현 단계로 넘긴다)

회원 페이지 중 editAccount.jsp, changePasswd.jsp, bye.jsp는 loginCheck.jsp 파일을 인클루드한다.

화면을 보여주지 않고 처리만을 담당하는 페이지는 파일명에 _proc를 붙여서 구별했다.

로그인 정책 정리

구현에 앞서 로그인 정책을 다시 확인한다.

  1. 게시판과 관련된 모든 페이지는 로그인이 필요하다.
  2. 회원 모듈에서 내 정보 수정, 비밀번호 변경, 탈퇴는 로그인이 필요하다.
  3. 로그인이 성공하면 /bbs/list.jsp?boardCd=free&curPage=1로 이동한다.
  4. 로그인하지 않고 로그인이 필요한 페이지를 방문하면 로그인 페이지로 이동하고, 로그인이 성공하면 원래 방문하려 했던 페이지로 이동한다.
  5. 로그아웃하면 홈페이지로 이동한다.

이로써 프로토타입을 완성했다.
이 프로토타입은 과정 마지막까지 쓰인다.