Java Web Programming with Eclipse contents
Last modified February 15, 2011 05:12 am

back next

Wiki Application (continued)

Video

Edit Page

Overview

In this section you will create and configure the servlet and jsp needed to let users edit wiki pages.

The JSP

Create edit-page.jsp in the jsp folder with the contents of the following listing.

edit-page.jsp

<jsp:useBean id="wikipage" scope="request" type="wiki.data.Page" />

<html>
<head>
   <title>Wiki</title>
   <link rel="stylesheet" type="text/css" href="../styles.css" />

</head>
<body>

<form method="post">
   <input type="submit" name="save-button" value="Save" />

   <input type="submit" name="cancel-button" value="Cancel" />
   <input type="hidden" name="name" value="${wikipage.name}" />

   <input type="hidden" name="published" value="${wikipage.published}" />
   <br />
   <textarea name="content" cols="50" rows="15">${wikipage.content}</textarea>

</form>

</body>
</html>

The first line tells the JSP translator to generate code that retrieves the value of a page obejct that has been associated with the key wikipage in the request object. The form element does not contain an action method, so the browser will submit form data to the same URL that it used to retrieve the form data. The first two input elements in the form are save and cancel buttons. The save button has the attribute name set to save-button and the cancel button has the attribute name set to cancel-button. When the edit page servlet receives a submission from the browser, it will check for the presence of a parameter that has name save-button or cancel-button, and will thus be able to determine which button the user clicked.

The third input element is a hidden element with the page name set as the value of name. Browsers do not display hidden input elements to the user. Hidden input elements are used to carry information that is sent to the server with the rest of the form data. In this case, the hidden element is used to send the name of the page to the edit servlet. This is neccessary because the edit servlet needs to know which page is being updated.

The forth element is also a hidden element. It is used to carry the state of the published attribute. This information is actually not needed at this point, because once the edit servlet has the page name, it can determine the state of the published attribute.

The final input control within the form is a textarea element. This element displays as a multi-line editable text box. The current contents of the given page will be displayed in this text area.

The Edit Page Servlet

The following listing shows the contents of EditPageServlet.java.

EditPageServlet.java

package wiki.web;

import java.io.IOException;

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

import org.apache.log4j.Logger;

import wiki.data.Page;
import wiki.data.PageDAO;

public class EditPageServlet extends HttpServlet {
	private Logger logger = Logger.getLogger(this.getClass());

	private RequestDispatcher jsp;

	public void init(ServletConfig config) throws ServletException {
		ServletContext context = config.getServletContext();
		jsp = context.getRequestDispatcher("/WEB-INF/jsp/edit-page.jsp");
	}

	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		logger.debug("doGet()");
		String pathInfo = req.getPathInfo();
		String name = pathInfo.substring(1);
		logger.debug("Page requested: " + name);
		Page page = new PageDAO().find(name);
		if (page == null) {
			logger.debug("page doesn't exist; creating empty page");
			page = new Page();
			page.setName(name);
			page.setContent("");
			page.setPublished(false);
		}
		req.setAttribute("wikipage", page);
		jsp.forward(req, resp);
	}

	protected void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		logger.debug("doPost()");

		// Extract form data.
		String pageName = req.getParameter("name");
		String content = req.getParameter("content");
		String publishedString = req.getParameter("published");
		Boolean publishedBoolean = Boolean.valueOf(publishedString);
		boolean published = publishedBoolean.booleanValue();

		// Check for cancel button.
		String cancelButton = req.getParameter("cancel-button");
		if (cancelButton != null) {
			resp.sendRedirect("../view/" + pageName);
			return;
		}

		// Prepare a page object.
		PageDAO pageDAO = new PageDAO();
		Page page = new Page();
		page.setName(pageName);
		page.setContent(content);
		page.setPublished(published);

		// Check to see if user is setting page content to nothing (or all
		// spaces).
		if (content.trim().length() == 0) {
			pageDAO.delete(page);
			resp.sendRedirect("../view/" + page.getName());
			return;
		}

		// Create or update page as appropriate.
		if (pageDAO.find(pageName) == null) {
			// Page doesn't exist; insert into database.
			pageDAO.create(page);
		} else {
			// Page exists; update database.
			pageDAO.update(page);
		}
		resp.sendRedirect("../view/" + page.getName());
	}
}

The doGet method of the edit page servlet is identical to the view page servlet. In both servlets, the doGet method must retrieve or create a wiki page object and pass this to its JSP. In the case of the view page servlet, the JSP displays the contents of the wiki page within a div element. In the case of the edit page servlet, the JSP places the contents of the page in an editable text area within a form element. So although the two different JSPs use the wiki page object in different ways, they both need the same object.

The view page and edit page servlets differ in that the edit page servlet implements a doPost method, which the view page servlet does not have. The doPost method of the edit page servlet receives form data from the browser when the user submits changes to the page contents. The first thing the doPost method does is extract references to the form data and stores them in variables.

After extracting the form data, the doPost method checks to see if the cancel button was clicked, in which case the user does not want to save changes to the page. In this case, we return an HTTP redirect message to the browser telling it to request the view page for the page that was in the edit window. We return after sending this message to the browser, because no other work is needed.

If on the other hand the user is not canceling the edit, we need to store changes to the page in the database. We do this by constructing a new page object with the data submitted by the user. If the user is submitting an empty string, or a string of blank characters, then we delete the page from the database. We do this by calling the delete method of the page DAO. Note that we do not need to check to see whether or not the page exists in the database because if the page does not exist, the SQL delete command will have no effect and will not throw an exception.

If the user is submitting non-empty page content, then we need to check to see whether or not the page exists. If the page does not exist, we call the create method of the page DAO, passing in the new page to create. If the page exists, then we call the update method of the page DAO. The create method uses an SQL insert command and the update method uses an SQL update command.

It is possible for one user to delete a page from the database just before another user saves changes to the page. In this case, the update method of the page DAO will throw an exception because it submitted an update command for a row that doesn't exist. Further work would need to be done with the wiki application to handle this problem without displaying an exception to the end user.

Modify Deployment Descriptor

The following XML fragment needs to be added to the deployment descriptor to configure the edit page servlet.

   <servlet>
      <servlet-name>edit-page</servlet-name>
      <servlet-class>wiki.web.EditPageServlet</servlet-class>
   </servlet>
   <servlet-mapping>
      <servlet-name>edit-page</servlet-name>
      <url-pattern>/edit/*</url-pattern>
   </servlet-mapping>

Note that the url pattern is similar to the one used to direct requests to the view page servlet. Although other approaches are possible, we use this one in order to match with the way we route to the view servlet.

Test

Stop and start the wiki application with the manager application. Then test the new functionality by going to http://localhost:8080/wiki/view/ and trying to edit the page. The edit page should look like the following screen shot.

Edit page

Edit page

back next

Copyright 2007-2009 David Turner and Jinseok Chae. All rights reserved.