Model 2

Model 1 is a program structure that uses JavaBeans in a JSP. Model 2 is a structure in which a controller is added to Model 1. The controller acts as a bridge between the view (JSP) and the model (JavaBeans) responsible for business logic. The process of Model 2 is summarized as follows.

  1. All requests are received by the controller.
  2. The controller delegates tasks to the model. The model is JavaBean, which is responsible for business logic. When the controller delegates tasks, it passes the request object to the model.
  3. The model completes the task and passes the results to the controller. The model does this by storing the results in the request object.
  4. The controller passes the output to the JSP, which ultimately serves the client's request. The controller uses the forward() method to perform this task.

The following sources provide hints to the controller.

ControllerServlet.java
package net.java_school.board;

import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;

public class ControllerServlet extends HttpServlet {

	public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		doPost(req,resp);
	}

	public void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		String uri = req.getRequestURI();
		String contextPath = req.getContextPath();
		String command = null;
		command = uri.substring(contextPath.length());
		
		PrintWriter out = resp.getWriter();
		out.println(command);
		out.close();
	}
}

Add the following to web.xml:

<servlet>
   <servlet-name>Controller</servlet-name>
   <servlet-class>net.java_school.board.ControllerServlet</servlet-class>
   <load-on-startup>1</load-on-startup>
</servlet>

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

Restart Tomcat. Visit http://localhost:8080/list.do, http://localhost:8080/board/list.do, http://localhost:8080/board/view.do, http://localhost:8080/board/write_form.do, http://localhost:8080/board/modify_form.do. When you visit, the request string will be output. Unlike before, the request string does not imply a specific component of the server. The controller will respond to the user's request by determining the model and view according to the request string.

Create Models

When you create a model class, let the class name end with Action. (This is the naming convention used by the Struts 2 framework) From now on, We will modify the model 1 bulletin board to the model 2 bulletin board. Let's modify it from the list. For the list, the model must do the following: the list item number on the list page, the result set to be displayed on the list page, the page number corresponding to [<], the page number corresponding to [>], the first page number, the last page number. We will call the execute() method of the action class to generate the data mentioned above.(This is also the naming convention used in Struts 2)

ListAction.java
package net.java_school.board;

import javax.servlet.http.HttpServletRequest;

public class ListAction {
	public void execute(HttpServletRequest request) {
		//TODO
	}
}

Complete the execute() method as follows:

ListAction.java
package net.java_school.board;

import java.io.UnsupportedEncodingException;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

public class ListAction {
    public void execute(HttpServletRequest request) throws UnsupportedEncodingException {
        request.setCharacterEncoding("UTF-8");
        
        int curPage = request.getParameter("curPage") == null ? 1 : Integer.parseInt(request.getParameter("curPage"));
        String keyword = request.getParameter("keyword");
        if (keyword == null) keyword = "";

        BoardService service = new BoardService();
        int totalRecord = service.getTotalRecord(keyword);
        Map<String, Integer> numbers = service.getNumbersForPaging(totalRecord, curPage, 10, 5);
        int startRecord = numbers.get("startRecord");
        int endRecord = numbers.get("endRecord");
        
        List<Article> list = service.getBoardList(startRecord, endRecord, keyword);
        
        int listItemNo = numbers.get("listItemNo");
        int prevPage = numbers.get("prevPage");
        int nextPage = numbers.get("nextPage");
        int firstPage = numbers.get("firstPage");
        int lastPage = numbers.get("lastPage");
        
        request.setAttribute("list", list);
        request.setAttribute("listItemNo", listItemNo);
        request.setAttribute("prevPage", prevPage);
        request.setAttribute("nextPage", nextPage);
        request.setAttribute("firstPage", firstPage);
        request.setAttribute("lastPage", lastPage);
    }
}

If you modify the request.setCharacterEncoding ("UTF-8") to be performed by the controller, the ListAction and controller will change as follows:

ListAction.java
package net.java_school.board;

import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

