Model 2

To modify our project with Model 2, you first need to know about EL and JSTL.

EL

EL is an expression made for easy access to data available in JSP. JSP Spec includes EL. EL provides easier access to JavaBean's property values. ${user.email} is equivalent to calling the getEmail() method of the User object. You don't need to know precisely in which scope the User object is. User objects in ${user.email} are retrieved in the following order: pageScope, requestScope, sessionScope, applicationScope.

The following are implicit objects available in EL.

  • pageScope
  • requestScope
  • sessionScope
  • applicationScope
  • param
  • paramValues
  • header
  • headerValues
  • initParam
  • cookie
  • pageContext

You can use an implicit object like ${param.searchWord} to access the value of the searchWord parameter. The ${param.searchWord} prints nothing instead of null, even if there is no searchWord parameter.

In Model 2, views only serve to display the received data. Models generate data. Therefore, you should avoid using scriptlets in Model 2 as much as possible.

JSTL

A tag library is a technique for creating tags that change into Java code. JST Standard Tag Library (JSTL) provides a standard for tag libraries. JSP Spec does not include JSTL. Therefore, you need to download the library to use JSTL. Download and extract the most recent version of JSTL from http://archive.apache.org/dist/jakarta/taglibs/standard/binaries/ and Copy jstl.jar and standard.jar from the lib folder to WEB-INF/lib of out project. The core of JSTL is the most used. To use the core, add the taglib directive to the JSP like below.

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>

Let's test a simple JSTL example. Create the following file on the document base.

/jstl.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="java.util.*" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%
int firstPage = 21;
int lastPage = 30;
ArrayList<Integer> a = new ArrayList<Integer>();
a.add(1);a.add(2);a.add(3);
a.add(4);a.add(5);a.add(6);
a.add(7);a.add(8);a.add(9);a.add(10);
%>
<c:set var="a" value="<%=a %>" />
<c:set var="c" value="" />
<c:set var="firstPage" value="<%=firstPage %>" />
<c:set var="lastPage" value="<%=lastPage %>" />
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>JSTL core examples</title>
</head>
<body>
<h1>if statement</h1>

<c:if test="${empty b }">
  <h4>b list is empty.</h4>
</c:if>

<c:if test="${not empty c }">
  <h4>c is not null and is not "".</h4>
</c:if>

<c:choose>
  <c:when test="${empty a }">
    <h4>List is empty.</h4>
  </c:when>
</c:choose>

<h1>if ~ else statement</h1>
<c:choose>
  <c:when test="${empty a }">
    <h4>List is empty.</h4>
  </c:when>
  <c:otherwise>
    <h4>List is not empty.</h4>
  </c:otherwise>
</c:choose>

<h1>for statement</h1>
<c:forEach var="i" begin="${firstPage }" end="${lastPage }">
  [${i }]
</c:forEach>

<h1>for statement</h1>
<table>
<c:forEach var="i" items="${a }" varStatus="status">
  <tr>
    <td>${status.index }</td><td>${i }</td>
  </tr>
</c:forEach>
</table>
</body>
</html>

The example shows the basics of the JSTL core.

Now you are ready to change the project from Model 1 to Model 2. Significant changes are as follows.

  • All JSPs use EL and JSTL.
  • JSP only shows the received data.
  • Action classes are responsible for business logic.
  • Requests with the extension *.do are sent to the controller.
  • Change the parameter name curPage, which contains the current page number, to page.

Use EL and JSTL to modify JSPs and change all .jsp to .do, except for the jsp used in the include directive.

header.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<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;">
<c:choose>
  <c:when test="${empty user}">
    <input type="button" value="Login" onclick="location.href='/users/login.do'" />
    <input type="button" value="SignUp" onclick="location.href='/users/signUp.do'" />
  </c:when>
  <c:otherwise>
    <input type="button" value="Logout" onclick="location.href='/users/logout.do'" />
    <input type="button" value="Modify Account" onclick="location.href='/users/editAccount.do'" />
  </c:otherwise>
</c:choose>
</div>
bbs-sub.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<h1>BBS</h1>
<ul>
  <li>
    <ul>
      <li><a href="list.do?boardCd=chat&page=1">Small talk</a></li>
      <li><a href="list.do?boardCd=qna&page=1">Q & A</a></li>
    </ul>
  </li>
</ul>

Modify also the main-menu.jsp in the same way.

Delete the loginCheck.jsp file before modifying the list page. We will delegate what the loginCheck.jsp did to an action class.

