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

back next

Wiki Application (continued)

Video

Publish Page

Overview

In this section, we create and configure the servlet and jsp needed to let users publish wiki pages to the publisher application. However, we will not actually make a connection to the publisher application until the next chapter. Therefore, the partial implementation that we provide will serve as a placeholder for the complete solution to be implemented in the next chapter after adding a programmatic interface, called a web service, to the publisher application that allows the wiki application to add and remove news items to its news feed.

The JSP

The following list contains the contents of the JSP file that will be used to confirm that the user wishes to publish a given wiki page.

publish-page.jsp

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

<p>
Are you sure you want to publish this page?
</p>

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

The Publish Page Servlet

The implementation of the publish page servlet is shown in the following listing.

PublishPageServlet.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 PublishPageServlet 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/publish-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");

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

	      PageDAO pageDAO = new PageDAO();
	      Page page = pageDAO.find(pageName);
	      
	      // Don't do anything if page doesn't exist or is already published.
	      if (page == null || page.isPublished())
	      {
	         resp.sendRedirect("../view/" + pageName);
	         return;
	      }

	      // Invoke remote web service to publish page.
	      logger.debug("invoking web service");
              try
              {
                  String publishedId = publish(page);
                  page.setPublishedId(publishedId);
	          page.setPublished(true);
              }
              catch (Exception e) 
              {
                  logger.error(e);
                  throw new RuntimeException(e);
              }

	      // Update page.
              pageDAO.update(page);

	      resp.sendRedirect("../view/" + page.getName());
	}

        private String publish(Page page) throws IOException
        {
              return "3";  // Pretend that publish service returned an id of 3.
        }
}

The doGet method of the publish page servlet is requested by the browser when the user clicks on the publish link that appears within the view page. The doGet method as implemented above allows empty pages to be published. For this reason, the method must create an instance of the wiki page class if the find method of the page DAO returns null. The doGet method forwards execution to the publish page JSP, which asks the user to confirm the operation.

In the publish page JSP, the user either clicks the publish button or the cancel button. Regardless of whether the publish or cancel buttons are clicked, the doPost method needs to know which page the user is on. If he or she clicks the cancel button, the doPost method redirects the the user back to the view page. The user can verify that the page is not published by seeing that the publish option is still available for the page.

If the user is confirming the publish operation, the next thing we do is to retrieve an instance of the page from the database. If the page does not exist in the database, it mean the user is publishing an empty page. We do not allow publishing of blank pages, so we redirect the user to the view page. However, the user will see the publish link in the view page, which may implies that page is not published. Additionally, if the page is already published, we do the same thing.

If the page exists in the database, then we invoke the publish web service of the publisher application, which will be implemented in the next chapter. We place all of the logic for this web service invocation in a private method called publish. When we invoke the publish service, we will obtain a news feed id as a result. To prepare for this evetuality, we create a news feed id, called publishedId, and set it to the artificial value 3 for testing purposes. Note that we declare the publish method as throwing an exception to prepare for later code that communicates with the publisher application and thus will be capable of throwing exceptions related to communciation, XML document procesing and other sources of exceptions.

After invoking the publish web service, we need to save the published id with the rest of the page data and we need to set the isPublished property of the wiki page to true. After doing this, we redirect the user to the view page, where he can now see the unpublished link, which is implicit confirmation of the publish operation.

Modify Deployment Descriptor

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

   <servlet>
      <servlet-name>publish-page</servlet-name>
      <servlet-class>wiki.web.PublishPageServlet</servlet-class>
   </servlet>
   <servlet-mapping>
      <servlet-name>publish-page</servlet-name>
      <url-pattern>/publish/*</url-pattern>
   </servlet-mapping>

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 clicking on the publish link. Verify that the publish confirmation page displays correctly as shown in the following screen shot.

Publish page

Publish page

Try canceling the operation and then verifying that the publish link is displayed in the view page. The try the publish link again but this time confirm the publish operation. Verify that the link turns to unpublished as shown in the following screen shot.

Publish menu becomes unpublish

Publish menu becomes unpublish

back next

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