public class ListAction {
    public void execute(HttpServletRequest request) {
        int curPage = request.getParameter("curPage") == null ? 1 : Integer.parseInt(request.getParameter("curPage"));
        String keyword = request.getParameter("keyword");
        if (keyword == null) keyword = "";

        BoardService service = new BoardService();
        int totalRecord = service.getTotalRecord(keyword);
        Map<String, Integer> numbers = service.getNumbersForPaging(totalRecord, curPage, 10, 5);
        int startRecord = numbers.get("startRecord");
        int endRecord = numbers.get("endRecord");
        
        List<Article> list = service.getBoardList(startRecord, endRecord, keyword);
        
        int listItemNo = numbers.get("listItemNo");
        int prevPage = numbers.get("prevPage");
        int nextPage = numbers.get("nextPage");
        int firstPage = numbers.get("firstPage");
        int lastPage = numbers.get("lastPage");
        
        request.setAttribute("list", list);
        request.setAttribute("listItemNo", listItemNo);
        request.setAttribute("prevPage", prevPage);
        request.setAttribute("nextPage", nextPage);
        request.setAttribute("firstPage", firstPage);
        request.setAttribute("lastPage", lastPage);
    }
}
ControllerServlet.java
package net.java_school.board;

import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;

public class ControllerServlet extends HttpServlet {

	public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		doPost(req,resp);
	}

	public void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		req.setCharacterEncoding("UTF-8");
		String uri = req.getRequestURI();
		String contextPath = req.getContextPath();
		String command = null;
		command = uri.substring(contextPath.length());
		
		PrintWriter out = resp.getWriter();
		out.println(command);
		out.close();
	}
}

Let's add code to the control with the list request.

ControllerServlet.java
package net.java_school.board;

import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;

public class ControllerServlet extends HttpServlet {

	public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		doPost(req,resp);
	}

	public void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		req.setCharacterEncoding("UTF-8");
		String uri = req.getRequestURI();
		String contextPath = req.getContextPath();
		String command = null;
		command = uri.substring(contextPath.length());
		
		String view = null; //JSP
		boolean isRedirect = false; //If false, forwarding

		if (command.equals("/board/list.do")) {
			ListAction listAction = new ListAction();
			listAction.execute(req);
			view = "/board/list.jsp";
		}

		if (isRedirect == false) {
			ServletContext sc = this.getServletContext();
			RequestDispatcher rd = sc.getRequestDispatcher(view);
			rd.forward(req, resp);
		} else {
			resp.sendRedirect(view);
		}
		
	}
}

Modify the /board/list.jsp file as shown below.

/board/list.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="net.java_school.board.*" %>
<%@ page import="java.util.*" %>
<%
String curPage = request.getParameter("curPage");
if (curPage == null) curPage = "1";
String keyword = request.getParameter("keyword");
if (keyword == null) keyword = "";
int listItemNo = (Integer) request.getAttribute("listItemNo");
List<Article> list = (List<Article>) request.getAttribute("list");
int prevPage = (Integer) request.getAttribute("prevPage");
int nextPage = (Integer) request.getAttribute("nextPage");
int firstPage = (Integer) request.getAttribute("firstPage");
int lastPage = (Integer) request.getAttribute("lastPage");
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>List</title>
</head>
<body style="font-size: 11px;">
<h1>List</h1>
<%
for (int i = 0; i < list.size(); i++) {
	Article article = list.get(i);
	int indent = article.getIndent();
	for (int j = 0; j < indent; j++) {
		out.println("&nbsp;&nbsp;");
	}
	if(indent != 1) {
		out.println("↳");
	}
%>
<%=listItemNo %>
<a href="view.do?no=<%=article.getNo() %>&curPage=<%=curPage %>&keyword=<%=keyword %>"><%=article.getTitle() %></a>
<%=article.getWdate() %><br />
<hr />
<%
listItemNo--;
}
if (prevPage != 0) {
%>
	<a href="list.do?curPage=<%=prevPage %>&keyword=<%=keyword %>">[<]</a>
<%
}
for (int i = firstPage; i <= lastPage; i++) {
%>
	<a href="list.do?curPage=<%=i %>&keyword=<%=keyword %>">[<%=i %>]</a>
<%
}
if (nextPage != 0) {
%>
	<a href="list.do?curPage=<%=nextPage %>&keyword=<%=keyword %>">[>]</a>
<%
}
%>				
<p>
<a href="write_form.do?curPage=<%=curPage %>&keyword=<%=keyword %>">New</a>
</p>
<form method="get">
	<input type="text" size="10" maxlength="30" name="keyword" />
	<input type="submit" value="Search" />