list.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="Keywords" content="Board list" />
<meta name="Description" content="Board list" />
<title>Small talk</title>
<link rel="stylesheet" href="/css/screen.css" type="text/css"  />
<script>
function goList(page) {
  var form = document.getElementById("listForm");
  form.page.value = page;
  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">
<div id="content-categories">Small talk</div>
<!-- List heading -->
<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>
<!-- List itmes -->
<c:forEach var="article" items="${list }" varStatus="status">
<tr>
  <td style="text-align: center;">${listItemNo - status.index }</td>
  <td>
    <a href="javascript:goView('${article.articeNo }')">${article.title }</a>
    <c:if test="${article.attachFileNum > 0 }">
    <img src="../images/attach.png" alt="Attach File" style="vertical-align: middle;" />
    </c:if>
    <c:if test="${article.commentNum > 0 }">
    <span class="bbs-strong">[${article.commentNum }]</span>
    </c:if>
  </td>
  <td style="text-align: center;">${article.regdate }</td>
  <td style="text-align: center;">${article.hit }</td>
</tr>
</c:forEach>
<!-- List items end -->
</table>
<div id="paging">
  <c:if test="${prevPage > 0 }">
    <a href="javascript:goList('${prevPage }')">[Prev]</a>
  </c:if>
  <c:forEach var="i" begin="${firstPage }" end="${lastPage }">
    <c:choose>
      <c:when test="${param.page == i }">
      <span class="bbs-strong">${i }</span>
      </c:when>
      <c:otherwise>
      <a href="javascript:goList('${i }')">${i }</a>
      </c:otherwise>
    </c:choose>
  </c:forEach>
  <c:if test="${nextPage > 0 }">
    <a href="javascript:goList('${nextPage }')">[Next]</a>
  </c:if>
</div>
<div id="list-menu">
  <input type="button" value="New" onclick="goWrite()" />
</div>
<form action="list.do" method="get">
  <input type="hidden" name="page" value="1" />
  <input type="hidden" name="boardCd" value="${param.boardCd }" />
  <div id="search">
  <input type="text" name="searchWord" size="15" maxlength="30" />
  <input type="submit" value="Search" />
  </div>
</form>

    </div><!-- content end -->
  </div><!-- container end -->
    
  <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.do" method="get">
    <input type="hidden" name="boardCd" value="${param.boardCd }" />
    <input type="hidden" name="page" />
    <input type="hidden" name="searchWord" value="${param.searchWord }" />
  </form>
  <form id="viewForm" action="view.do" method="get">
    <input type="hidden" name="articleNo" />
    <input type="hidden" name="boardCd" value="${param.boardCd }" />
    <input type="hidden" name="page" value="${param.page }" />
    <input type="hidden" name="searchWord" value="${param.searchWord }" />
  </form>
  <form id="writeForm" action="write_form.do" method="get">
    <input type="hidden" name="boardCd" value="${param.boardCd }" />
    <input type="hidden" name="page" value="${param.page }" />
    <input type="hidden" name="searchWord" value="${param.searchWord }" />
  </form>
</div>

</body>
</html>

You need to create an action class building the following data and passing them to the list page.

  • boardNm: Board name
  • list: List of articles
  • listItemNo: List items No
  • prevPage: page number for [Prev]
  • firstPage: first-page number of current block
  • lastPage: last page number of current block
  • nextPage: page number fo [Next]
view.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="Keywords" content="Board detailed view" />
<meta name="Description" content="Board detailed view" />
<title>${boardNm }</title>
<link rel="stylesheet" href="/css/screen.css" type="text/css" />
<script>
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(page) {
  var form = document.getElementById("listForm");
  form.page.value = page;
  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("Are you sure you want to delete it?");
  if (check) {
    var form = document.getElementById("delForm");
    form.submit();
  }
}
function deleteAttachFile(attachFileNo) {
  var check = confirm("Are you sure you want to delete it?");
  if (check) {
    var form = document.getElementById("deleteAttachFileForm");
    form.attachFileNo.value = attachFileNo;
    form.submit();
  }
}
function deleteComment(commentNo) {
  var check = confirm("Are you sure you want to delete it?");
  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">
<!-- content begin -->
<div id="content-categories">${boardNm }</div>
<div class="view-menu" style="margin-top: 15px;margin-bottom: 5px;">
  <c:if test="${user.email == email }">
  <div class="fl">
    <input type="button" value="Modify" onclick="goModify()" />
    <input type="button" value="Del" onclick="goDelete()"/>
  </div>
  </c:if>
  <div class="fr">
    <c:if test="${nextArticle != null }">
    <input type="button" value="Next Article" onclick="goView('${nextArticle.articleNo }')" />
    </c:if>
    <c:if test="${prevArticle != null }">
    <input type="button" value="Prev Article" onclick="goView('${prevArticle.articleNo }')" />
    </c:if>
    <input type="button" value="List" onclick="goList('${param.page }')" />
    <input type="button" value="New" 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;">${title }</th>
</tr> 
</table>
<div id="detail">
  <div id="date-writer-hit">edited ${regdate } by ${name } hit ${hit }</div>
  <div id="article-content">${content }</div>
  <div id="file-list" style="text-align: right">
  <c:forEach var="file" items="${attachFileList }" varStatus="status">
    <div id="attach-file">
      <a href="${uploadPath }${file.filename }">${file.filename }</a>
      <c:if test="${user.email == file.email }">
      <a href="javascript:deleteAttachFile('${file.attachFileNo }')">x</a>
      </c:if>
    </div>
  </c:forEach>
  </p>
</div>
<form id="addCommentForm" action="addComment.do" method="post">
  <input type="hidden" name="articleNo" value="${param.articleNo }"/>
  <input type="hidden" name="boardCd" value="${param.boardCd }" />
  <input type="hidden" name="page" value="${param.page }" />
  <input type="hidden" name="searchWord" value="${param.searchWord }" />       
  <div id="addComment">
    <textarea name="memo" rows="7" cols="50"></textarea>
  </div>
  <div style="text-align: right;">
    <input type="submit" value="Add comment" />
  </div>
</form>
<c:forEach var="comment" items="${commentList }" varStatus="status">
<div class="comments">
  <span class="writer">${comment.name }</span>
  <span class="date">${comment.regdate }</span>
  <c:if test="${user.email == comment.email }">
  <span class="modify-del">
    <a href="javascript:modifyCommentToggle('${comment.commentNo }')">Modify</a>
     | <a href="javascript:deleteComment('${comment.commentNo }')">Del</a>
  </span>
  </c:if>
  <p id="comment${comment.commentNo }">${comment.memo }</p>
  <form id="modifyCommentForm${comment.commentNo }" class="comment-form" action="updateComment.do" method="post" style="display: none;">
  <input type="hidden" name="commentNo" value="${comment.commentNo }" />
  <input type="hidden" name="boardCd" value="${param.boardCd }" />
  <input type="hidden" name="articleNo" value="${param.articleNo }" />
  <input type="hidden" name="page" value="${param.page }" />
  <input type="hidden" name="searchWord" value="${param.searchWord }" />
  <div class="fr">
    <a href="javascript:document.forms.modifyCommentForm${comment.commentNo }.submit()">Submit</a>
    | <a href="javascript:modifyCommentToggle('${comment.commentNo }')">Cancel</a>
  </div>
  <div>
    <textarea class="comment-textarea" name="memo" rows="7" cols="50">${comment.memo }</textarea>
  </div>
  </form>
</div>
</c:forEach>
<div id="next-prev">
  <c:if test="${nextArticle != null }">
  <p>Next Article : <a href="javascript:goView('${nextArticle.articleNo }')">${nextArticle.title }</a></p>
  </c:if>
  <c:if test="${prevArticle != null }">
  <p>Prev Article : <a href="javascript:goView('${prevArticle.articleNo }')">${prevArticle.title }</a></p>
  </c:if>
</div>
<div class="view-menu">
  <c:if test="${user.email == email }">
  <div class="fl">
    <input type="button" value="Modify" onclick="goModify()" />
    <input type="button" value="Del" onclick="goDelete()"/>
  </div>
  </c:if>
  <div class="fr">
    <c:if test="${nextArticle != null }">
    <input type="button" value="Next Article" onclick="goView('${nextArticle.articleNo }')" />
    </c:if>
    <c:if test="${prevArticle != null }">
    <input type="button" value="Prev Article" onclick="goView('${prevArticle.articleNo }')" />
    </c:if>
    <input type="button" value="List" onclick="goList('${param.page }')" />
    <input type="button" value="New" onclick="goWrite()" />
  </div>
</div>
<!-- List -->
<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>
<c:forEach var="article" items="${list }" varStatus="status">
<tr>
  <td style="text-align: center;">
  <c:choose>
    <c:when test="${param.articleNo == article.articleNo }">
    <img src="../images/arrow.gif" alt="You are reading this" />
    </c:when>
    <c:otherwise>
    ${listItemNo - status.index }
    </c:otherwise>
  </c:choose>
  </td>
  <td>
    <a href="javascript:goView('${article.articleNo }')">${article.title }</a>
    <c:if test="${article.attachFileNum > 0 }">
    <img src="/images/attach.png" alt="Attach File" style="vertical-align: middle;" />
    </c:if>
    <c:if test="${article.commentNum > 0 }">
    <span class="bbs-strong">[${article.commentNum }]</span>
    </c:if>
  </td>
  <td style="text-align: center;">${article.regdate }</td>
  <td style="text-align: center;">${article.hit }</td>
</tr>
</c:forEach>
</table>
<div id="paging">
  <c:if test="${prevPage > 0 }">
    <a href="javascript:goList('${prevPage }')">[Prev]</a>
  </c:if>
  <c:forEach var="i" begin="${firstPage }" end="${lastPage }">
    <c:choose>
      <c:when test="${param.page == i }">
        <span class="bbs-strong">${i }</span>
      </c:when>
      <c:otherwise>
        <a href="javascript:goList('${i }')">${i }</a>
      </c:otherwise>
    </c:choose>  
  </c:forEach>
  <c:if test="${nextPage > 0 }">
    <a href="javascript:goList('${nextPage }')">[Next]</a>
  </c:if>
</div>
<div id="list-menu">
  <input type="button" value="New" onclick="goWrite()" />
</div>
<form action="list.do" method="get">
  <input type="hidden" name="page" value="1" />
  <input type="hidden" name="boardCd" value="${param.boardCd }" />
  <div id="search">
    <input type="text" name="searchWord" size="15" maxlength="30" />
    <input type="submit" value="Search" />
  </div>
</form>
<!-- content end -->
    </div><!-- content end -->
  </div><!--  container end -->
    
  <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.do" method="get">
    <input type="hidden" name="boardCd" value="${param.boardCd }" />
    <input type="hidden" name="page" />
    <input type="hidden" name="searchWord" value="${param.searchWord }" />
  </form>
  <form id="viewForm" action="view.do" method="get">
    <input type="hidden" name="articleNo" />
    <input type="hidden" name="boardCd" value="${param.boardCd }" />
    <input type="hidden" name="page" value="${param.page }" />
    <input type="hidden" name="searchWord" value="${param.searchWord }" />
  </form>
  <form id="writeForm" action="write_form.do" method="get">
    <input type="hidden" name="articleNo" value="${param.articleNo }" />
    <input type="hidden" name="boardCd" value="${param.boardCd }" />
    <input type="hidden" name="page" value="${param.page }" />
    <input type="hidden" name="searchWord" value="${param.searchWord }" />
  </form>
  <form id="modifyForm" action="modify_form.do" method="get">
    <input type="hidden" name="articleNo" value="${param.articleNo }" />
    <input type="hidden" name="boardCd" value="${param.boardCd }" />
    <input type="hidden" name="page" value="${param.page }" />
    <input type="hidden" name="searchWord" value="${param.searchWord }" />
  </form>
  <form id="delForm" action="del.do" method="post">
    <input type="hidden" name="articleNo" value="${param.articleNo }" />
    <input type="hidden" name="boardCd" value="${param.boardCd }" />
    <input type="hidden" name="page" value="${param.page }" />
    <input type="hidden" name="searchWord" value="${param.searchWord }" />
  </form>
  <form id="deleteCommentForm" action="deleteComment.do" method="post">
    <input type="hidden" name="commentNo" />
    <input type="hidden" name="articleNo" value="${param.articleNo }" />
    <input type="hidden" name="boardCd" value="${param.boardCd }" />
    <input type="hidden" name="page" value="${param.page }" />
    <input type="hidden" name="searchWord" value="${param.searchWord }" />
  </form>   
  <form id="deleteAttachFileForm" action="deleteAttachFile.do" method="post">
    <input type="hidden" name="attachFileNo" />
    <input type="hidden" name="articleNo" value="${param.articleNo }" />
    <input type="hidden" name="boardCd" value="${param.boardCd }" />
    <input type="hidden" name="page" value="${param.page }" />
    <input type="hidden" name="searchWord" value="${param.searchWord }" />
  </form>       
</div>

</body>
</html>

You need to create an action class building the following data and passing them to the view page.

  • boardNm
  • title
  • regdate
  • name: Owner'name
  • hit: read count
  • content: content of the article
  • attachFileList: List of attachfiles
  • commentList: List of comments
  • nextArticle: Next article object
  • prevArticle: Prev article object
  • -- Below are the same as the list --
  • list
  • listItemNo
  • prevPage
  • firstPage
  • lastPage
  • nextPage

Change the file name of the write_form.jsp to write.jsp and modify it like below.

write.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> 
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="Keywords" content="New article form" />
<meta name="Description" content="New article form" />
<title>${boardNm }</title>
<link rel="stylesheet" href="/css/screen.css" type="text/css" />
<script>
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">
<!-- content begin -->
<div id="content-categories">${boardNm }</div>
<h3>New article</h3>
<form id="writeForm" action="write.do" method="post" enctype="multipart/form-data">
<input type="hidden" name="boardCd" value="${param.boardCd }" />
<table id="write-form" class="bbs-table">
<tr>
  <td>Title</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>Attach File</td>
  <td><input type="file" name="attachFile" /></td>
</tr>
</table>
<div style="text-align: center;padding-bottom: 15px;">
  <input type="submit" value="Submit" />
  <input type="button" value="List" onclick="goList()" />
  <c:if test="${not empty param.articleNo }">
  <input type="button" value="Detailed view" onclick="goView()" />
  </c:if>
</div>
</form>
<!-- content end -->
    </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.do" method="get">
    <input type="hidden" name="articleNo" value="${param.articleNo }" />
    <input type="hidden" name="boardCd" value="${param.boardCd }" />
    <input type="hidden" name="page" value="${param.page }" />
    <input type="hidden" name="searchWord" value="${param.searchWord }" />
  </form>
  <form id="listForm" action="list.do" method="get">
    <input type="hidden" name="boardCd" value="${param.boardCd }" />
    <input type="hidden" name="page" value="${param.page }" />
    <input type="hidden" name="searchWord" value="${param.searchWord }" />
  </form>   
</div>

</body>
</html>

you need to create an action class building the board's name and passing it to the write form page.

Change the name of modify_form.jsp to modify.jsp and modify it like below.

modify.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" %>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="Keywords" content="Modify form page" />
<meta name="Description" content="Modify form page" />
<title>${boardNm }</title>
<link rel="stylesheet" href="/css/screen.css" type="text/css"  />
<script>
function check() {
  //var form = document.getElementById("modifyForm");
  //TODO validaion logic
  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">
<!-- content begin -->
<div id="content-categories">${boardNm }</div>
<h3>Modify</h3>
<form id="modifyForm" action="modify.do" method="post" enctype="multipart/form-data" onsubmit="return check();">
<input type="hidden" name="articleNo" value="${param.articleNo }" />
<input type="hidden" name="boardCd" value="${param.boardCd }" />
<input type="hidden" name="page" value="${param.page }" />
<input type="hidden" name="searchWord" value="${param.searchWord }" />
<table id="write-form" class="bbs-table">
<tr>
  <td>Title</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>Attach File</td>
  <td><input type="file" name="attachFile" /></td>
</tr>
</table>
<div style="text-align: center;padding-bottom: 15px;">
  <input type="submit" value="Submit" />
  <input type="button" value="Detailed view" onclick="goView()" />
</div>
</form>
<!-- content end -->
    </div><!-- content end -->
  </div><!--  container end -->
    
  <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.do" method="get">
    <input type="hidden" name="articleNo" value="${param.articleNo }" />
    <input type="hidden" name="boardCd" value="${param.boardCd }" />
    <input type="hidden" name="page" value="${param.page }" />
    <input type="hidden" name="searchWord" value="${param.searchWord }" />
  </form>
</div>

</body>
</html>

You need to create an action class building the following data and passing them to the modify.jsp.

  • boardNm
  • title
  • content

Let's work with membership-related views.

user-sub.jsp
<h1><Membership</h1>
<ul>
  <c:choose>
    <c:when test="${empty check}">
      <li><a href="/users/login">Login</a></li>
      <li><a href="/users/signUp">SignUp</a></li>
      <li><a href="#">Forgot ID</a></li>
      <li><a href="#">Forgot Password</a></li>
    </c:when>
    <c:otherwise>
      <li><a href="/users/editAccount">Modify Account</a></li>
      <li><a href="/users/changePasswd">Change Password</a></li>
      <li><a href="/users/bye">Bye</a></li>
    </c:otherwise>
  </c:choose>
</ul>
login.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="Keywords" content="Login" />
<meta name="Description" content="Login" />
<title>Login</title>
<link rel="stylesheet" href="/css/screen.css" type="text/css" />
<script>
function check() {
  //var form = document.getElementById("loginForm");
  //TODO validation logic
  return true;
}
</script>           
</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">

<!-- content begin -->
<div id="content-categories">Membership</div>
<h2>Login</h2>
<c:if test="${not empty param.msg }">
<p style="color: red;">Login Failed!</p>
</c:if>      
<form id="loginForm" action="login.do" method="post" onsubmit="return check()">
<p style="margin: 0; padding: 0;">
<input type="hidden" name="url" value="${param.url }" />
</p>
<table>
<tr>
  <td style="width: 200px;">Email</td>
  <td style="width: 390px"><input type="text" name="email" style="width: 99%;" /></td>
</tr>
<tr>
  <td>Password</td>
  <td><input type="password" name="passwd" style="width: 99%;" /></td>
</tr>
</table>
<div style="text-align: center;padding: 15px 0;">
  <input type="submit" value="Submit" />
  <input type="button" value="Sign Up" onclick="location.href='signUp.do'" />
</div>
</form>
<!-- content end -->

    </div><!-- content end -->
  </div><!--  container end -->
    
  <div id="sidebar">
    <%@ include file="user-sub.jsp" %>
  </div>
    
  <div id="extra">
    <%@ include file="../inc/extra.jsp" %>
  </div>

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

</div>

</body>
</html>
signUp.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="Keywords" content="Sign Up" />
<meta name="Description" content="Sign Up" />
<title>Sign Up</title>
<link rel="stylesheet" href="/css/screen.css" type="text/css" />
<script>
function check() {
  //var form = document.getElementById("signUpForm");
  //TODO validation logic
  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">

<!-- content begin -->        
<h3>Sign Up</h3>
<form id="signUpForm" action="signUp.do" 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%;" /></td>
</tr>
<tr>
  <td>Password</td>
  <td><input type="password" name="passwd" style="width: 99%;" /></td>
</tr>
<tr>
  <td colspan="2" style="text-align: center;font-weight: bold;">
  Do not make the password the same as your email account password because Email is used as an ID.
  </td>
</tr>
<tr>
  <td>Confirm</td>
  <td><input type="password" name="confirm" style="width: 99%;" /></td>
</tr>
<tr>
  <td>Email</td>
  <td><input type="text" name="email" style="width: 99%;" /></td>
</tr>
<tr>
  <td>Mobile</td>
  <td><input type="text" name="mobile" style="width: 99%;" /></td>
</tr>
</table>
<div style="text-align: center;padding-bottom: 15px;">
  <input type="submit" value="Submit" />
</div>
</form>
<!-- content end -->

    </div><!-- content end -->
  </div><!--  container end -->
    
  <div id="sidebar">
    <%@ include file="user-sub.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
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="Keywords" content="Welcome" />
<meta name="Description" content="Welcome" />
<title>Welcome</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">

<!-- content begin -->        
<h3>Welcome</h3>
<p>
The email you entered at registration will be used as an ID.<br />
<input type="button" value="Login" onclick="javascript:location.href='login.do'" />
</p>
<!-- content end -->

    </div><!-- content end -->
  </div><!--  container end -->
    
  <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>
editAccount.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="Keywords" content="Modify account" />
<meta name="Description" content="Modify account" />
<title>Modify account</title>
<link rel="stylesheet" href="/css/screen.css" type="text/css"  />
<script>
function check() {
  //var form = document.getElementById("editAccountForm");
  //TODO validation logic
  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">

<!-- content begin -->        
<h3>Modify account</h3>
<p>
You can edit your account information except your password. <a href="changePasswd.do">Change password</a>
</p>
<form id="editAccountForm" action="editAccount.do" method="post" onsubmit="return check()">
<table>
<tr>
  <td>Full Name</td>
  <td><input type="text" name="name" value="${user.name }" /></td>
</tr>
<tr>
  <td>Mobile</td>
  <td><input type="text" name="mobile" value="${user.mobile }" /></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>
<!-- content end -->

    </div><!-- content end -->
  </div><!--  container end -->
    
  <div id="sidebar">
    <%@ include file="user-sub.jsp" %>
  </div>
    
  <div id="extra">
    <%@ include file="../inc/extra.jsp" %>
  </div>

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

</div>

</body>
</html>
changePasswd.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="Keywords" content="Change password" />
<meta name="Description" content="Change password" />
<title>Change password</title>
<link rel="stylesheet" href="/css/screen.css" type="text/css"  />
<script>
function check() {
  var form = document.getElementById("changePasswordForm");
  if (form.newPasswd.value == form.confirm.value) {
    return true;    
  } else {
    alert("[Change Password] and [Change Password Confirm] values are not the same.");
    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">

<!-- content begin -->        
<h3>Change password</h3>
<p>
${user.name }<br />
${user.mobile }<br />
</p>
<form id="changePasswordForm" action="changePasswd.do" method="post" onsubmit="return check()">
<table>
<tr>
  <td>Current Password</td>
  <td><input type="password" name="currentPasswd" /></td>   
</tr>
<tr>
  <td>Change password</td>
  <td><input type="password" name="newPasswd" /></td>
</tr>
<tr>
  <td>Change password confirm</td>
  <td><input type="password" name="confirm" /></td>
</tr>
<tr>
  <td colspan="2"><input type="submit" value="Submit" /></td>
</tr>
</table>
</form>
<!-- content end -->

    </div><!-- content end -->
  </div><!--  container end -->

  <div id="sidebar">
    <%@ include file="user-sub.jsp" %>
  </div>

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

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

</div>

</body>
</html>
changePasswd_confirm.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="Keywords" content="Password change confirm" />
<meta name="Description" content="Password change confirm" />
<title>Password change confirm</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">

<!-- content begin -->        
<h3>Password Changed.</h3>
<p>
You can login with the changed password.<br />
<input type="button" value="Login" onclick="javascript:location.href='login.do'" />
</p>
<!-- content end -->

    </div>
  </div><!--  container end -->
    
  <div id="sidebar">
    <%@ include file="user-sub.jsp" %>
  </div>
    
  <div id="extra">
    <%@ include file="../inc/extra.jsp" %>
  </div>

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

</div>

</body>
</html>
bye.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="Keywords" content="Bye" />
<meta name="Description" content="Bye" />
<title>Bye</title>
<link rel="stylesheet" href="/css/screen.css" type="text/css" />
<script>
function check() {
  //var form = document.getElementById("byeForm");
  //TODO validation logic
  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">

<!-- content begin -->
<div id="content-categories">Membership</div>
<h3>Bye</h3>
<form id="byeForm" action="bye.do" method="post" onsubmit="return check()">
<table>
<tr>
  <td>Email</td>
  <td><input type="text" name="email" /></td>   
</tr>
<tr>
  <td>Password</td>
  <td><input type="password" name="passwd" /></td>  
</tr>
<tr>
  <td colspan="2"><input type="submit" value="Submit" /></td>
</tr>
</table>
</form>
<!-- content end -->

    </div>
  </div><!--  container end -->

  <div id="sidebar">
    <%@ include file="user-sub.jsp" %>
  </div>

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

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

</div>

</body>
</html>

error.jsp

This single error page covers the main errors. For easy implementation, this page does not use JSTL.

/error.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="net.java_school.user.User" %>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="Keywords" content="Error" />
<meta name="Description" content="Error" />
<title>Error</title>
<link rel="stylesheet" href="/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">
    <%@ include file="./inc/header.jsp" %>
  </div>

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

  <div id="container">
    <div id="content">

<!--  content begin -->
<div id="content-categories">Error</div>
<h3>Error Page</h3>
<%
if (statusCode != null && 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>");
}
%>
<!-- content end -->

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

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

</div>

</body>
</html>

Don't forget to edit the homepage as well.

Implementation

ActionForward is the return type of the execute() method of the action class. ActionForward object stores only the address to forward or redirect. If the ActionForward object's redirect property is false, forwarding works. Action classes are responsible for making addresses, storing them in ActionForward, and setting the redirect flag of ActionForward.

ActionForward.java
package net.java_school.action;

public class ActionForward {
  private boolean isRedirect;
  private String view;
    
  public boolean isRedirect() {
    return isRedirect;
  }
  public void setRedirect(boolean isRedirect) {
    this.isRedirect = isRedirect;
  }
  public String getView() {
    return view;
  }
  public void setView(String view) {
    this.view = view;
  }
}

All action classes must implement the Action interface.

Action.java
package net.java_school.action;

import java.io.IOException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public interface Action {
  public ActionForward execute(HttpServletRequest req, HttpServletResponse resp) throws IOException;
}

The below is a custom exception class to use when authentication fails. It inherits runtime exceptions.

AuthenticationException.java
package net.java_school.exception;

public class AuthenticationException extends RuntimeException {

  public AuthenticationException() {
    super();
  }

  public AuthenticationException(String message, Throwable cause,
        boolean enableSuppression, boolean writableStackTrace) {
    super(message, cause, enableSuppression, writableStackTrace);
  }

  public AuthenticationException(String message, Throwable cause) {
    super(message, cause);
  }

  public AuthenticationException(String message) {
    super(message);
  }

  public AuthenticationException(Throwable cause) {
    super(cause);
  }
    
}

Our controller handles * .do requests.

Controller.java
package net.java_school.controller;

import java.io.IOException;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.java_school.action.Action;
import net.java_school.action.ActionForward;
import net.java_school.exception.AuthenticationException;

public class Controller extends HttpServlet {

  @Override
  public void doGet(HttpServletRequest req, HttpServletResponse resp)
        throws ServletException, IOException {
    doPost(req,resp);
  }
    
  @Override
  public void doPost(HttpServletRequest req, HttpServletResponse resp) 
        throws ServletException, IOException {
            
    req.setCharacterEncoding("UTF-8");
       
    String uri = req.getRequestURI();
    String contextPath = req.getContextPath();
    String command = uri.substring(contextPath.length());
        
    String view = null;
    Action action = null;
    ActionForward forward = null;
        
    try {
      if (command.equals("/bbs/list.do") && req.getMethod().equals("GET")) {
        //action = new ListAction();
        forward = action.execute(req, resp);
      } else if (command.equals("/bbs/view.do") && req.getMethod().equals("GET")) {
        //action = new ViewAction();
        forward = action.execute(req, resp);
      } else if (command.equals("/bbs/write.do") && req.getMethod().equals("GET")) {
        //action = new WriteFormAction();
        forward = action.execute(req, resp);
      } else if (command.equals("/bbs/write.do") && req.getMethod().equals("POST")) {
        //action = new WriteAction();
        forward = action.execute(req, resp);
      } else if (command.equals("/bbs/addComment.do") && req.getMethod().equals("POST")) {
        //action = new AddCommentAction();
        forward = action.execute(req, resp);
      } else if (command.equals("/bbs/updateComment.do") && req.getMethod().equals("POST")) {
        //action = new UpdateCommentAction();
        forward = action.execute(req, resp);
      } else if (command.equals("/bbs/deleteComment.do") && req.getMethod().equals("POST")) {
        //action = new DeleteCommentAction();
        forward = action.execute(req, resp);
      } else if (command.equals("/bbs/deleteAttachFile.do") && req.getMethod().equals("POST")) {
        //action = new DeleteAttachFileAction();
        forward = action.execute(req, resp);                
      } else if (command.equals("/bbs/modify.do") && req.getMethod().equals("GET")) {
        //action = new ModifyFormAction();
        forward = action.execute(req, resp);
      } else if (command.equals("/bbs/modify.do") && req.getMethod().equals("POST")) {
        //action = new ModifyAction();
        forward = action.execute(req, resp);
      } else if (command.equals("/bbs/del.do") && req.getMethod().equals("POST")) {
        //action = new DeleteAction();
        forward = action.execute(req, resp);
      } else if (command.equals("/users/changePasswd.do") && req.getMethod().equals("GET")) {
        //action = new ChangePasswdFormAction();
        forward = action.execute(req, resp);
      } else if (command.equals("/users/changePasswd.do") && req.getMethod().equals("POST")) {
        //action = new ChangePasswdAction();
        forward = action.execute(req, resp);
      } else if (command.equals("/users/changePasswd_confirm.do") && req.getMethod().equals("GET")) {
        forward = new ActionForward();
        forward.setView("/users/changePasswd_confirm.jsp");             
      } else if (command.equals("/users/signUp.do") && req.getMethod().equals("GET")) {
        forward = new ActionForward();
        forward.setView("/users/signUp.jsp");
      } else if (command.equals("/users/signUp.do") && req.getMethod().equals("POST")) {
        //action = new SignUpAction();
        forward = action.execute(req, resp);
      } else if (command.equals("/users/welcome.do") && req.getMethod().equals("GET")) {
        forward = new ActionForward();
        forward.setView("/users/welcome.jsp");              
      } else if (command.equals("/users/editAccount.do") && req.getMethod().equals("GET")) {
        //action = new EditAccountFormAction();
        forward = action.execute(req, resp);
      } else if (command.equals("/users/editAccount.do") && req.getMethod().equals("POST")) {
        //action = new EditAccountAction();
        forward = action.execute(req, resp);
      } else if (command.equals("/users/bye.do") && req.getMethod().equals("GET")) {
        //action = new ByeFormAction();
        forward = action.execute(req, resp);
      } else if (command.equals("/users/bye.do") && req.getMethod().equals("POST")) {
        //action = new ByeAction();
        forward = action.execute(req, resp);
      } else if (command.equals("/users/login.do") && req.getMethod().equals("GET")) {
        forward = new ActionForward();
        forward.setView("/users/login.jsp");
      } else if (command.equals("/users/login.do") && req.getMethod().equals("POST")) {
        //action = new LoginAction();
        forward = action.execute(req, resp);
      } else if (command.equals("/users/logout.do") && req.getMethod().equals("POST")) {
        //action = new LogoutAction();
        forward = action.execute(req, resp);
      }
            
      view = forward.getView();
            
      if (forward.isRedirect() == false) {
        RequestDispatcher rd = this.getServletContext().getRequestDispatcher(view);
        rd.forward(req, resp);
      } else {
        resp.sendRedirect(view);
      }
    } catch (AuthenticationException e) {
      //If an authentication failure exception is passed to the controller, the controller passes an error message to the container.
      resp.sendError(HttpServletResponse.SC_FORBIDDEN, e.getMessage());
    }
  }
}

Declare the controller servlet in web.xml and map it to the specific pattern URL.

web.xml
<servlet>
  <servlet-name>controller</servlet-name>
  <servlet-class>net.java_school.controller.Controller</servlet-class>
  <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
  <servlet-name>controller</servlet-name>
  <url-pattern>*.do</url-pattern>
</servlet-mapping>

Add Line Separator to the WebContants.java.

WebContants.java
package net.java_school.commons;

public class WebContants {
  //Session key
  public final static String USER_KEY = "user";
  //Error Message
  public final static String NOT_LOGIN = "Not Login";
  public final static String AUTHENTICATION_FAILED = "Authentication Failed";
  //Line Separator
  public final static String LINE_SEPARATOR = System.getProperty("line.separator");
}

Since we have established a policy that only logged-in users can use the bulletin board, we will implement login, our top priority. Refer to Model 1's implementation of login_proc.jsp to create an action class to handle logins. This class works when a login.do POST request comes in. If login fails, go back to the login page.

LoginAction.java
package net.java_school.user.action;

import java.io.IOException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import net.java_school.action.Action;
import net.java_school.action.ActionForward;
import net.java_school.commons.WebContants;
import net.java_school.user.User;
import net.java_school.user.UserService;

public class LoginAction implements Action {

  @Override
  public ActionForward execute(HttpServletRequest req, 
      HttpServletResponse resp) throws IOException {
        
    String url = req.getParameter("url");
        
    String email = req.getParameter("email");
    String passwd = req.getParameter("passwd");

    UserService service = new UserService();
    User user = service.login(email, passwd);

    ActionForward forward = new ActionForward();
         
    if (user == null) {
      forward.setView("/users/login.do?url=" + url +"&msg=Login-Failed");
      forward.setRedirect(true);
    } else {
      HttpSession session = req.getSession();
      session.setAttribute(WebContants.USER_KEY, user);
      if (url != null && !url.equals("")) {
        forward.setView(url);
        forward.setRedirect(true);
      } else {
        forward.setView("/bbs/list.do?boardCd=chat&page=1");
        forward.setRedirect(true);
      }
    }
    return forward;
  }
}

You have to obtain the address for redirecting and the address for fowarding differently. Addresses for forwarding use addresses starting with "/" excluding the context path. Addresses for redirecting uses an address beginning with the context path or uses a relative path based on the page's location that sends the redirect URL. Since our project is a root application, it is the same whether we add a context path to the address we want to redirect to or not.

LogoutAction.java
package net.java_school.user.action;

import java.io.IOException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import net.java_school.action.Action;
import net.java_school.action.ActionForward;
import net.java_school.commons.WebContants;

public class LogoutAction implements Action {

  @Override
  public ActionForward execute(HttpServletRequest req,
        HttpServletResponse resp) throws IOException {
            
    ActionForward forward = new ActionForward();
                
    HttpSession session = req.getSession();
    session.removeAttribute(WebContants.USER_KEY);

    String contextPath = req.getContextPath();
    forward.setView("/");//go to homepage
    forward.setRedirect(true);

    return forward;
  }
}

SignUpAction handles subscription.

SignUpAction.java
package net.java_school.user.action;

import java.io.IOException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.java_school.action.Action;
import net.java_school.action.ActionForward;
import net.java_school.user.User;
import net.java_school.user.UserService;

public class SignUpAction implements Action {

  @Override
  public ActionForward execute(HttpServletRequest req,
        HttpServletResponse resp) throws IOException {

    ActionForward forward = new ActionForward();

    String email = req.getParameter("email");
    String passwd = req.getParameter("passwd");
    String name = req.getParameter("name");
    String mobile = req.getParameter("mobile");

    User user = new User(email, passwd, name, mobile);

    UserService service = new UserService();
    service.addUser(user);

    forward.setView("welcome.do");
    forward.setRedirect(true);

    return forward;
  }
}

EditAccountFormAction's logic runs when the /users/editAccount.do request is passed to the controller by clicking the Edit My Info button.

EditAccountFormAction.java
package net.java_school.user.action;

import java.io.IOException;
import java.net.URLEncoder;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import net.java_school.action.Action;
import net.java_school.action.ActionForward;
import net.java_school.commons.WebContants;
import net.java_school.user.User;

public class EditAccountFormAction implements Action {

  @Override
  public ActionForward execute(HttpServletRequest req,
        HttpServletResponse resp) throws IOException {

    ActionForward forward = new ActionForward();

    HttpSession session = req.getSession();
    User user = (User) session.getAttribute(WebContants.USER_KEY);

    //Same as loginCheck.jsp logic.
    if (user == null) {
      String url = req.getRequestURI();
      String query = req.getQueryString();
      if (query != null) url += "?" + query;
      url = URLEncoder.encode(url, "UTF-8");
      forward.setRedirect(true);
      forward.setView("/users/login.do?url=" + url);

      return forward;
    }

    forward.setView("/users/editAccount.jsp");

    return forward;
  }
}

EditAccountAction's logic acts on the /users/editAccount.do POST request to edit the user's information.

EditAccountAction.java
package net.java_school.user.action;

import java.io.IOException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import net.java_school.action.Action;
import net.java_school.action.ActionForward;
import net.java_school.commons.WebContants;
import net.java_school.exception.AuthenticationException;
import net.java_school.user.User;
import net.java_school.user.UserService;

public class EditAccountAction implements Action {

  @Override
  public ActionForward execute(HttpServletRequest req,
        HttpServletResponse resp) throws IOException {
            
    ActionForward forward = new ActionForward();
        
    HttpSession session = req.getSession();
    User user = (User) session.getAttribute(WebContants.USER_KEY);

    String name = req.getParameter("name");
    String mobile = req.getParameter("mobile");
    String passwd = req.getParameter("passwd");
        
    if (user == null) {
      throw new AuthenticationException(WebContants.NOT_LOGIN);
    }
        
    String email = user.getEmail();
        
    UserService service = new UserService();
        
    //user.setEmail(email);
    user.setPasswd(passwd);
    user.setName(name);
    user.setMobile(mobile);
        
    int check = service.editAccount(user);
        
    if (check > 0) {
      session.setAttribute(WebContants.USER_KEY, user);
      forward.setView("changePasswd.do");
      forward.setRedirect(true);
    } else {
      throw new AuthenticationException(WebContants.AUTHENTICATION_FAILED);
    }
        
    return forward;
  }
}

ChangePasswdFormAction's logic acts on the /users/changePasswd.do request.

ChangePasswdFormAction.java
package net.java_school.user.action;

import java.io.IOException;
import java.net.URLEncoder;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import net.java_school.action.Action;
import net.java_school.action.ActionForward;
import net.java_school.commons.WebContants;
import net.java_school.user.User;

public class ChangePasswdFormAction implements Action {
    
  @Override
  public ActionForward execute(HttpServletRequest req, 
        HttpServletResponse resp) throws IOException {
        
    ActionForward forward = new ActionForward();
        
    HttpSession session = req.getSession();
    User user = (User) session.getAttribute(WebContants.USER_KEY);
        
    if (user == null) {
      String url = req.getRequestURI();
      String query = req.getQueryString();
      if (query != null) url += "?" + query;
      url = URLEncoder.encode(url, "UTF-8");
      forward.setView("/users/login.do?url=" + url);
      forward.setRedirect(true);
            
      return forward;
    }

    forward.setView("/users/changePasswd.jsp");
        
    return forward;
  }
}

ChangePasswdAction works on the /users/changePasswd.do POST request.

ChangePasswdAction.java
package net.java_school.user.action;

import java.io.IOException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import net.java_school.action.Action;
import net.java_school.action.ActionForward;
import net.java_school.commons.WebContants;
import net.java_school.exception.AuthenticationException;
import net.java_school.user.User;
import net.java_school.user.UserService;

public class ChangePasswdAction implements Action {
    
  @Override
  public ActionForward execute(HttpServletRequest req,
        HttpServletResponse resp) throws IOException {
       
    ActionForward forward = new ActionForward();
        
    HttpSession session = req.getSession();
    User user = (User) session.getAttribute(WebContants.USER_KEY);
        
    if (user == null) {
      throw new AuthenticationException(WebContants.NOT_LOGIN);
    }

    String currentPasswd = req.getParameter("currentPasswd");
    String newPasswd = req.getParameter("newPasswd");
    String email = user.getEmail();

    UserService service = new UserService();
    int check = service.changePasswd(currentPasswd, newPasswd, email);
                
    if (check < 1) {
      throw new AuthenticationException(WebContants.AUTHENTICATION_FAILED);
    }
        
    forward.setView("changePasswd_confirm.do");
    forward.setRedirect(true);
        
    return forward;
  }
}

ByeFormAction works on the /users/bye.do GET request.

ByeFormAction.java
package net.java_school.user.action;

import java.io.IOException;
import java.net.URLEncoder;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import net.java_school.action.Action;
import net.java_school.action.ActionForward;
import net.java_school.user.User;

public class ByeFormAction implements Action {

  @Override
  public ActionForward execute(HttpServletRequest req,
        HttpServletResponse resp) throws IOException {

    ActionForward forward = new ActionForward();

    HttpSession session = req.getSession();
    User user = (User) session.getAttribute(WebContants.USER_KEY);
        
    if (user == null) {
      String url = req.getRequestURI();
      String query = req.getQueryString();
      if (query != null) url += "?" + query;
      url = URLEncoder.encode(url, "UTF-8");
      forward.setView("/users/login.do?url=" + url);
      forward.setRedirect(true);
 
      return forward;
    }

    forward.setView("/users/bye.jsp");
        
    return forward;
  }
}

ByeAction works on the /users/bye.do POST request.

ByeAction.java
package net.java_school.user.action;

import java.io.IOException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import net.java_school.action.Action;
import net.java_school.action.ActionForward;
import net.java_school.commons.WebContants;
import net.java_school.exception.AuthenticationException;
import net.java_school.user.User;
import net.java_school.user.UserService;

public class ByeAction implements Action {

  @Override
  public ActionForward execute(HttpServletRequest req,
        HttpServletResponse resp) throws IOException {

    ActionForward forward = new ActionForward();
        
    HttpSession session = req.getSession();
    User user = (User) session.getAttribute(WebContants.USER_KEY);

    if (user == null) {
      throw new AuthenticationException(WebContants.NOT_LOGIN); 
    }

    String email = req.getParameter("email");
    String passwd = req.getParameter("passwd");

    UserService service = new UserService();

    service.bye(email, passwd);
    session.removeAttribute(WebContants.USER_KEY);

    forward.setView("/users/bye_confirm.jsp");
        
    return forward;
  }
}

ListAction works on the /bbs/list.do GET request.

ListAction.java
package net.java_school.board.action;

import java.io.IOException;
import java.net.URLEncoder;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import net.java_school.action.Action;
import net.java_school.action.ActionForward;
import net.java_school.board.Article;
import net.java_school.board.BoardService;
import net.java_school.commons.WebContants;
import net.java_school.user.User;

public class ListAction implements Action {
  public NumbersForPaging getNumbersForPaging(int totalRecord, int page, int numPerPage, int pagePerBlock) {
    int totalPage = totalRecord / numPerPage;
    if (totalRecord % numPerPage != 0) totalPage++;
    int totalBlock = totalPage / pagePerBlock;
    if (totalPage % pagePerBlock != 0) totalBlock++;
    int block = page / pagePerBlock;
    if (page % pagePerBlock != 0) block++;
    int firstPage = (block - 1) * pagePerBlock + 1;
    int lastPage = block * pagePerBlock;
    int prevPage = 0;
    if (block > 1) {
      prevPage = firstPage - 1;
    }
    int nextPage = 0;
    if (block < totalBlock) {
      nextPage = lastPage + 1;
    }
    if (block >= totalBlock) {
      lastPage = totalPage;
    }
    int listItemNo = totalRecord - (page - 1) * numPerPage;
        
    NumbersForPaging numbers = new NumbersForPaging();
        
    numbers.setTotalPage(totalPage);
    numbers.setFirstPage(firstPage);
    numbers.setLastPage(lastPage);
    numbers.setPrevBlock(prevPage);
    numbers.setNextBlock(nextPage);
    numbers.setListItemNo(listItemNo);
        
    return numbers;
  }    
  @Override
  public ActionForward execute(HttpServletRequest req, HttpServletResponse resp) throws IOException {

    ActionForward forward = new ActionForward();
        
    HttpSession session = req.getSession();
    User user = (User) session.getAttribute(WebContants.USER_KEY);
        
    if (user == null) {
      String url = req.getRequestURI();
      String query = req.getQueryString();
      if (query != null) url += "?" + query;
      url = URLEncoder.encode(url, "UTF-8");
      forward.setView("/users/login.do?url=" + url);
      forward.setRedirect(true);
            
      return forward;
    }
        
    String boardCd = req.getParameter("boardCd");
    int page = Integer.parseInt(req.getParameter("page"));
    String searchWord = req.getParameter("searchWord");
        
    BoardService service = new BoardService();
           
    int numPerPage = 10;
    int pagePerBlock = 10;
                 
    int totalRecord = service.getTotalRecord(boardCd, searchWord);
        
    int startRecord = (page - 1) * numPerPage + 1;
    int endRecord = page * numPerPage;
        
    List<Article> list = service.getArticleList(boardCd, searchWord, startRecord, endRecord);
        
    NumbersForPaging numbers = this.getNumbersForPaging(totalRecord, page, numPerPage, pagePerBlock);
        
    String boardNm = service.getBoardNm(boardCd);
        
    req.setAttribute("list", list);
    req.setAttribute("listItemNo", numbers.getListItemNo());
    req.setAttribute("prevPage", numbers.getPrevPage());
    req.setAttribute("firstPage", numbers.getFirstPage());
    req.setAttribute("lastPage", numbers.getLastPage());
    req.setAttribute("nextPage", numbers.getNextPage());
    req.setAttribute("boardNm", boardNm);
        
    forward.setView("/bbs/list.jsp");
        
    return forward;
  }
}

ViewAction works on the /bbs/view.do GET request.

ViewAction.java
package net.java_school.board.action;

import java.io.IOException;
import java.net.URLEncoder;
import java.util.List;
import java.util.Date;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import net.java_school.action.Action;
import net.java_school.action.ActionForward;
import net.java_school.board.Article;
import net.java_school.board.AttachFile;
import net.java_school.board.BoardService;
import net.java_school.board.Comment;
import net.java_school.commons.NumbersForPaging;
import net.java_school.commons.WebContants;
import net.java_school.user.User;

public class ViewAction implements Action {
  public NumbersForPaging getNumbersForPaging(int totalRecord, int page, int numPerPage, int pagePerBlock) {
    int totalPage = totalRecord / numPerPage;
    if (totalRecord % numPerPage != 0) totalPage++;
    int totalBlock = totalPage / pagePerBlock;
    if (totalPage % pagePerBlock != 0) totalBlock++;
    int block = page / pagePerBlock;
    if (page % pagePerBlock != 0) block++;
    int firstPage = (block - 1) * pagePerBlock + 1;
    int lastPage = block * pagePerBlock;
    int prevPage = 0;
    if (block > 1) {
      prevPage = firstPage - 1;
    }
    int nextPage = 0;
    if (block < totalBlock) {
      nextPage = lastPage + 1;
    }
    if (block >= totalBlock) {
      lastPage = totalPage;
    }
    int listItemNo = totalRecord - (page - 1) * numPerPage;
        
    NumbersForPaging numbers = new NumbersForPaging();
        
    numbers.setTotalPage(totalPage);
    numbers.setFirstPage(firstPage);
    numbers.setLastPage(lastPage);
    numbers.setPrevBlock(prevPage);
    numbers.setNextBlock(nextPage);
    numbers.setListItemNo(listItemNo);
        
    return numbers;
  }    

  @Override
  public ActionForward execute(HttpServletRequest req, 
        HttpServletResponse resp) throws IOException {

    ActionForward forward = new ActionForward();
        
    HttpSession session = req.getSession();
    User user = (User) session.getAttribute(WebContants.USER_KEY);
        
    if (user == null) {
      String url = req.getRequestURI();
      String query = req.getQueryString();
      if (query != null) url += "?" + query;
      url = URLEncoder.encode(url, "UTF-8");
      forward.setView("/users/login.do?url=" + url);
      forward.setRedirect(true);
                        
      return forward;
    }

    int articleNo = Integer.parseInt(req.getParameter("articleNo"));
    String boardCd = req.getParameter("boardCd");
    int page = Integer.parseInt(req.getParameter("page"));
    String searchWord = req.getParameter("searchWord");

    BoardService service = new BoardService();
        
    service.increaseHit(articleNo);

    int numPerPage = 10;
    int pagePerBlock = 10;
        
    int startRecord = (page - 1) * numPerPage + 1;
    int endRecord = page * numPerPage;        
        
    Article article = 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> list = service.getArticleList(boardCd, searchWord, startRecord, endRecord);
    List<Comment> commentList = service.getCommentList(articleNo);
    String boardNm = service.getBoardNm(boardCd);

    String title = article.getTitle();
    String content = article.getContent();
    content = content.replaceAll(WebContants.LINE_SEPARATOR, "<br />");
    int hit = article.getHit();
    String name = article.getName();
    String email = article.getEmail();
    Date regdate = article.getRegdate();
    String contextPath = req.getContextPath();
    String uploadPath = contextPath + "/upload/";

    int totalRecord = service.getTotalRecord(boardCd, searchWord);
    NumbersForPaging numbers = this.getNumbersForPaging(totalRecord, page, numPerPage, pagePerBlock);
        
    req.setAttribute("title", title);
    req.setAttribute("content", content);
    req.setAttribute("hit", hit);
    req.setAttribute("name", name);
    req.setAttribute("email", email);
    req.setAttribute("regdate", regdate);
    req.setAttribute("uploadPath", uploadPath);
    req.setAttribute("attachFileList", attachFileList);
    req.setAttribute("nextArticle", nextArticle);
    req.setAttribute("prevArticle", prevArticle);
    req.setAttribute("commentList", commentList);
        
    req.setAttribute("list", list);
    req.setAttribute("listItemNo", numbers.getListItemNo());
    req.setAttribute("prevPage", numbers.getPrevPage());
    req.setAttribute("firstPage", numbers.getFirstPage());
    req.setAttribute("lastPage", numbers.getLastPage());
    req.setAttribute("nextPage", numbers.getNextPage());
    req.setAttribute("boardNm", boardNm);
        
    forward.setView("/bbs/view.jsp");
        
    return forward;
  }
}

WriteFormAction works on the /bbs/write.do GET request.

WriteFormAction.java
package net.java_school.board.action;

import java.io.IOException;
import java.net.URLEncoder;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import net.java_school.action.Action;
import net.java_school.action.ActionForward;
import net.java_school.board.BoardService;
import net.java_school.user.User;

public class WriteFormAction implements Action {
    
  @Override
  public ActionForward execute(HttpServletRequest req, 
        HttpServletResponse resp) throws IOException {

    ActionForward forward = new ActionForward();
        
    HttpSession session = req.getSession();
    User user = (User) session.getAttribute(WebContants.USER_KEY);
        
    if (user == null) {
      String url = req.getRequestURI();
      String query = req.getQueryString();
      if (query != null) url += "?" + query;
      url = URLEncoder.encode(url, "UTF-8");
      forward.setView("/users/login.do?url=" + url);
      forward.setRedirect(true);
            
      return forward;
    }

    String boardCd = req.getParameter("boardCd");

    BoardService service = new BoardService();
    String boardNm = service.getBoardNm(boardCd);
        
    req.setAttribute("boardNm", boardNm);
        
    forward.setView("/bbs/write.jsp");
        
    return forward;
  }
}

WriteAction works on the /bbs/write.do POST request.

WriteAction.java
package net.java_school.board.action;

import java.io.File;
import java.io.IOException;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import com.oreilly.servlet.MultipartRequest;
import com.oreilly.servlet.multipart.DefaultFileRenamePolicy;

import net.java_school.action.Action;
import net.java_school.action.ActionForward;
import net.java_school.board.Article;
import net.java_school.board.AttachFile;
import net.java_school.board.BoardService;
import net.java_school.commons.WebContants;
import net.java_school.exception.AuthenticationException;
import net.java_school.user.User;

public class WriteAction implements Action {
    
  @Override
  public ActionForward execute(HttpServletRequest req, 
        HttpServletResponse resp) throws IOException {

    ActionForward forward = new ActionForward();
        
    HttpSession session = req.getSession();
    User user = (User) session.getAttribute(WebContants.USER_KEY);
        
    if (user == null) {
      throw new AuthenticationException(WebContants.NOT_LOGIN);
    }
        
    ServletContext servletContext = req.getServletContext();
    String dir = servletContext.getRealPath("/upload");

    MultipartRequest multi = new MultipartRequest(
          req,
          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);
        
    forward.setView("list.do?boardCd=" + boardCd + "&page=1");
    forward.setRedirect(true);
        
    return forward;
  }
}

ModifyFormAction works on the /bbs/modify.do GET request.

ModifyFormAction.java
package net.java_school.board.action;

import java.io.IOException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import net.java_school.action.Action;
import net.java_school.action.ActionForward;
import net.java_school.board.Article;
import net.java_school.board.BoardService;
import net.java_school.commons.WebContants;
import net.java_school.exception.AuthenticationException;
import net.java_school.user.User;

public class ModifyFormAction implements Action {
    
  @Override
  public ActionForward execute(HttpServletRequest req, 
        HttpServletResponse resp) throws IOException {

    ActionForward forward = new ActionForward();
        
    int articleNo = Integer.parseInt(req.getParameter("articleNo"));
    String boardCd = req.getParameter("boardCd");

    HttpSession session = req.getSession();
    User user = (User) session.getAttribute(WebContants.USER_KEY);

    BoardService service = new BoardService();
    Article article = service.getArticle(articleNo);

    if (user == null || !user.getEmail().equals(article.getEmail())) {
      throw new AuthenticationException(WebContants.AUTHENTICATION_FAILED);
    }

    String title = article.getTitle();
    String content = article.getContent();
    String boardNm = service.getBoardNm(boardCd);

    req.setAttribute("title", title);
    req.setAttribute("content", content);
    req.setAttribute("boardNm", boardNm);
        
    forward.setView("/bbs/modify.jsp");
        
    return forward;
  }
}

ModifyAction works on the /bbs/modify.do POST request.

ModifyAction.java
package net.java_school.board.action;

import java.io.File;
import java.io.IOException;
import java.net.URLEncoder;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import com.oreilly.servlet.MultipartRequest;
import com.oreilly.servlet.multipart.DefaultFileRenamePolicy;

import net.java_school.action.Action;
import net.java_school.action.ActionForward;
import net.java_school.board.Article;
import net.java_school.board.AttachFile;
import net.java_school.board.BoardService;
import net.java_school.commons.WebContants;
import net.java_school.exception.AuthenticationException;
import net.java_school.user.User;

public class ModifyAction implements Action {
    
  @Override
  public ActionForward execute(HttpServletRequest req, 
        HttpServletResponse resp) throws IOException {

    ActionForward forward = new ActionForward();
        
    HttpSession session = req.getSession();
    User user = (User) session.getAttribute(WebContants.USER_KEY);

    ServletContext servletContext = req.getServletContext();
    String dir = servletContext.getRealPath("/upload");

    MultipartRequest multi = new MultipartRequest(
          req,
          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())) {
      throw new AuthenticationException(WebContants.AUTHENTICATION_FAILED);
    }

    String boardCd = multi.getParameter("boardCd");
    int page = Integer.parseInt(multi.getParameter("page"));
    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);

    forward.setView("view.do?articleNo="+ articleNo + "&boardCd=" + boardCd + "&page=" + page + "&searchWord=" + searchWord);
    forward.setRedirect(true);
        
    return forward;
  }
}

DeleteAction works on the /bbs/del.do POST request.

DeleteAction.java
package net.java_school.board.action;

import java.io.IOException;
import java.net.URLEncoder;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import net.java_school.action.Action;
import net.java_school.action.ActionForward;
import net.java_school.board.Article;
import net.java_school.board.BoardService;
import net.java_school.commons.WebContants;
import net.java_school.exception.AuthenticationException;
import net.java_school.user.User;

public class DeleteAction implements Action {
    
  @Override
  public ActionForward execute(HttpServletRequest req, 
        HttpServletResponse resp) throws IOException {

    ActionForward forward = new ActionForward();
        
    HttpSession session = req.getSession();
    User user = (User) session.getAttribute(WebContants.USER_KEY);

    int articleNo = Integer.parseInt(req.getParameter("articleNo"));

    BoardService service = new BoardService();
    Article article = service.getArticle(articleNo);
        
    if (user == null || !user.getEmail().equals(article.getEmail())) {
      throw new AuthenticationException(WebContants.AUTHENTICATION_FAILED);
    }

    service.removeArticle(articleNo);

    String boardCd = req.getParameter("boardCd");
    String page = req.getParameter("page");
    String searchWord = req.getParameter("searchWord");

    searchWord = URLEncoder.encode(searchWord, "UTF-8");
       
    forward.setView("list.do?boardCd=" + boardCd + "&page=" + page + "&searchWord=" + searchWord);
    forward.setRedirect(true);
        
    return forward;
  }
}

AddCommentAction works on the /bbs/addComment.do POST request.

AddCommentAction.java
package net.java_school.board.action;

import java.io.IOException;
import java.net.URLEncoder;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import net.java_school.action.Action;
import net.java_school.action.ActionForward;
import net.java_school.board.BoardService;
import net.java_school.board.Comment;
import net.java_school.commons.WebContants;
import net.java_school.exception.AuthenticationException;
import net.java_school.user.User;

public class AddCommentAction implements Action {
    
  @Override
  public ActionForward execute(HttpServletRequest req, 
        HttpServletResponse resp) throws IOException {

    ActionForward forward = new ActionForward();
        
    HttpSession session = req.getSession();
    User user = (User) session.getAttribute(WebContants.USER_KEY);
        
    if (user == null) {
      throw new AuthenticationException(WebContants.NOT_LOGIN);
    }

    int articleNo = Integer.parseInt(req.getParameter("articleNo"));
    String boardCd = req.getParameter("boardCd");
    int page = Integer.parseInt(req.getParameter("page"));
    String searchWord = req.getParameter("searchWord");
    String memo = req.getParameter("memo");

    Comment comment = new Comment();
    comment.setArticleNo(articleNo);
    comment.setEmail(user.getEmail());
    comment.setMemo(memo);

    BoardService service = new BoardService();
    service.addComment(comment);

    searchWord = URLEncoder.encode(searchWord, "UTF-8");
    forward.setView("view.do?articleNo=" + articleNo + "&boardCd=" + boardCd + "&page=" + page + "&searchWord=" + searchWord);
    forward.setRedirect(true);
        
    return forward;
  }
}

UpdateCommentAction works on the /bbs/updateComment.do POST request.

UpdateCommentAction.java
package net.java_school.board.action;

import java.io.IOException;
import java.net.URLEncoder;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import net.java_school.action.Action;
import net.java_school.action.ActionForward;
import net.java_school.board.BoardService;
import net.java_school.board.Comment;
import net.java_school.commons.WebContants;
import net.java_school.exception.AuthenticationException;
import net.java_school.user.User;

public class UpdateCommentAction implements Action {

  @Override
  public ActionForward execute(HttpServletRequest req,
        HttpServletResponse resp) throws IOException {

    ActionForward forward = new ActionForward();
        
    HttpSession session = req.getSession();
    User user = (User) session.getAttribute(WebContants.USER_KEY);

    int commentNo = Integer.parseInt(req.getParameter("commentNo"));

    BoardService service = new BoardService();
    Comment comment = service.getComment(commentNo);
        
    if (user == null || !user.getEmail().equals(comment.getEmail())) {
      throw new AuthenticationException(WebContants.AUTHENTICATION_FAILED);
    }

    int articleNo = Integer.parseInt(req.getParameter("articleNo"));
    String boardCd = req.getParameter("boardCd");
    int page = Integer.parseInt(req.getParameter("page"));
    String searchWord = req.getParameter("searchWord");

    String memo = req.getParameter("memo");

    comment.setCommentNo(commentNo);
    comment.setArticleNo(articleNo);
    comment.setEmail(user.getEmail());
    comment.setMemo(memo);

    service.modifyComment(comment);

    searchWord = URLEncoder.encode(searchWord, "UTF-8");
        
    forward.setView("view.do?articleNo="+ articleNo + "&boardCd=" + boardCd + "&page=" + page + "&searchWord=" + searchWord);
    forward.setRedirect(true);
        
    return forward;
  }
}

DeleteCommentAction works on the /bbs/deleteComment.do POST request.

DeleteCommentAction.java
package net.java_school.board.action;

import java.io.IOException;
import java.net.URLEncoder;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import net.java_school.action.Action;
import net.java_school.action.ActionForward;
import net.java_school.board.BoardService;
import net.java_school.board.Comment;
import net.java_school.commons.WebContants;
import net.java_school.exception.AuthenticationException;
import net.java_school.user.User;

public class DeleteCommentAction implements Action {
    
  @Override
  public ActionForward execute(HttpServletRequest req, 
        HttpServletResponse resp) throws IOException {

    ActionForward forward = new ActionForward();
                
    HttpSession session = req.getSession();
    User user = (User) session.getAttribute(WebContants.USER_KEY);

    int commentNo = Integer.parseInt(req.getParameter("commentNo"));

    BoardService service = new BoardService();
    Comment comment = service.getComment(commentNo);
    if (user == null || !user.getEmail().equals(comment.getEmail())) {
      throw new AuthenticationException(WebContants.AUTHENTICATION_FAILED);
    }

    int articleNo = Integer.parseInt(req.getParameter("articleNo"));
    String boardCd = req.getParameter("boardCd");
    int page = Integer.parseInt(req.getParameter("page"));
    String searchWord = req.getParameter("searchWord");

    service.removeComment(commentNo);

    searchWord = URLEncoder.encode(searchWord, "UTF-8");
    forward.setView("view.do?articleNo=" + articleNo + "&boardCd=" + boardCd + "&page=" + page + "&searchWord=" + searchWord);
    forward.setRedirect(true);
        
    return forward;
  }
}

DeleteAttachFileAction works on the /bbs/deleteAttachFile.do POST request.

DeleteAttachFileAction.java
package net.java_school.board.action;

import java.io.IOException;
import java.net.URLEncoder;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import net.java_school.action.Action;
import net.java_school.action.ActionForward;
import net.java_school.board.AttachFile;
import net.java_school.board.BoardService;
import net.java_school.commons.WebContants;
import net.java_school.exception.AuthenticationException;
import net.java_school.user.User;

public class DeleteAttachFileAction implements Action {

  @Override
  public ActionForward execute(HttpServletRequest req,
        HttpServletResponse resp) throws IOException {

    ActionForward forward = new ActionForward();
        
    HttpSession session = req.getSession();
    User user = (User) session.getAttribute(WebContants.USER_KEY);

    int attachFileNo = Integer.parseInt(req.getParameter("attachFileNo"));

    BoardService service = new BoardService();
    AttachFile attachFile = service.getAttachFile(attachFileNo);
        
    if (user == null || !user.getEmail().equals(attachFile.getEmail())) {
      throw new AuthenticationException(WebContants.AUTHENTICATION_FAILED);
    }

    int articleNo = Integer.parseInt(req.getParameter("articleNo"));
    String boardCd = req.getParameter("boardCd");
    int page = Integer.parseInt(req.getParameter("page"));
    String searchWord = req.getParameter("searchWord");

    service.removeAttachFile(attachFileNo);

    searchWord = URLEncoder.encode(searchWord, "UTF-8");
        
    forward.setView("view.do?articleNo=" + articleNo + "&boardCd=" + boardCd + "&page=" + page + "&searchWord=" + searchWord);
    forward.setRedirect(true);
        
    return forward;
  }
}

Model 2 Features

Model 2 consists of model, view, and controller.

  • All requests go to the controller.
  • The controller delegates tasks to the model.
  • The model performs the business logic and passes the results to the view.

Business logic is the logic that processes data required for business. Models are responsible for business logic. Views display the data that models generate, and the controller passes. Views in web applications are JSPs.

Business logic needs to be detached from views and implemented in models. If a view has business logic, it's not good code.

Final Source: https://github.com/kimjonghoon/model2