The organization of servlets is a subject of some discussion among those of us who think about this kind of thing. One camp says that it is fine to place business logic in servlets, and the other says that the servlet itself should be reserved for communication purposes. There are distinct advantages to the second point of view. Simplicity The communication and housekeeping portions of a servlet are complex enough without adding business logic to them. Object Orientation Using classes to encapsulate functionality is the basic tenet of OO. All the benefits normally associated with OO flow from it. Debugging It is far simpler to debug an ordinary Java Class than it is to debug a servlet. Single-step debuggers are much easier to set up when ordinary classes are involved. A main() method can be written that instantiates the class in a similar way to the servlet in production. To illustrate the OO approach to servlets, we will modify the PassParam class that you were introduced to earlier in this chapter. Listing 21.12 shows this new class. Listing 21.12 The PassParam2 Class /* * PassParam2.java * * Created on June 21, 2002, 5:25 PM */ import javax.servlet.*; import javax.servlet.http.*; import com.samspublishing.jpp.ch21; /** * * @author Stephen Potts * @version */ public class PassParam2 extends HttpServlet { /** Initializes the servlet. */ public void init(ServletConfig config) throws ServletException { super.init(config); } /** Destroys the servlet. */ public void destroy() { } /** Processes requests for both HTTP <code>GET</code> * and <code>POST</code> methods. * @param request servlet request * @param response servlet response */ protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, java.io.IOException { response.setContentType("text/html"); java.io.PrintWriter out = response.getWriter(); System.out.println("Creating the HTMLBuilder"); HTMLBuilder hb = new HTMLBuilder(); String htmlOutput = hb.formatResponse(request); out.println(htmlOutput); System.out.println("Response was formatted by HTMLBuilder"); out.close(); } /** Handles the HTTP <code>GET</code> method. * @param request servlet request * @param response servlet response */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, java.io.IOException { processRequest(request, response); } /** Handles the HTTP <code>POST</code> method. * @param request servlet request * @param response servlet response */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, java.io.IOException { processRequest(request, response); } /** Returns a short description of the servlet. */ public String getServletInfo() { return "Short description"; } } Compiling this class can be tricky. This class is not part of a package (except the default package), so it can be compiled in any directory that has visibility to the HTMLBuiler class. HTMLBuilder, which this class calls, is in the com.samspublishing.jpp.ch21 package, so move the PassParam2.java file to the directory just above the com/samspublishing/jpp/ch21 class and compile it there. If you placed this chapter's code in C:\com\samspublishing\jpp\ch21, you would move to the c:\ directory to compile it. This class is identical to the PassParam class except for the contents of processRequest(). In this version, processRequest() does only servlet-type work, delegating the actual layout work to the HTMLBuilder class, which we will examine next. An instance of HTMLBuilder is created, and its formatResponse() method is called with the HttpServletRequest object passed in as a parameter. It returns a String object, which we print to the PrintWriter object. protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, java.io.IOException { response.setContentType("text/html"); java.io.PrintWriter out = response.getWriter(); System.out.println("Creating the HTMLBuilder"); HTMLBuilder hb = new HTMLBuilder(); String htmlOutput = hb.formatResponse(request); out.println(htmlOutput); System.out.println("Response was formatted by HTMLBuilder"); out.close(); } Several println() statements were added to this class. These statements appear in the Tomcat console when the servlet runs. This is a primitive, but effective, technique for debugging servlets. The real work has now been delegated to the HTMLBuilder class, which is shown in Listing 21.13. /* * HTMLBuilder.java * * Created on June 25, 2002, 9:55 AM */ package com.samspublishing.jpp.ch21; import javax.servlet.*; import javax.servlet.http.*; /** * * @author Stephen Potts * @version */ public class HTMLBuilder { /** Creates new HTMLBuilder */ public HTMLBuilder() { } public String formatResponse(HttpServletRequest request) throws ServletException, java.io.IOException { System.out.println("Entered into HTMLBuilder.formatResponse()"); StringBuffer sb = new StringBuffer(); // output your page here sb.append("<html>\n"); sb.append("<head>\n"); sb.append("<title>" + "HTML Formatting" + "</title>\n"); sb.append("</head>\n"); sb.append("<body BGCOLOR=\"#FDF5E6\"\n>\n"); sb.append("<h1 ALIGN=CENTER>\n"); sb.append("Here are the Parameter2"); sb.append("</h1>\n"); sb.append("<B>The UserName2 is </B>\n"); sb.append(request.getParameter("UserName") + "<BR>\n"); sb.append(" "); sb.append("<B>The UserAge2 is </B>\n"); sb.append(request.getParameter("UserAge") + "<BR>\n"); sb.append(" "); sb.append("<B>The UserSport2 is </B>\n"); sb.append(request.getParameter("UserSport") + "<BR>\n"); sb.append(" "); sb.append("</body>\n"); sb.append("</html>\n"); System.out.println("Returning from HTMLBuilder.formatResponse()"); return sb.toString(); } } This class is created in a package. This will impact its deployment in the Tomcat directory structure. In Java, the package name and the class name form the real name of the program or servlet. The directory structure must match the package name, according to the rules of Java. package com.samspublishing.jpp.ch21; The formatResponse() method takes the HttpServletRequest object as a paramater, and it returns a String object. The fact that this class is not a servlet does not impact its capability to make method calls on the HttpServletRequest object. This is an object like any other in Java and can be passed as a parameter as is done here. public String formatResponse(HttpServletRequest request) throws ServletException, java.io.IOException We create a StringBuffer class because we will be appending a lot of strings to it. StringBuffer's performance is so much better than the String class's, that it makes sense to use it here. In fact, programmers who do serial appends to String objects risk embarrassment during code review. StringBuffer sb = new StringBuffer(); // output your page here sb.append("<html>\n"); sb.append("<head>\n"); The request object's methods, such as getParameter(), are available inside this class also. sb.append(request.getParameter("UserName") + "<BR>\n"); Before returning, we transform the StringBuffer into a String object and return it to the servlet for insertion into the response object. return sb.toString(); To get this to work we also have to modify the DataEntry.html file, as shown in Listing 21.13. Listing 21.13 The DataEntry2.html File <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <HTML> <HEAD> <TITLE>Passing Parameters to Java Servlets</TITLE> </HEAD> <BODY BGCOLOR="#FDF5E6"> <H1 align="CENTER"> Enter Values DataEntry2 </H1> <FORM action='/examples/servlet/PassParam2'> Name2: <INPUT TYPE="TEXT" NAME="UserName"><BR><BR> Age2: <INPUT TYPE="TEXT" NAME="UserAge"><BR><BR> Favorite Sport2: <INPUT TYPE="TEXT" NAME="UserSport"><BR><BR> <CENTER> <INPUT TYPE="SUBMIT"> </CENTER> </FORM> </BODY> </HTML> The only major change is the calling of the PassParam2 servlet instead of the PassParam servlet. <FORM action='/examples/servlet/PassParam2'> The deployment of this servlet and class is a bit different. The PassParam2.class file can be placed in the ...\webapps\examples\WEB-INF\classes directory, and the HTML file can be placed in the ...\webapps\examples directory as before. The HTMLBuilder class, however, is in a package. The rules of packages state that the class file must be stored in a directory structure that matches the package name. The package name for HTMLBuilder is com.samspublishing.jpp.ch21. This requires that this class be placed in the directory: ...\webapps\examples\WEB-INF\classes\com\samspublishing\jpp\ch21 This makes for a long subdirectory string, but Tomcat can find what it needs very easily. You run this by entering the name of the HTML file in the address line of the browser: http://localhost:1776/examples/DataEntry2.html When you click the SUBMIT button, the URL that appears is [View full width] http://localhost:1776/examples/servlet/PassParam2? UserName=Jake&UserAge=9&UserSport=Soccer The browser output is nearly identical to Figures 21.9 and 21.10, so they won't be repeated here. This application added several println() statements for debugging purposes. The Tomcat console, which is shown here, is where these statements appear. Creating the HTMLBuilder Entered into HTMLBuilder.formatResponse() Returning from HTMLBuilder.formatResponse() Response was formatted by HTMLBuilder It is often useful to add println() statements to your code to monitor its progress and to track down bugs. |