FileDocCategorySizeDatePackage
GuestBookServlet.javaAPI DocExample14068Tue Aug 22 17:32:44 BST 2000None

GuestBookServlet

public class GuestBookServlet extends HttpServlet

Fields Summary
private Properties
connectionProperties
private Driver
driver
private String
driverName
private String
jdbcURL
private Random
random
Constructors Summary
Methods Summary
public voiddoGet(javax.servlet.http.HttpServletRequest req, javax.servlet.http.HttpServletResponse res)
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

        PrintWriter out = res.getWriter();
        Locale loc = getLocale(req);

        res.setContentType("text/html");
        printCommentForm(out, loc);
        printComments(out, loc);
    
public voiddoPost(javax.servlet.http.HttpServletRequest req, javax.servlet.http.HttpServletResponse res)

        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);
        }
    
private java.lang.StringfixComment(java.lang.String comment)
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

        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;
    
private java.util.LocalegetLocale(javax.servlet.http.HttpServletRequest req)
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

        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 java.lang.StringgetServletInfo()

        return "Guest Book Servlet\nFrom Database Programming with JDBC " +
            "and Java";
    
public voidinit(javax.servlet.ServletConfig cfg)
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

    
                                                                                 
          
        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());
            }
        }
    
private java.lang.StringnoXML(java.lang.String cmt)
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

        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();
    
private voidprintCommentForm(java.io.PrintWriter out, java.util.Locale loc)

        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 voidprintComments(java.io.PrintWriter out, java.util.Locale loc)

        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 ) { }
            }
        }