</form>	
</body>
</html>

Go to http://localhost:8080/board/list.do and test. The list.jsp no longer produces the numbers needed for paging, or does not work with the database. Instead, the list.jsp only receive and display the results produced by the model. But I still do not like the code in the next part of list.jsp.

int listItemNo = (Integer) request.getAttribute("listItemNo");
List<Article> list = (List<Article>) request.getAttribute("list");
int prevPage = (Integer) request.getAttribute("prevPage");
int nextPage = (Integer) request.getAttribute("nextPage");
int firstPage = (Integer) request.getAttribute("firstPage");
int lastPage = (Integer) request.getAttribute("lastPage");

The problem with the above code is that you need to remember names like listItemNo, list, prevPage, nextPage, firstPage, lastPage as well as tricky conversion. So let's use a pattern called Value Object (VO) or Data Transfer Object (DTO) to store the transferred data.

ListVo.java
package net.java_school.board;

import java.util.List;

public class ListVo {	
	private List<Article> list;
	private int totalPage;
	private int listItemNo;
	private int firstPage;
	private int lastPage;
	private int prevPage;
	private int nextPage;
	private int startRecord;
	private int endRecord;
	
	public List<Article> getList() {
		return list;
	}
	public void setList(List<Article> list) {
		this.list = list;
	}
	public int getTotalPage() {
		return totalPage;
	}
	public void setTotalPage(int totalPage) {
		this.totalPage = totalPage;
	}
	public int getListItemNo() {
		return listItemNo;
	}
	public void setListItemNo(int listItemNo) {
		this.listItemNo = listItemNo;
	}
	public int getPrevPage() {
		return prevPage;
	}
	public void setPrevPage(int prevPage) {
		this.prevPage = prevPage;
	}
	public int getFirstPage() {
		return firstPage;
	}
	public void setFirstPage(int firstPage) {
		this.firstPage = firstPage;
	}
	public int getLastPage() {
		return lastPage;
	}
	public void setLastPage(int lastPage) {
		this.lastPage = lastPage;
	}
	public int getNextPage() {
		return nextPage;
	}
	public void setNextPage(int nextPage) {
		this.nextPage = nextPage;
	}
	public int getStartRecord() {
		return startRecord;
	}
	public void setStartRecord(int startRecord) {
		this.startRecord = startRecord;
	}
	public int getEndRecord() {
		return endRecord;
	}
	public void setEndRecord(int endRecord) {
		this.endRecord = endRecord;
	}
	
}

Modify the BoardService to use the VO you just created.

BoardService.java
package net.java_school.board;

import java.util.List;

public class BoardService {

	private BoardDao dao = new BoardDao();

	public BoardService() {}

