7 Web Databases Access to Web Databases: Servlets, Applets Java Server Pages PHP, PEAR Languages: Java, PHP, Python,... Prof. Dr. Dietmar Seipel 837
7.1 Access to Web Databases by Servlets Java Servlets can be called using a parametrised URL (Uniform Resource Locator). To guarantee the scalability of the architecture even for very large numbers of users, the servlet engine executes the requests in parallel in several independent threads (lightweight processes). Sofware systems which are extended in that way often in combination with a Web server are called application servers. Prof. Dr. Dietmar Seipel 838
Formular Interface Prof. Dr. Dietmar Seipel 839
Query Page in HTML <html> <head><title>employees over a given Income</title></head> <body> <h1>employees over a given Income</h1> <blockquote> <form action="https:/www.xyz.de/servlets/employeesalary" method="get"> Please enter the minimum salary: <br> <input type="text" name="salary"/> <br> <input type="submit" value="submit Query"/> </form> </blockquote> </body> </html> Prof. Dr. Dietmar Seipel 840
The servlet implements a method doget (or dopost): start of the database connection using JDBC execution of the query generation of the HTML page which is send to the browser Parameters: The parameters which are necessary for formulating the query are computed on the client side using a formular interface. They are transferred to the servlet as an HttpServletRequest object request. The servlet accesses a paramenter Par by calling request.getparameter("par"). Output: The generated HTML document is transferred to the HttpServletResponse object using a PrintWriter object. Prof. Dr. Dietmar Seipel 841
GET Method When using the HTTP GET method, the parameters are transferred from the Web browser as part of the URL to the servlet, e.g.: https:/www.xyz.de/servlets/employeesalary?salary=30000 The parameter part (following the character? ) of such a URL is often called query string. Several parameter/value pairs can be transmitted separated by &. POST Method When using the alternative HTTP POST method, the parameters are transferred invisbly from the Web browser to the servlet; they are not part of the URL. Prof. Dr. Dietmar Seipel 842
Java Servlet import javax.servlet.*; import javax.servlet.http.*; import java.io.*; import java.sql.*; import java.text.*; public class EmployeeSalary extends HttpServlet { public void doget ( HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException { protected Connection con = null; initconnection(); response.setcontenttype("text/html"); PrintWriter out = response.getwriter(); String Salary = request.getparameter("salary"); generatehtmltable(salary); } } Prof. Dr. Dietmar Seipel 843
private void generatehtmltable(string Salary) { printhtmlheader(salary); try { String query = "SELECT * FROM employee " + "WHERE salary >= " + Salary + " "; Statement stmt = con.createstatement(); ResultSet rs = stmt.executequery(query); while (rs.next()) { out.println( "<tr><td>" + rs.getstring("fname") + "</td><td>" + rs.getstring("minit") + "</td><td>" + rs.getstring("lname") + "</td><td>" + rs.getstring("salary") + "</td></tr>" ); } } catch (Exception mye){ out.println(mye.tostring()); } printhtmlbottom(); } Prof. Dr. Dietmar Seipel 844
Result of the Query (HTML, in Browser) <html> <head><title>employees earning at least 30000 USD</title></head> <body> <table border="1" cellpadding="5"> <tr><th>fname</th><th>minit</th><th>lname</th><th>salary</th></tr> <tr><td>john</td><td>b</td><td>smith</td><td>30000</td></tr> <tr><td>franklin</td><td>t</td><td>wong</td><td>40000</td></tr> <tr><td>jennifer</td><td>s</td><td>wallace</td><td>43000</td></tr> <tr><td>ramesh</td><td>k</td><td>narayan</td><td>38000</td></tr> <tr><td>james</td><td>e</td><td>borg</td><td>55000</td></tr> </table> </body> </html> Prof. Dr. Dietmar Seipel 845
A servlet should check the parameters before using them in SQL queries. Database Injection Problem If we build the query as String query = "SELECT * FROM employee " + "WHERE salary >= " + Salary; then a user could enter 30000; DELETE * FROM employee in the field for salary of the HTML formular. Then the query SELECT * FROM employee WHERE salary >= 30000; DELETE * FROM employee would be constructed; its execution would delete all tuples of the relation employee. Prof. Dr. Dietmar Seipel 846
HTML Page with Servlet Calls <html> <head><title>employees over a given Income</title></head> <body> <h1>employees over a given Income</h1> <ul> <li> <a href=".../servlets/employeesalary?salary=0"> list all employess </a> </li> <li> <a href=".../servlets/employeesalary?salary=30000"> list employess over 30000 USD </a> </li> <li> <a href=".../servlets/employeesalary?salary=60000"> list employess over 60000 USD </a> </li> </ul> </body> </html> Prof. Dr. Dietmar Seipel 847
Prof. Dr. Dietmar Seipel 848
Access to Web Databases by Java Applets Applets are Java programs which are executed at the client side. Applets are mobile code, which is transferred from the Web server to the client, and which is executed at the client side. Prof. Dr. Dietmar Seipel 849
7.2 Java Server Pages HTML pages which consist of both static and dynamically generated parts Java Server Pages (JSPs) allow for embedding Java code fragments in an HTML page. The Web server initiates their execution before the page is send to the client. Advantage: The visualisation, i.e., the HTML code, is statically part of the document. The Java code fragments can be components (Java beans) that are part of separate files. This encreases readability and reuse. Microsoft alternatively offers Active Server Pages (ASPs). Prof. Dr. Dietmar Seipel 850
5 additional tags: <%@page attributes of the directive%> guiding the translation of the JSP by various attributes <%!declaration%> e.g., a Java operation which later is executed in the page several times <%=expression%> corresponds to <% out.print(expression) %> <%java code fragment%> <%--comment--%> is not transferred to the generated HTML document Prof. Dr. Dietmar Seipel 851
Java Server Page with Java Code <%@page import="java.sql.*"%> <%!Connection con = null;%> <%initconnection();%> <%!String generatehtmltable(string Salary)...%> <html> <head><title>employees over a given Income</title></head> <body> <ul> <li> 0 <%=generatehtmltable("0")%> </li> <li> 30000 <%=generatehtmltable("30000")%> </li> <li> 60000 <%=generatehtmltable("60000")%> </li> </ul> </body> </html> Prof. Dr. Dietmar Seipel 852
String generatehtmltable(string Salary) { StringBuffer result = new StringBuffer(); result.append("<table>"); try { String query = "SELECT * FROM employee " + "WHERE salary >= " + Salary + " "; Statement stmt = con.createstatement(); ResultSet rs = stmt.executequery(query); while (rs.next()) { result.append( "<tr><td>" + rs.getstring("fname") + "</td><td>" + rs.getstring("minit") + "</td><td>" + rs.getstring("lname") + "</td><td>" + rs.getstring("salary") + "</td></tr>" ); } } catch (Exception mye){ result.append(mye.tostring()); } result.append("</table>"); return result.tostring(); } Prof. Dr. Dietmar Seipel 853
Computation in PROLOG / FNQuery The relational database is accessed using an ODBC query. The data types of the returned rows of the table employee are given by Types. generate_html_table(salary, table:rows) :- concat( SELECT fname, minit, lname, salary \ FROM employee WHERE salary >=, Salary, Query), Types = [types([atom,atom,atom,integer])], findall( Row, ( odbc_query(mysql, Query, row(f,m,l,s), Types), Row = tr:[td:[f], td:[m], td:[l], td:[s]] ), Rows ). For a every result row(f,m,l,s), a PROLOG term tr:[td:[f], td:[m], td:[l], td:[s]] is constructed, which represents a table row in HTML. Prof. Dr. Dietmar Seipel 854
Java Server Page with a Call to a Java Bean <%@page import="jspdemo.employeebean"%> <jsp:usebean id="mybean" class="jspdemo.employeebean" scope="application"/> <html> <head><title>employees over a given Income</title></head> <body> <ul> <li> 0 <%=mybean.generatehtmltable("0")%> </li> <li> 30000 <%=mybean.generatehtmltable("30000")%> </li> <li> 60000 <%=mybean.generatehtmltable("60000")%> </li> </ul> </body> </html> Prof. Dr. Dietmar Seipel 855
Java Bean package jspdemo; import java.sql.*; public class EmployeeBean { Connection con = null; public EmployeeBean() { initconnection(); } public String generatehtmltable(string Salary)... } There must exist a constructor without parameters. Prof. Dr. Dietmar Seipel 856
Access to a JSP The JSP is translated into a servlet. The browser requests the JSP. The Web server initiates the execution of the generated servlet. During the execution, the Java code fragments (including the tags for the expressions) are eliminated, and they are replaced by the results that are generated during the execution. The resulting pure HTML page is send to the client. The Web browser displays this page. Prof. Dr. Dietmar Seipel 857
A Template Implementation in PROLOG (cf. Server Faces) <html> <head><title>employees earning at least 30000 USD</title></head> <body> <table border="1" cellpadding="5"> <tr> <th BGCOLOR="#dfdfff">Fname</th> <th BGCOLOR="#dfdfff">Minit</th> <th BGCOLOR="#dfdfff">Lname</th> <th BGCOLOR="#dfdfff">Salary</th> </tr> <sequence database="company" sql="where salary >= 30000 order by salary"> <tr> <td><select table="employee" attribute="fname"/></td> <td><select table="employee" attribute="minit"/></td> <td><select table="employee" attribute="lname"/></td> <td><select table="employee" attribute="salary"/></td> </tr> </table> </body> </html> Prof. Dr. Dietmar Seipel 858
7.3 Web Database Connections in PHP originally, PHP was designed as a scripting language, for generating HTML functional language, since PHP Version 4 also object oriented very broad support of the providers (classical environment: Apache / PHP 4 or PHP 5 / MySQL) lower costs for development and maintenance than for servlet applications Prof. Dr. Dietmar Seipel 859
databases can be accessed from PHP in two ways: directly over the PHP interface implementation of the database (e.g., php mysql) over the PEAR database interface (PHP Extension and Application Repository) PEAR serves as a layer of abstraction in PHP and supports (almost) all common database types, including MySQL, PostgreSQL, Oracle 7/8/8i, Interbase, ODBC, Microsoft SQL,... Prof. Dr. Dietmar Seipel 860
PEAR Database Model as an Abstraction Layer: Advantage: independent of database specific extensions (cf., ODBC), thus easily portable (e.g., from Mysql to Postgres) Disadvantage: no database specific features (e.g., view mechanisms under Postgres) Example (PEAR) Start of a connection over DSN (data source names): mysql://user:very_secret@localhost/company Query Shutdown of the connection Prof. Dr. Dietmar Seipel 861
<?php require_once( DB.php ); // $dsn = array( phptype => mysql, username => user, password => very_secret, hostspec => localhost, database => company ); $db =& DB::connect($dsn); if(pear::iserror($db)){ die($db->getmessage()); } $sql = "SELECT * FROM employee"; $result =& $db->query($sql); if(pear::iserror($result)){ die($result->getmessage()); } while($result->fetchinto($row)){ // $row: Array of result data } $db->disconnect();?> Prof. Dr. Dietmar Seipel 862
same example (Java like): <?php... $db = new DB(); $connection = $db->connect($dsn); if(pear::iserror($connection)){ die($connection->getmessage()); }... $result = $connection->query($sql);... while($row = $result->fetchrow()){ //... } $connection->disconnect();?> Prof. Dr. Dietmar Seipel 863
prepare and execute Statements for Select Queries standard query: $result = $db->query( "SELECT * FROM employee WHERE SALARY >= 30000"); prepared query with scalar: $prepared = $db->prepare( "SELECT * FROM employee WHERE SALARY >=?"); $result = $db->execute($prepared, 30000); prepared query with arrays: $prepared = $db->prepare( "SELECT * FROM employee WHERE SALARY >=? AND SEX =? "); $result = $db->execute($prepared, array(30000, F )); prepared statement for several queries: $prepared = $db->prepare( "SELECT * FROM employee WHERE SALARY >=? AND SEX =? "); $data = array(array(30000, F ), array(30000, M )); $results = $db->executemultiple($prepared, $data); foreach ($results as $result){ //... } Prof. Dr. Dietmar Seipel 864
autoprepare and autoexecute for Insert/Update Queries autoprepare generates complete Update or Insert Statements, which are executed using execute later autoexecute generates and executes Update or Insert Statements the query mode is set by DB_AUTOQUERY_INSERT and DB_AUTOQUERY_UPDATE, respectively Prof. Dr. Dietmar Seipel 865
Example (SQL, PHP): John Smith gets a raise in salary UPDATE employee SET SALARY=40000 WHERE SSN = 888888888 ; <?php $field_values = array( SALARY => 40000); $result = $db->autoexecute( employee, // table $field_values, // Werte DB_AUTOQUERY_UPDATE, // Mode "SSN= 888888888 " // WHERE--Bedingung ); // or: $field_names = array( SALARY ); $field_values = array( 40000 ); $prepared = $db->autoprepare( employee, $field_names, DB_AUTOQUERY_UPDATE, "SSN = 888888888 "); $result =& $db->execute($prepared, $field_values);?> Prof. Dr. Dietmar Seipel 866
Result Sets of Queries: Arrays The result sets can be stored as indexed arrays: <?php while($row = $result->fetchrow()){ // $row indexed }?> associative arrays (the array index uses the DB columns): <?php $db->setfetchmode(db_fetchmode_assoc); while($row = $result->fetchrow()){ echo $row[ FNAME ]; echo $row[ LNAME ]; echo $row[ SEX ]; echo $row[ SALARY ]; }?> Prof. Dr. Dietmar Seipel 867
Literature Rasmus Lerdorf, Kevin Tatroe: Programming PHP, O Reilly Verlag, 2002. PEAR Online Manual: http://pear.php.net/manual/en/ Prof. Dr. Dietmar Seipel 868