Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

AhmadLang / Java, How To Program, 2004

.pdf
Скачиваний:
626
Добавлен:
31.05.2015
Размер:
51.82 Mб
Скачать

[Page 1265 (continued)]

26.8. Multitier Applications: Using JDBC from a Servlet

Servlets can communicate with databases via JDBC (Chapter 25). Many of today's applications are three-tier distributed applications, consisting of a user interface, business logic and a database. The user interface in such an application is often created using HTML or XHTML (as shown in this chapter). HTML and XHTML are preferred in systems where portability is a concern. Using the networking provided by the browser, the user interface can communicate with the middle-tier business logic. The middle tier can then access the database to manipulate the data. The three tiers can reside on separate computers that are connected to a network.

In multitier architectures, Web servers often are used in the middle tier. Server-side components, such as servlets, execute in an application server alongside the Web server. These components provide the business logic that manipulates data from databases and communicates with client Web browsers.

Servlets, through JDBC, can interact with popular database systems. Developers use SQL for queries, and JDBC drivers handle the specifics of interacting with each database system.

The SurveyServlet in Fig. 26.21 and the Survey.html document in Fig. 26.22 implement portions of a three-tier distributed application. The middle tier is Survey-Servlet, which handles requests from the client browser and provides access to the third tiera MySQL database accessed via JDBC. The servlet in this example allows users to vote for their favorite animals. When the servlet receives a post request from the Web browser, the servlet uses JDBC to update the total number of votes for that animal in the database and returns a dynamically generated XHTML document containing the survey results to the client.

[Page 1266]

Figure 26.21. Multitier Web-based survey using XHTML, servlets and JDBC.

(This item is displayed on pages 1266 - 1268 in the print version)

1

//

Fig.

26.21:

SurveyServlet.java

2

//

A Web-based

survey that uses JDBC from a servlet.

3

package

com.deitel.jhtp6.servlets;

4

 

 

 

 

5import java.io.PrintWriter;

6import java.io.IOException;

7import java.sql.Connection;

8import java.sql.DriverManager;

9import java.sql.Statement;

10import java.sql.ResultSet;

11import java.sql.SQLException;

12import javax.servlet.ServletConfig;

13import javax.servlet.ServletException;

14import javax.servlet.UnavailableException;

15import javax.servlet.http.HttpServlet;

16import javax.servlet.http.HttpServletRequest;

17import javax.servlet.http.HttpServletResponse;

19public class SurveyServlet extends HttpServlet

20{

21private Connection connection;

22private Statement statement;

24// set up database connection and create SQL statement

25public void init( ServletConfig config ) throws ServletException

26{

27// attempt database connection and create Statements

28try

29{

30Class.forName( config.getInitParameter( "databaseDriver" ) );

31connection = DriverManager.getConnection(

32

config.getInitParameter( "databaseName" ) );

33

config.getInitParameter(

"username"

),

34

config.getInitParameter(

"password"

) );

35

 

 

 

36// create Statement to query database

37statement = connection.createStatement();

38} // end try

39// for any exception throw an UnavailableException to

40// indicate that the servlet is not currently available

41catch ( Exception exception )

42{

43exception.printStackTrace();

44throw new UnavailableException(exception.getMessage());

45} // end catch

46} // end method init

47

48// process survey response

49protected void doPost( HttpServletRequest request,

50HttpServletResponse response )

51throws ServletException, IOException

52{

53// set up response to client

54response.setContentType( "text/html" );

55PrintWriter out = response.getWriter();

56

57// start XHTML document

58out.println( "<?xml version = \"1.0\"?>" );

60out.printf( "%s%s%s" , "<!DOCTYPE html PUBLIC" ,

61" \"-//W3C//DTD XHTML 1.0 Strict//EN\"",

62" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n" );

64out.println(

65"<html xmlns = \"http://www.w3.org/1999/xhtml\">" );

67// head section of document

68out.println( "<head>" ) ;

70// read current survey response

71int value =

72Integer.parseInt( request.getParameter( "animal" ) );

73String sql;

74

75// attempt to process a vote and display current results

76try

77{

78// update total for current survey response

79sql = "UPDATE surveyresults SET votes = votes + 1 " +

80

"WHERE id = " + value;

 

81

statement.executeUpdate( sql

);

82

 

 

83// get total of all survey responses

84sql = "SELECT sum( votes ) FROM surveyresults" ;

85ResultSet totalRS = statement.executeQuery( sql );

86totalRS.next(); // position to first record

87int total = totalRS.getInt( 1 );

88

89// get results

90sql = "SELECT surveyoption, votes, id FROM surveyresults " +

91

"ORDER BY id";

92ResultSet resultsRS = statement.executeQuery( sql );

93out.println( "<title>Thank you!</title>" ) ;

94out.println( "</head>" );

95

96out.println( "<body>" );

97out.println( "<p>Thank you for participating." );

98out.println( "<br />Results:</p><pre>" );

99

100// process results

101int votes;

102

103while ( resultsRS.next() )

104{

105

out.print(

resultsRS.getString( 1 ) );

106

out.print(

": " );

107

votes = resultsRS.getInt( 2 );

108

out.printf( "%.2f", ( double ) votes / total * 100 );

109

out.print( "% responses: " );

110

out.println( votes );

111

} // end while

112

 

113

resultsRS.close();

114

 

115out.print( "Total responses: " );

116out.print( total );

117

118// end XHTML document

119out.println( "</pre></body></html>" );

120out.close();

121} // end try

122// if database exception occurs, return error page

123catch ( SQLException sqlException )

124{

125sqlException.printStackTrace();

126out.println( "<title>Error</title>" );

127out.println( "</head>" );

128out.println( "<body><p>Database error occurred. " );

129out.println( "Try again later.</p></body></html>" );

130out.close();

131} // end catch

132} // end method doPost