	public ListVo getNumbersForPaging(int totalRecord, int curPage, int numPerPage, int pagePerBlock) {
		int totalPage = totalRecord / numPerPage;
		if (totalRecord % numPerPage != 0) totalPage++;
		int totalBlock = totalPage / pagePerBlock;
		if (totalPage % pagePerBlock != 0) totalBlock++;

		int block = curPage / pagePerBlock;
		if (curPage % 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 - (curPage - 1) * numPerPage;
		int startRecord = (curPage - 1) * numPerPage + 1;
		int endRecord = curPage * numPerPage;

		ListVo listVo = new ListVo();
		
		listVo.setTotalPage(totalPage);
		listVo.setFirstPage(firstPage);
		listVo.setLastPage(lastPage);
		listVo.setPrevPage(prevPage);
		listVo.setNextPage(nextPage);
		listVo.setListItemNo(listItemNo);
		listVo.setStartRecord(startRecord);
		listVo.setEndRecord(endRecord);

		return listVo;
	}

	public List<Article> getBoardList(int startRecord, int endRecord, String keyword) {
		return dao.getBoardList(startRecord, endRecord, keyword);
	}

	public int getTotalRecord(String keyword) {
		return dao.getTotalRecord(keyword);
	}

	public void write(Article article) {
		dao.insert(article);
	}

	public Article getArticle(int no) {
		return dao.selectOne(no);
	}

	public void modify(Article article) {
		dao.update(article);
	}

	public void delete(int no) {
		dao.delete(no);
	}

	public void reply(Article article) {
		dao.reply(article);
	}	
}
ListAction.java
package net.java_school.board;

import java.util.List;

import javax.servlet.http.HttpServletRequest;

public class ListAction {
	public void execute(HttpServletRequest request) {
		int curPage = request.getParameter("curPage") == null ? 1 : Integer.parseInt(request.getParameter("curPage"));
		String keyword = request.getParameter("keyword");
		if (keyword == null) keyword = "";

		BoardService service = new BoardService();
		int totalRecord = service.getTotalRecord(keyword);
		
		ListVo vo = service.getNumbersForPaging(totalRecord, curPage, 10, 5);
		int startRecord = vo.getStartRecord();
		int endRecord = vo.getEndRecord();

		List<Article> list = service.getBoardList(startRecord, endRecord, keyword);

		vo.setList(list);

		request.setAttribute("listVo", vo);
		
	}
}

Modify the list.jsp file as follows:

list.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="net.java_school.board.*" %>
<%@ page import="java.util.*" %>
<%
String curPage = request.getParameter("curPage");
if (curPage == null) curPage = "1";
String keyword = request.getParameter("keyword");
if (keyword == null) keyword = "";
ListVo vo = (ListVo) request.getAttribute("listVo");
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>List</title>
</head>
<body style="font-size: 11px;">
<h1>List</h1>
<%
int listItemNo = vo.getListItemNo();
List<Article> list = vo.getList();
for (int i = 0; i < list.size(); i++) {
	Article article = list.get(i);
	int indent = article.getIndent();
	for (int j = 0; j < indent; j++) {
		out.println("&nbsp;&nbsp;");
	}
	if(indent != 1) {
		out.println("↳");
	}
%>
<%=listItemNo %>
<a href="view.do?no=<%=article.getNo() %>&curPage=<%=curPage %>&keyword=<%=keyword %>"><%=article.getTitle() %></a>
<%=article.getWdate() %><br />
<hr />
<%
listItemNo--;
}
int prevPage = vo.getPrevPage();
if (prevPage != 0) {
%>
	<a href="list.do?curPage=<%=prevPage %>&keyword=<%=keyword %>">[<]</a>
<%
}
int firstPage = vo.getFirstPage();
int lastPage = vo.getLastPage();
for (int i = firstPage; i <= lastPage; i++) {
%>
	<a href="list.do?curPage=<%=i %>&keyword=<%=keyword %>">[<%=i %>]</a>
<%
}
int nextPage = vo.getNextPage();
if (nextPage != 0) {
%>
	<a href="list.do?curPage=<%=nextPage %>&keyword=<%=keyword %>">[>]</a>
<%
}
%>				
<p>
<a href="write_form.do?curPage=<%=curPage %>&keyword=<%=keyword %>">New</a>
</p>
<form action="list.do" method="post">
	<input type="text" size="10" maxlength="30" name="keyword" />
	<input type="submit" value="Search" />
</form>	
</body>
</html>

More action classes are needed. So when you create an action interface and apply it to an action, the controller's code becomes elegant.

Action.java
package net.java_school.board;

import javax.servlet.http.HttpServletRequest;

public interface Action {
	public void execute(HttpServletRequest request);
}

Modify the ListAction to implement the action interface.

ListAction.java
package net.java_school.board;

import java.util.List;

import javax.servlet.http.HttpServletRequest;

public class ListAction implements Action {
	@Override
	public void execute(HttpServletRequest request) {
	
		//.. The code below is omitted because it is the same as before..
	
	}
}

Modify the controller as follows.

ControllerServlet.java
package net.java_school.board;

import javax.servlet.*;
import javax.servlet.http.*;

import java.io.*;

public class ControllerServlet extends HttpServlet {

