自《精通Servlets——Java平台的服务器编程》:
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
import java.util.*;
/**
* The BulletinBoard servlet allows the user to view posted
* bulletins as well as add bulletins of their own to be viewed
* by others.
*
* @author Dustin R. Callaway
*/
public class BulletinBoard extends HttpServlet
{
private String filePath;
//stores root path for bulletin files
private Properties propTopics;
//stores bulletin board topics
/**
* init() method is called when the servlet is first loaded. It
* reads the directory where the bulletin files are stored from
* an initialization parameter.
*/
public void init() throws ServletException
{
//get path to topics properties file and bulletin board files
filePath = getInitParameter("FilePath");
if (filePath == null)
{
//default to root directory if no FilePath init parameter
filePath = File.separator;
}
else
if (!filePath.endsWith(File.separator))
{
filePath += File.separator;
//add separator if necessary
}
FileInputStream fileTopics = null;
try
{
//open input stream to topics.properties file
fileTopics = new FileInputStream(filePath +
"topics.properties");
propTopics = new Properties();
propTopics.load(fileTopics);
//load properties object
}
catch (FileNotFoundException e)
{
throw new ServletException("The topics.properties file " +
"was not found at " + filePath + "<BR><BR>Error: " + e);
}
catch (Exception e)
{
throw new ServletException("Error: " + e);
}
finally
{
try
{
fileTopics.close();
//close file input stream
}
catch (Exception ignored) {}
}
}
/**
*do
Get() method is called in response to any GET request.
* Returns an HTML form that allows the user to select a
* bulletin board topic and choose to view bulletins or post
* a new one.
*/
public voiddo
Get(HttpServletRequest request,
HttpServletResponse response) throws IOException
{
response.setContentType("text/html");
//html output
//get a handle to the output stream
PrintWriter out = response.getWriter();
try
{
//create HTML form to allow user to select a topic
out.println("<HTML>");
out.println("<HEAD>");
out.println("<TITLE>Servlet Bulletin Board</TITLE>");
out.println("</HEAD>");
out.println("<BODY>");
out.println("<H2>Servlet Bulletin Board</H2>");
out.println("<BR><FORM METHOD=/"POST/">");
out.println("Select Bulletin Board Topic: ");
out.println("<SELECT NAME=/"Topic/">");
//begin
SELECT tag
String topic;
//stores description of current topic
//create enumeration from properties object
Enumeration enumTopics = propTopics.propertyNames();
//iterate through all topics in topics.properties file
while (enumTopics.hasMoreElements())
{
//set topic variable to current topic in enumeration
topic = (String)enumTopics.nextElement();
//add each topic from properties file to drop-down list
if (propTopics.getProperty(topic).equals(
request.getParameter("Topic")))
{
//if user has selected a topic, keep it selected
out.println("<OPTION SELECTED>" +
propTopics.getProperty(topic) + "</OPTION>");
}
else
{
//not the selected topic, just add to drop-down list
out.println("<OPTION>" +
propTopics.getProperty(topic) + "</OPTION>");
}
}
out.println("</SELECT><BR><BR><BR>");
//end SELECT tag
//display View and Post buttons
out.println("<INPUT TYPE=/"SUBMIT/" NAME=/"VIEW/" " +
"VALUE=/"VIEW BULLETINS/"> ");
out.println("<INPUT TYPE=/"SUBMIT/" NAME=/"POST/" " +
"VALUE=/"POST BULLETIN/">");
out.println("</FORM>");
out.println("</BODY></HTML>");
}
catch (Exception e)
{
sendErrorToClient(out, e);
//send stack trace to client
log("Error indo
Get() method.", e);
//log error
}
finally
{
try
{
//close output stream
out.close();
}
catch (Exception ignored) {}
}
}
/**
*do
Post() method is called in response to any POST request.
* This method determines if it was called in response to the
* user selecting to view bulletins, post a bulletin, or
* save a bulletin and responds accordingly.
*/
public voiddo
Post(HttpServletRequest request,
HttpServletResponse response)
{
PrintWriter out = null;
//get bulletin board topic selected from drop-down list
String currentTopic = request.getParameter("Topic");
//get the name of file containing bulletins for this topic
String file = filePath + currentTopic + ".txt";
//get path to servlet for use in hyperlinks
String servletPath = request.getContextPath() +
request.getServletPath();
response.setContentType("text/html");
//html output
try
{
out = response.getWriter();
//get handle to output stream
//send HTML tags common to show, post, and save pages
out.println("<HTML>");
out.println("<HEAD><TITLE>" + currentTopic +
" Bulletin Board</TITLE></HEAD>");
out.println("<BODY>");
boolean showReturnLink = false;
//display view, post, or save page
if (request.getParameter("VIEW") != null) //view
{
//displays bulletins for the selected topic
viewBulletins(out, file, currentTopic);
showReturnLink = true;
}
else
if (request.getParameter("POST") != null) //post
{
//allows user to enter bulletin and submit it
postBulletin(out, currentTopic);
}
else
if (request.getParameter("SAVE") != null) //save
{
//saves the bulletin to file
saveBulletin(out, file, request);
showReturnLink = true;
}
else
if (request.getParameter("CANCEL") != null) //cancel
{
response.reset();
//clear the response
do
Get(request, response);
//pass request todo
Get()
return;
//stop executing thedo
Post() method
}
else
//error if no view, post, save, or cancel parameter
{
throw new ServletException("Expected Parameter Missing");
}
if (showReturnLink)
{
//create hyperlink to return to main page
out.println("<BR><BR><A HREF=/"" + servletPath +
"?Topic=" + java.net.URLEncoder.encode(currentTopic) +
"/">Return to Main Page</A>");
}
out.println("</BODY></HTML>");
//close BODY and HTML tags
}
catch (Exception e)
{
sendErrorToClient(out, e);
//send stack trace to client
log("Error indo
Post() method.", e);
//log error
}
}
/**
* viewBulletins() method reads bulletins from disk and sends
* them to the client. If filedo
es not exist, client is
* informed that the selected topic contains no bulletins. This
* method is synchronized for thread safety.
*
* @param out Client output stream
* @param file File containing bulletins for selected topic
* @param currentTopic User's currently selected topic
*/
private synchronized void viewBulletins(PrintWriter out,
String file, String currentTopic)
{
FileReader fr = null;
BufferedReader br = null;
try
{
File fileTopic = new File(file);
//get handle to file
//display page heading
out.println("<H2>" + currentTopic +
" Bulletin Board</H2>");
out.println("<H3>View Bulletins</H3>");
if (fileTopic.exists()) //file exists, display it
{
fr = new FileReader(file);
//get file input stream
br = new BufferedReader(fr);
String line = br.readLine();
//read first line
//iterate through each line of the bulletin board file
while (line != null)
{
out.println(line + "<BR>/n");
//send bulletins
line = br.readLine();
//read next line
}
}
else
//filedo
esn't exist, display no bulletins message
{
out.println("This topic currently contains no " +
"bulletins.");
}
}
catch (Exception e)
{
sendErrorToClient(out, e);
//send stack trace to client
log("Error in viewBulletins() method.", e);
//log error
}
finally
{
try
{
br.close();
//close buffered reader
}
catch (Exception ignored) {}
try
{
fr.close();
//close file reader
}
catch (Exception ignored) {}
}
}
/**
* postBulletin() method generates the HTML form that allows
* the user to enter a new bulletin.
*
* @param out Client output stream
* @param currentTopic User's currently selected topic
*/
private void postBulletin(PrintWriter out,
String currentTopic)
{
//create HTML form to allow user to enter new bulletin
out.println("<H2>" + currentTopic + " Bulletin Board</H2>");
out.println("<H3>Post Bulletin</H3><BR>");
out.println("<FORM METHOD=/"POST/">");
out.println("<P><TEXTAREA NAME=/"BULLETIN/" " +
"COLS=/"60/" ROWS=/"5/" WRAP=/"VIRTUAL/"></TEXTAREA>");
out.println("<BR><BR><BR><INPUT TYPE=/"SUBMIT/" " +
"NAME=/"SAVE/" VALUE=/"SAVE BULLETIN/"> ");
out.println("<INPUT TYPE=/"SUBMIT/" " +
"NAME=/"CANCEL/" VALUE=/"CANCEL/">");
//include current topic in hidden field
out.println("<INPUT TYPE=/"HIDDEN/" " +
"NAME=/"Topic/" VALUE=/"" + currentTopic + "/">");
out.println("</FORM>");
}
/**
* saveBulletin() method saves the bulletin to disk. This
* method is synchronized for thread safety.
*
* @param out Client output stream
* @param file File containing bulletins for selected topic
* @param request HttpServletRequest object
*/
private synchronized void saveBulletin(PrintWriter out,
String file, HttpServletRequest request)
{
FileWriter fw=null;
PrintWriter pw=null;
try
{
fw = new FileWriter(file, true);
pw = new PrintWriter(fw);
//get output stream to file
//writer separator to file
pw.println("----------------------------------------");
//write user's bulletin to file
pw.println(request.getParameter("BULLETIN"));
//inform user that the bulletin was saved successfully
out.println("<H2>Bulletin Saved!</H2>");
}
catch (Exception e)
{
sendErrorToClient(out, e);
//send stack trace to client
log("Error in saveBulletin() method.", e);
//log error
}
finally
{
try
{
pw.flush();
//flush output stream to file
pw.close();
//close print writer
}
catch (Exception ignored) {}
try
{
fw.close();
//close file writer
}
catch (Exception ignored) {}
}
}
/**
* Return stack trace to client. Useful for debugging but
* not for use in a production environment.
*
* @param out Client output stream
* @param e Exception
*/
private void sendErrorToClient(PrintWriter out, Exception e)
{
//send stack trace back to client and to standard out
StringWriter stringError = new StringWriter();
PrintWriter printError = new PrintWriter(stringError);
e.printStackTrace(printError);
String stackTrace = stringError.toString();
//send error message to client
out.println("<HTML><TITLE>Error</TITLE><BODY>");
out.println("<H1>Servlet Error</H1><H4>Error</H4>" + e +
"<H4>Stack Trace</H4>" + stackTrace + "</BODY></HTML>");
//print stack trace to standard out
System.out.println("Servlet Error: " + stackTrace);
}
}
//topics.properties文件:
# Bulletin Board servlet topics
Topic1=Java
Topic2=Internet
Topci3=World Wide Web