133

134// close SQL statements and database when servlet terminates

135public void destroy()

136{

137// attempt to close statements and database connection

138try

139{

140statement.close();

141connection.close();

142} // end try

143// handle database exceptions by returning error to client

144catch ( SQLException sqlException )

145{

146sqlException.printStackTrace();

147} // end catch

148} // end method destroy

149} // end class SurveyServlet

Figure 26.22. Survey.html document that allows users to submit survey responses to SurveyServlet.

 

(This item is displayed on pages 1270 - 1271 in the print version)

1

<?xml version = "1.0" ?>

2

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"

3

"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

4

 

5

<!-- Fig. 26.22: Survey.html -->

6

 

7<html xmlns = "http://www.w3.org/1999/xhtml">

8<head>

9<title>Survey</title>

10</head>

11

12<body>

13<form method = "post" action = "/jhtp6/animalsurvey">

14<p>What is your favorite pet?</p>

15<p>

16<input type = "radio" name = "animal"

17value = "1" />Dog<br />

18<input type = "radio" name = "animal"

19value = "2" />Cat<br />

20<input type = "radio" name = "animal"

21value = "3" />Bird<br />

22<input type = "radio" name = "animal"

23value = "4" />Snake<br />

24<input type = "radio" name = "animal"

25value = "5" checked = "checked" /> None

26</p>

27<p><input type = "submit" value = "Submit" /></p>

28</form>

29</body>

30</html>

[View full size image]

Lines 21 and 22 begin by declaring a Connection to manage the database connection and a Statement for updating the vote count for an animal, totaling all the votes and obtaining the complete survey results.

[Page 1269]

Servlets are initialized by method init, which we override in SurveyServlet (lines 2546). Method init is called exactly once in a servlet's life cycle, before any client requests are accepted. The method takes ServletConfig argument and throws a Servlet-Exception. The argument provides the servlet with information about its initialization parameters (i.e., parameters not associated with a request, but passed to the servlet for initializing the servlet). These parameters are specified in the web.xml deployment descriptor file as part of a servlet element. Each parameter appears in an init-param element of the following form:

<init-param>

<param-name>parameter name</param-name> <param-value>parameter value </param-value>

</init-param>

Servlets can obtain initialization parameter values by invoking ServletConfig method getInitParameter, which receives a string representing the param-name of the parameter and returns the param-value as a string.

In this example, the servlet's init method (lines 2546) performs the connection to the MySQL database. Line 30 loads the driver (com.mysql.jdbc.Driver, which is specified in the initialization parameter "databaseDriver"). Lines 3134 attempt to open a connection to the animalsurvey database. The database name, username and password are specified in the initialization parameters "databaseName", "username" and "password", respectively. The database contains one table (surveyresults) that consists of three fieldsa unique integer to identify each record (id), a string representing the survey option (surveyoption) and an integer representing the number of votes for a survey option (votes). [Note: The examples folder for this chapter contains the SQL script animalsurvey.sql with which you can create the animalsurvey database for this example. For information on executing the SQL script, please refer to Chapter 25.]

When a user submits a survey response, method doPost (lines 49132) handles the request. Lines 7172 obtain the survey response, then lines 76121 attempt to process it. Lines 7980 specify an update statement to increment the votes value for the record with the specified ID and update the database. Lines 8587 execute the query specified in line 84 to retrieve the total number of votes received using SQL's built-in sum function to total all the votes in the surveyresults table. Then lines 92120 execute the query specified in lines 9091 to obtain the data in the table and process the ResultSet to create the survey summary for the client. When the servlet container terminates the servlet, method destroy (lines 135148) closes the Statement, then closes the database connection. Figure 26.22 shows survey.html, which invokes SurveyServlet through alias animalsurvey when the user submits the form.