	private static final long serialVersionUID = 4024375917229853991L;
	private ServletContext sc;
	
	@Override
	public void init() throws ServletException {
		sc = this.getServletContext();
	}

	@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 = null;
		command = uri.substring(contextPath.length());
		
		String view = null; //JSP
		Action action = null;
		boolean isRedirect = false; //if fasle, forwarding.
		if (command.equals("/board/list.do")) {
			action = new ListAction();
			action.execute(req);
			view = "/board/list.jsp";
		} else if (command.equals("/board/write_form.do")) {
			//TODO 1
		} else if (command.equals("/board/write.do")) {
			//TODO 2
		} else if (command.equals("/board/view.do")) {
			//TODO 3
		} else if (command.equals("/board/modify_form.do")) {
			//TODO 4
		} else if (command.equals("/board/modify.do")) {
			//TODO 5 
		} else if (command.equals("/board/del.do")) {
			//TODO 6
		} else if (command.equals("/board/reply_form.do")) {
			//TODO 7
		} else if (command.equals("/board/reply.do")) {
			//TODO 8
		}
		if (isRedirect == false) {
			RequestDispatcher rd = sc.getRequestDispatcher(view);
			rd.forward(req, resp);
		} else {
			resp.sendRedirect(view);
		}
	}
}

//TODO 1

view = "/board/write_form.jsp";

You can just forward it to write_form.jsp. This is because there is no data to be preprocessed before forwarding to write_form.jsp. Open the write_form.jsp file and change the .jsp in your code to .do. Visit the list and click New to see if you can go to write_form.jsp

//TODO 2

action = new WriteAction();
action.execute(req);
view = "/board/list.do";
isRedirect = true;

WriteAction.java should be created. This model should be responsible for the logic that processes the writing. You can refer to the existing write.jsp file.

WriteAction.java
package net.java_school.board;

import javax.servlet.http.HttpServletRequest;

public class WriteAction implements Action{

	@Override
	public void execute(HttpServletRequest request) {
		String title = request.getParameter("title");
		String content = request.getParameter("content");

		Article article = new Article();
		article.setTitle(title);
		article.setContent(content);
		
		BoardService service= new BoardService();
		service.write(article);
	}

}

Test new posting. If the test succeeds, the write.jsp file is not needed, so delete it.

//TODO 3

action = new ViewAction();
action.execute(req);
view = "/board/view.jsp";

ViewAction should handle the detail view logic.

ViewAction.java
package net.java_school.board;

import javax.servlet.http.HttpServletRequest;

public class ViewAction implements Action {

	@Override
	public void execute(HttpServletRequest request) {
		int no = Integer.parseInt(request.getParameter("no"));
		BoardService service = new BoardService();
		
		Article article = service.getArticle(no);
		
		request.setAttribute("article", article);
	}
}

Now modify view.jsp. The view should be modified to only show the data that the model has preprocessed and delivered. Open the view.jsp file and change the .jsp to .do in your code. Also, refer to the emphasized part and correct it.

