WebDev Essential Skills BCIS 3680 Enterprise Programming Overview Getting and displaying information Building SQL Conversion or no conversion Quotes or no quotes Handling foreign key relationships Shaping the retrieved info Sharing and passing info among pages 2 Handcrafted query strings Session variables Application variables Cookies Building SQL Information entered by user often is used to build a query, e.g., values for columns in an INSERT statement, filtering criterion in WHERE clauses, etc. Remember that <form> parameters are passed as Strings. Therefore: 3 For optional entries (checkboxes, radio buttons), first verify that the parameter is not null or empty strings. For mandatory entries (textboxes, password, etc.), read and store parameters as Strings. No Conversion Needed Since an SQL statement is essentially a long string and parameters are strings, we don’t have to convert a parameter value even if its business meaning is numeric because it is added to another string. When building SQL statements, the operation involved is concatenation, not math! For example, when building this WHERE clause: "WHERE price > " + request.getParameter("price"); We don’t have to convert the value of the price parameter by using Double.parseDouble() or Float.parseFloat() even though the price value may well be numeric. 4 To Quote or Not to Quote… What needs to be decided is whether to concatenate a single quote before and after the parameter. The business meaning of a parameter is a number, e.g., price, quantity, ID implemented as integers, etc. No need to add single quotes when using it in filtering condition The business meaning of a parameter is text, e.g., username, password, city, state, etc. 5 Need to add single quotes when using it in filtering condition (WHERE clauses). No Quotes If the business meaning of a parameter is numeric, and it looks like a number, then no single quotes are needed. Build the SQL as a string until the numeric parameter value is needed. Then concatenate the parameter to it. String sql = "SELECT * FROM product WHERE id = " + request.getParameter("prodid"); So, if the product ID entered by the user is 1001, in runtime the variable sql will evaluate to: SELECT * FROM product WHERE prodid = 1001 If more string literals are needed as part of the SQL statement, concatenate them after the parameter. 6 Quotes If the business meaning of a parameter is textual, then single quotes are needed. Add an' before concatenating the parameter and another one after the parameter. Note in the example below that: The second 'must be enclosed by two double-quotes ("'"). String sql = "SELECT * FROM user WHERE username = '" + request.getParameter("username") + "'"; So, if the username entered by the user is Carlos, in runtime the variable sql will evaluate to: SELECT * FROM user WHERE username = 'Carlos' 7 What about the Semicolon Although a semicolon is mandatory in MySQL to mark the end of an SQL statement, it is optional when the SQL statement is passed as the argument to the executeQuery() or executeUpdate() method of the Statement object. However, some people find it helpful to add it so that it acts as an visual cue of the end of an SQL statement being built. That improves code readability. String sql = "SELECT * FROM user WHERE username = '" + request.getParameter("username") + "';"; String sql = "SELECT * FROM product WHERE id = " + request.getParameter("prodid") + ";"; 8 Foreign Key Relationship When building queries that retrieve information from two or more tables with foreign key relationship(s), it’s important that you “mimic” the FK relationship(s) in the WHERE clause by stating table1.FK = table2.PK; the table names are mandatory to avoid ambiguity. This must be repeated for every FK relationship between the tables. Only the first one starts with the WHERE keyword; each subsequent part is added using the AND keyword. If there is some filtering criterion, add it as the last AND (add additional ANDs for additional criteria). 9 Repeating Table Rows When multiple matches are returned by a query, usually they will be displayed in the same manner. That means there are some common HTML tags that will be used to enclose each result, e.g., the <tr> and <td> tags. Identify those HTML tags and situate them (as well as all the necessary out.print code) inside the loop body of while. Leave HTML tags that are related but not supposed to be repeated (e.g., the <table> and <th> tags) outside of the loop. If certain actions need to be performed on some but not all results, then add if statement(s) to do the job. The if statement still must be part of the loop body. 10 Shaping the Retrieved Info Data are stored in DBMSes in their “raw” form (which conforms to the data types defined in the schema). Thus, when retrieved, data often may not be in the exact form suitable for display in web pages. Therefore, manipulation of the data after the query is returned often is needed before we mix them with HTML. Useful String methods include: 11 substring() replace() indexOf() charAt() Shaping the Retrieved Info There are some functions in SQL that performs some manipulations on the data. We can call them to get data that is represented more in line with the required format, e.g., use the YEAR function to retrieve just the year part of a date. Such functions typically are for logical and mathematical operations. Their formatting capabilities are limited to say the best. Using functions is not the optimal approach if the manipulation involved is too complex or if a number of transformations may be needed on the same set of data in the Web pages. 12 Sharing and Passing Info Among Pages Handcrafted query string Session variables Application variables Cookies 13 Handcrafted Query String A <form> is used to pass information from one page to the next. However, that takes place only when the submit button is clicked. However, it’s often necessary to pass information through different channels, e.g., a hyperlink opens up another page and passes info to that new page because the latter is dynamic and needs that info from the current page. It’d be very bad GUI design if the user had to click the submit button to open that hyperlink (the user’s intuitive action is to click the hyperlink to follow it). In this scenario, we don’t want to rely on <form> to pass information. 14 Handcrafted Query String You can manually created a query string – a question mark followed by name-value pair(s), connected to each other by &s and append it to a URL. In other words, the parameter name and value do not have to come from the name and value attributes of the <input> tags.You may create them “out of the blue”. However, this is a “quick and dirty” way that has limitations: 15 Just like using the <form> tag, the parameters go only as far as the next page. It works only when it does not generate security concerns because the parameters and their values are visible to the visitor. request Does Not Travel Far The most straightforward way to share information is the parameters in the request object. However, parameters only travel as far as the next page. Going into the third page and you don’t see them. The “sharing” is unidirectional – going forward to the next page. But often we need to go back and forward pages and still be able to access shared data. 16 request Does Not Travel Far 17 request Does Not Travel Far 18 A Dilemma in Web Design HTTP is a stateless protocol. The client makes a request; the server serves the requested document; and then the server closes the connection. Each request from the client is processed independent of other requests. The server does not “remember” previous requests from the same client. This allows the server to serve a maximum number of concurrent requests efficiently. However, there are many occasions when we want the server to “remember” the client, i.e., to maintain “state”. We often need to share information among a number of pages in a Web application. (Not Necessarily Good) Solutions Sessions Application Server-side collections of variables that make up the state. Once logged on, the client is assigned a session ID. Session variables do not survive browser closure – when the browser window is closed, the session is over. Information may be stored in the configuration file of a Web app. Cookies Small blocks of ASCII text stored on the client that can survive browser closures and computer reboots. Web application cannot rely on the assumption that a user will accept cookies. The session Object Implicit object, created automatically when a client requests a JSP page at the first time. A session object is associated with all requests from within the same browser window. Each client has a unique session object. The session object can be accessed by its owner only. 21 Creating/Accessing Session Variables To create a session variable, call the setAttribute() method of the session object: session.setAttribute("attributeName", anObjectReference); To retrieve the value stored in a session variable later, call the getAttribute() method: session.getAttribute("attributeName"); To remove a session variable: session.removeAttibute("attributeNameToRemove"); 22 Session Variables 23 Session Variables 24 Web Applications A Web application is a group of files A Web application software provides services to a variety of clients It consists of the following components: 25 Web server Documents Application server The Application Object Each Web application has one and only one application object. The application object can be shared by all application users. It can be used to hold references to other objects that can be accessed by all users. 26 Application Variables Accessible to all clients. Can be initialized when you configure the Web server and/or the Web application. Can be created by using the application object in a JSP file. 27 Application Variables 28 Initialization Parameters Set initialization parameters in web.xml (you need to restart Web server) <context-param> <param-name>variable name</param-name> <param-value>value</param-value> </context-param> For example: <context-param> <param-name>webmaster</param-name> <param-value>webmaster@ebcity.com</paramvalue> </context-param> 29 Get Initialization Parameters Accessible from any JSP file under the same application application.getInitParameter("parameterName") Returns a string containing the value of the named parameter If the parameter does not exist, it returns a null value 30 application.getInitParameterNames() Returns the names of these initialization parameters as an enumeration of string objects Setting/Getting App Variables in Code You may create new application variables in code (instead of in the configuration file): application.setAttribute("attr_name", an_object) This method binds an object to a given attribute name When you use the setAttribute() method to set an attribute, if the name specified is already used for an attribute, this method removes the old bound object and binds the name to the new object. 31 Remove Application Variable To access the value stored in the application variable later: application.getAttribute("attribute_name") This method returns an object bound to the attribute with the given name; if there is no attribute by that name, it returns a null value. To remove an application variable: application.removeAttribute("attributeName"); 32 This method removes the attribute with the given name. After removal, subsequent calls to getAttribute("attributeName") to retrieve the attribute's value will return null.