Java tutorial
/* Database Programming with JDBC and Java, Second Edition By George Reese ISBN: 1-56592-616-1 Publisher: O'Reilly */ import java.io.IOException; import java.io.PrintWriter; import java.sql.Connection; import java.sql.Date; import java.sql.Driver; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Locale; import java.util.Properties; import java.util.Random; import java.util.StringTokenizer; import javax.servlet.ServletConfig; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class GuestBookServlet extends HttpServlet { private Properties connectionProperties = new Properties(); private Driver driver = null; private String driverName = null; private String jdbcURL = null; private Random random = new Random(); /** * Provides the servlet with the chance to get runtime configuration values * and initialize itself. For a database servlet, you want to grab the * driver name, URL, and any connection information. For this example, I * assume a driver that requires a user name and password. For an example of * more database independent configuration, see Chapter 4. * * @param cfg * the servlet configuration information * @throws javax.servlet.ServletException * could not load the specified JDBC driver */ public void init(ServletConfig cfg) throws ServletException { super.init(cfg); { String user, pw; driverName = cfg.getInitParameter("gb.driver"); jdbcURL = cfg.getInitParameter("gb.jdbcURL"); user = cfg.getInitParameter("gb.user"); if (user != null) { connectionProperties.put("user", user); } pw = cfg.getInitParameter("gb.pw"); if (pw != null) { connectionProperties.put("password", pw); } try { driver = (Driver) Class.forName(driverName).newInstance(); } catch (Exception e) { throw new ServletException("Unable to load driver: " + e.getMessage()); } } } /** * Performs the HTTP GET. This is where we print out a form and a random * sample of the comments. * * @param req * the servlet request information * @param res * the servlet response information * @throws javax.servlet.ServletException * an error occurred talking to the database * @throws java.io.IOException * a socket error occurred */ public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { PrintWriter out = res.getWriter(); Locale loc = getLocale(req); res.setContentType("text/html"); printCommentForm(out, loc); printComments(out, loc); } public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { PrintWriter out = res.getWriter(); Locale loc = getLocale(req); String name, email, comment; Connection conn = null; Exception err = null; int id = -1; String[] tmp; // get the form values tmp = req.getParameterValues("name"); if (tmp == null || tmp.length != 1) { name = null; } else { name = tmp[0]; } tmp = req.getParameterValues("email"); if (tmp == null || tmp.length != 1) { email = null; } else { email = tmp[0]; } tmp = req.getParameterValues("comments"); if (tmp == null || tmp.length != 1) { comment = null; } else { comment = tmp[0]; } res.setContentType("text/html"); // validate values if (name.length() < 1) { out.println("You must specify a valid name!"); printCommentForm(out, loc); return; } if (email.length() < 3) { out.println("You must specify a valid email address!"); printCommentForm(out, loc); return; } if (email.indexOf("@") < 1) { out.println("You must specify a valid email address!"); printCommentForm(out, loc); return; } if (comment.length() < 1) { out.println("You left no comments!"); printCommentForm(out, loc); return; } try { SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd", Locale.US); java.util.Date date = new java.util.Date(); ResultSet result; Statement stmt; conn = DriverManager.getConnection(jdbcURL, connectionProperties); // remove the "setAutoCommit(false)" line for mSQL or MySQL conn.setAutoCommit(false); stmt = conn.createStatement(); // generate a new comment ID // more on ID generation in Chapter 4 result = stmt.executeQuery("SELECT NEXT_SEQ " + "FROM SEQGEN " + "WHERE NAME = 'COMMENT_ID'"); if (!result.next()) { throw new ServletException("Failed to generate id."); } id = result.getInt(1) + 1; stmt.close(); // closing the statement closes the result stmt = conn.createStatement(); stmt.executeUpdate("UPDATE SEQGEN SET NEXT_SEQ = " + id + " WHERE NAME = 'COMMENT_ID'"); stmt.close(); stmt = conn.createStatement(); comment = fixComment(comment); stmt.executeUpdate( "INSERT INTO COMMENT " + "(COMMENT_ID, EMAIL, NAME, COMMENT, " + "CMT_DATE) " + "VALUES (" + id + ", '" + email + "', '" + name + "', '" + comment + "', '" + fmt.format(date) + "')"); conn.commit(); stmt.close(); } catch (SQLException e) { e.printStackTrace(); err = e; } finally { if (conn != null) { try { conn.close(); } catch (Exception e) { } } } if (err != null) { out.println("An error occurred on save: " + err.getMessage()); } else { printCommentForm(out, loc); printComments(out, loc); } } /** * Find the desired locale from the HTTP header. * * @param req * the servlet request from which the header is read * @return the locale matching the first accepted language */ private Locale getLocale(HttpServletRequest req) { String hdr = req.getHeader("Accept-Language"); StringTokenizer toks; if (hdr == null) { return Locale.getDefault(); } toks = new StringTokenizer(hdr, ","); if (toks.hasMoreTokens()) { String lang = toks.nextToken(); int ind = lang.indexOf(';'); Locale loc; if (ind != -1) { lang = lang.substring(0, ind); } lang = lang.trim(); ind = lang.indexOf("-"); if (ind == -1) { loc = new Locale(lang, ""); } else { loc = new Locale(lang.substring(0, ind), lang.substring(ind + 1)); } return loc; } return Locale.getDefault(); } public String getServletInfo() { return "Guest Book Servlet\nFrom Database Programming with JDBC " + "and Java"; } private void printCommentForm(PrintWriter out, Locale loc) throws IOException { out.println("<div class=\"gbform\">"); out.println("<form action=\"personal/guestbook.shtml\" " + "method=\"POST\">"); out.println("<table>"); out.println("<tr>"); out.println("<td>Name:</td>"); out.println("<td><input type=\"text\" name=\"name\" " + "size=\"30\"/></td>"); out.println("<td><input type=\"submit\" value=\"Save\"/></td>"); out.println("</tr>"); out.println("<tr>"); out.println("<td>Email:</td>"); out.println("<td><input type=\"text\" name=\"email\" " + "size=\"30\"/></td>"); out.println("<tr>"); out.println("<tr>"); out.println("<td>Comments:</td>"); out.println("<tr>"); out.println("<tr>"); out.println("<td colspan=\"3\">"); out.println("<textarea name=\"comments\" cols=\"40\" rows=\"7\">"); out.println("</textarea></td>"); out.println("<tr>"); out.println("</table>"); out.println("</form>"); } private void printComments(PrintWriter out, Locale loc) throws IOException { Connection conn = null; try { DateFormat fmt = DateFormat.getDateInstance(DateFormat.FULL, loc); ResultSet results; Statement stmt; int rows, count; conn = DriverManager.getConnection(jdbcURL, connectionProperties); stmt = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); results = stmt.executeQuery("SELECT NAME, EMAIL, CMT_DATE, " + "COMMENT, COMMENT_ID " + "FROM COMMENT " + "ORDER BY CMT_DATE"); out.println("<dl>"); results.last(); results.next(); rows = results.getRow(); // pick a random row rows = random.nextInt() % rows; if (rows < 4) { // if the random row is less than 4, print the first 4 rows results.afterLast(); } else { // otherwise go to the specified row, print the prior 5 rows results.absolute(rows); } count = 0; // print up to 5 rows going backwards from the randomly // selected row while (results.previous() && (count < 5)) { String name, email, cmt; Date date; count++; name = results.getString(1); if (results.wasNull()) { name = "Unknown User"; } email = results.getString(2); if (results.wasNull()) { email = "user@host"; } date = results.getDate(3); if (results.wasNull()) { date = new Date((new java.util.Date()).getTime()); } cmt = results.getString(4); if (results.wasNull()) { cmt = "No comment."; } out.println("<dt><b>" + name + "</b> (" + email + ") on " + fmt.format(date) + "</dt>"); cmt = noXML(cmt); out.println("<dd> " + cmt + "</dd>"); } out.println("</dl>"); } catch (SQLException e) { out.println("A database error occurred: " + e.getMessage()); } finally { if (conn != null) { try { conn.close(); } catch (SQLException e) { } } } } /** * Removes any XML-sensitive characters from a comment and replaces them * with their character entities. * * @param cmt * the raw comment * @return the XML-safe comment */ private String noXML(String cmt) { StringBuffer buff = new StringBuffer(); for (int i = 0; i < cmt.length(); i++) { char c = cmt.charAt(i); switch (c) { case '<': buff.append("<"); break; case '>': buff.append(">"); break; case '&': buff.append("&"); break; case '"': buff.append("""); break; default: buff.append(c); break; } } return buff.toString(); } /** * This method escapes single quotes so that database statements are not * messed up. * * @param comment * the raw comment * @return a comment with any quotes escaped */ private String fixComment(String comment) { if (comment.indexOf("'") != -1) { String tmp = ""; for (int i = 0; i < comment.length(); i++) { char c = comment.charAt(i); if (c == '\'') { tmp = tmp + "\\'"; } else { tmp = tmp + c; } } comment = tmp; } return comment; } }