view.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="net.java_school.board.*" %>
<%
int no = Integer.parseInt(request.getParameter("no"));
String curPage = request.getParameter("curPage");
String keyword = request.getParameter("keyword");
if (keyword == null) keyword = "";
Article article = (Article) request.getAttribute("article");
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>View</title>
<script type="text/javascript">
function goModify(no,curPage,keyword) {
	location.href="modify_form.do?no=" + no + "&curPage=" + curPage + "&keyword=" + keyword;
}

function goDelete(no,curPage,keyword) {
	var check = confirm("Are you sure you want to delete it?");
	if (check) {
		location.href="del.do?no=" + no + "&curPage=" + curPage + "&keyword=" + keyword;
	}
}
</script>
</head>
<body>
<h1>View</h1>
<h2>Title: <%=article.getTitle() %>, Date created: <%=article.getWdate() %></h2>
<p>
<%=article.getHtmlContent() %>
</p>
<a href="list.do?curPage=<%=curPage %>&keyword=<%=keyword %>">List</a>
<input type="button" value="Edit Post" onclick="javascript:goModify('<%=no %>','<%=curPage %>','<%=keyword %>')">
<input type="button" value="Delete" onclick="javascript:goDelete('<%=no %>','<%=curPage %>','<%=keyword %>')">
<a href="reply_form.do?no=<%=no %>&curPage=<%=curPage %>&keyword=<%=keyword %>">Reply</a>
</body>
</html>

//TODO 4

action = new ModifyFormAction();
action.execute(req);
view = "/board/modify_form.jsp";

Create ModifyFormAction.java as shown below.

ModifyFormAction.java
package net.java_school.board;

import javax.servlet.http.HttpServletRequest;

public class ModifyFormAction implements Action {

	@Override
	public void execute(HttpServletRequest request) {
		int no = Integer.parseInt(request.getParameter("no"));
		BoardService service = new BoardService();
		Article article = service.getArticle(no);
		request.setAttribute("article", article);
	}

}

Open the modify_form.jsp file and change the .jsp to .do in your code. Also, refer to the emphasized part and correct it.

modify_form.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="java.sql.*" %>
<%@ page import="net.java_school.board.*" %>
<%
int no = Integer.parseInt(request.getParameter("no"));
String curPage = request.getParameter("curPage");
String keyword = request.getParameter("keyword");
Article article = (Article) request.getAttribute("article");
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Edit Post</title>
</head>
<body>
<h1>Edit Post</h1>
<form action="modify.do" method="post">
<input type="hidden" name="no" value="<%=no %>">
<input type="hidden" name="curPage" value="<%=curPage %>">
<input type="hidden" name="keyword" value="<%=keyword %>">
<table>
<tr>
	<td>Title</td>
	<td><input type="text" name="title" size="50" value="<%=article.getTitle() %>" /></td>
</tr>
<tr>
	<td colspan="2">
		<textarea name="content" rows="30" cols="100"><%=article.getContent() %></textarea>
	</td>
</tr>
<tr>
	<td colspan="2">
		<input type="submit" value="Submit">
		<input type="reset" value="Reset">
		<a href="view.do?no=<%=no %>&curPage=<%=curPage %>&keyword=<%=keyword %>">View</a>
	</td>
</tr>
</table>
</form>
</body>
</html>
//TODO 5
action = new ModifyAction();
action.execute(req);
String no = req.getParameter("no");
String curPage = req.getParameter("curPage");
String keyword = req.getParameter("keyword");
if (keyword == null) keyword = "";
keyword = java.net.URLEncoder.encode(keyword, "UTF-8");
view = "/board/view.do?no=" + no + "&curPage=" + curPage + "&keyword=" + keyword;
isRedirect = true;

Create ModifyAction.java as follows.

ModifyAction.java
package net.java_school.board;

import javax.servlet.http.HttpServletRequest;

public class ModifyAction implements Action {

	@Override
	public void execute(HttpServletRequest request) {

		int no = Integer.parseInt(request.getParameter("no"));
		String title = request.getParameter("title");
		String content = request.getParameter("content");

		Article article = new Article();
		article.setNo(no);
		article.setTitle(title);
		article.setContent(content);

		BoardService service= new BoardService();
		service.modify(article);
		
	}

}