We use our jhtp6 context root to demonstrate the servlet of Fig. 26.21. Place Survey.html in the servlets directory created previously. Place SurveyServlet.class (with the complete package structure) in the classes subdirectory of WEB-INF in the jhtp6 context root. Then, edit the web.xml deployment descriptor in the WEB-INF directory to include the information specified in Fig. 26.23. This program cannot execute in Tomcat unless the Web application has access to the JAR file that contains the MySQL database driver and its supporting classes. This JAR file (mysql-connector-java-3.0.14-production- bin.jar) can be found in your MySQL Connector's installation directory. Place a copy of this file in the WEB-INF subdirectory lib to make its contents available to the Web application. Please refer to Chapter 25 for more information on how to configure MySQL.

[Page 1270]

Figure 26.23. Deployment descriptor information for servlet

SurveyServlet.

(This item is displayed on page 1272 in the print version)

Descriptor element

Value

 

 

servlet element

 

servlet-name

animalsurvey

description

Connecting to a database from a servlet.

servlet-class

com.deitel.jhtp6.servlets.SurveyServlet

init-param

 

 

 

param-name

databaseDriver

param-value

com.mysql.jdbc.Driver

init-param

 

param-name

databaseName

param-value

jdbc:mysql://localhost/animalsurvey

init-param

 

param-name

username

param-value

jhtp6

init-param

 

param-name

password

param-value

jhtp6

servlet-mapping element

 

servlet-name

animalsurvey

url-pattern

/animalsurvey

 

 

After copying these files, type the following URL in your Web browser:

http://localhost:8080/jhtp6/servlets/Survey.html

Select an animal and press the Submit button to invoke the servlet. [ Note: The MySQL database server should be running when the servlet is invoked.]

[Page 1270 (continued)]

26.9. Welcome Files

Web application developers can specify an ordered list of welcome files to be loaded when the request URL is not mapped to a servlet. These files are typically HTML or JSP documents. Welcome files are defined using the welcome-file-list element in the deployment descriptor. Element welcome- file-list contains one or more welcome-file elements. Each welcome-file element specifies the partial URL of a welcome file without a leading or trailing /. For example, the following welcome-file- list element indicates that index.html and index.htm are the welcome files.

<welcome-file-list>

<welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file>

</welcome-file-list>

[Page 1271]

To specify the welcome files for the jhtp6 context root, insert the preceding welcomefile-list element after the last servlet-mapping element in the web.xml deployment descriptor. When the URL http://localhost:8080/jhtp6/ is requested, the Web server appends each welcome file in the order specified in the deployment descriptor to the request URL, such as

[Page 1272]

http://localhost:8080/jhtp6/index.html

http://localhost:8080/jhtp6/index.htm

and checks whether the resource is valid. The servlet container sends the request to the first matching welcome file. For example, if index.html exists in the jhtp6 directory, the servlet container sends the request to the http://localhost:8080/jhtp6/index.html. If no matching welcome file is found, the servlet container returns a response indicating that the resource is not available.

Figure 26.24 is the index.html that provides links (lines 1524) to test all the examples demonstrated in this chapter. Copy this file to C:\jakarta-tomcat-5.0.25\webapps\jhtp6 and restart the Tomcat server. To test the welcome file, type the following URL in your Web browser:

Figure 26.24. Welcome file index.html.

 

(This item is displayed on page 1273 in the print version)

1

<?xml version = "1.0" ?>

2

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"

3

"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

4

 

5

<!-- Fig. 26.24: index.html -->

6

 

7<html xmlns = "http://www.w3.org/1999/xhtml">

8<head>

9<title>Welcome File</title>

10</head>

11

12<body>

13<p>Click a link to test each example demonstrated in this chapter</p>

14<p>

15<a href = "/jhtp6/servlets/WelcomeServlet.html">

16WelcomeServlet</a><br />

17<a href = "/jhtp6/servlets/WelcomeServlet2.html">

18WelcomeServlet2</a><br />

19<a href = "/jhtp6/servlets/WelcomeServlet3.html">

20WelcomeServlet3</a><br />

21<a href = "/jhtp6/servlets/RedirectServlet.html">

22RedirectServlet</a><br />

23<a href = "/jhtp6/servlets/Survey.html">

24SurveyServlet</a><br />

25</p>

26</body>

27</html>

[View full size image]

http://localhost:8080/jhtp6/

The index.html page is loaded. Click a link to test the corresponding servlet example.

[Page 1274]

26.10. Wrap-Up

This chapter continued our networking discussions by presenting servlets that enhance the functionality of Web servers. You learned the architecture and life cycle of servlets. You learned how to respond to HTTP requests by using an HttpServlet. You also learned how to redirect requests to a static or dynamic Web resource. You executed the sample servlets with the Apache Tomcat server. You then built a multitier Web application that uses JDBC to access and manipulate a database from a servlet. In the next chapter, we introduce JavaServer Pagesan extension of servlet technology. We demonstrate several JSP componentsimplicit objects, scripting elements, standard actions and directives. We also discuss how to use CachedRowSets to access a MySQL database from a JavaBean object, then access the JavaBean object from a JSP page.