Test the post modification. If the test succeeds, delete the modify.jsp file so you do not need it.

//TODO 6

action = new DeleteAction();
action.execute(req);
String curPage = req.getParameter("curPage");
String keyword = req.getParameter("keyword");
if (keyword == null) keyword = "";
keyword = java.net.URLEncoder.encode(keyword, "UTF-8");
view = "/board/list.do?curPage=" + curPage + "&keyword=" + keyword;
isRedirect = true;

Create DeleteAction.java as follows.

DeleteAction.java
package net.java_school.board;

import javax.servlet.http.HttpServletRequest;

public class DeleteAction implements Action {

	@Override
	public void execute(HttpServletRequest request) {
		int no = Integer.parseInt(request.getParameter("no"));
		BoardService service= new BoardService();	
		service.delete(no);
	}

}

Test the post deletion. If the test succeeds, delete the del.jsp.

//TODO 7

action = new ReplyFormAction();
action.execute(req);
view = "/board/reply_form.jsp";

Create ReplyFormAction.java as follows.

ReplyFormAction.java
package net.java_school.board;

import javax.servlet.http.HttpServletRequest;

import net.java_school.commons.WebContants;

public class ReplyFormAction implements Action {

	@Override
	public void execute(HttpServletRequest request) {

		int no = Integer.parseInt(request.getParameter("no"));

		BoardService service = new BoardService();
		Article article = service.getArticle(no);    
		String content = article.getContent();

		//Add > for each line of the parent content.
		content = content.replaceAll(WebContants.lineSeparator.value , WebContants.lineSeparator.value + ">");
		content = WebContants.lineSeparator.value + WebContants.lineSeparator.value + ">" + content;

		article.setContent(content);
		request.setAttribute("article", article);
	}

}

Open the reply_form.jsp file and change .jsp to .do in your code. Also, refer to the emphasized part and correct it.

reply_form.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="net.java_school.board.*" %>
<%
int no = Integer.parseInt(request.getParameter("no"));
String curPage = request.getParameter("curPage");
String keyword = request.getParameter("keyword");

Article article = (Article) request.getAttribute("article");
%>
<html>
<head>
</head>
<body>

<h1>Reply</h1>

<form action="reply.do" method="post">
<input type="hidden" name="no" value="<%=no %>" />
<input type="hidden" name="curPage" value="<%=curPage %>" />
<input type="hidden" name="keyword" value="<%=keyword %>" />
Title : <input type="text" name="title" size="45" value="<%=article.getTitle() %>" /><br />
<textarea name="content" rows="10" cols="60"><%=article.getContent() %></textarea><br />
<input type="submit" value="Submit" />
<input type="reset" value="Reset" /><br />
</form>
<a href="view.do?no=<%=no %>&curPage=<%=curPage %>&keyword=<%=keyword %>">View</a>
</body>
</html>

//TODO 8

action = new ReplyAction();
action.execute(req);
String curPage = req.getParameter("curPage");
String keyword = req.getParameter("keyword");
if (keyword == null) keyword = "";
keyword = java.net.URLEncoder.encode(keyword, "UTF-8");
view = "/board/list.do?curPage=" + curPage + "&keyword=" + keyword;
isRedirect = true;

Create ReplyAction.java as follows.

ReplyAction.java
package net.java_school.board;

import javax.servlet.http.HttpServletRequest;

public class ReplyAction implements Action {

	@Override
	public void execute(HttpServletRequest request) {

		int parent = Integer.parseInt(request.getParameter("no"));
		String title = request.getParameter("title");
		String content = request.getParameter("content");

		Article article = new Article();
		article.setParent(parent);
		article.setTitle(title);
		article.setContent(content);

		BoardService service= new BoardService();
		service.reply(article);
	}

}

Test Reply. If the test succeeds, delete reply.jsp.