480 likes | 615 Vues
This session focuses on the development of JavaServer Pages (JSP) with Apache Tomcat 5.x and Informix. It covers comparisons between JSP, PHP, and ASP, and provides practical guidance on configuring Tomcat for use with Informix databases. Topics include working with JDBC, session management, error handling, and authentication options. The presentation also features example JSP scripts demonstrating database interaction, session handling, and how to implement security measures in web applications. Ideal for developers looking to enhance their web application skills using JSP.
E N D
Session: I10 Java and IDS: Part 2 - JSP Guy Bowerman IBM Information Management Wed, October 4, 2006 • 11:00 a.m. – 12:00 a.m. Platform: Informix
Agenda • JSP vs. PHP vs. ASP vs. ??? • Configuring Apache Tomcat 5.x for IDS • JSP Example – Simple Select • Authentication & Sessions • Pagination – Cursor-less cursors • Inserting & Streaming Byte Data • JSP Connection Pool • AJAX Made Simple
JSP vs. PHP vs. ASP vs. ??? • JSP • Variety of ready-made libraries, beans • Platform independence • Reliance on JVM • PHP • Scalability • Increasing popularity • ASP • Limited to VBScript/COM • Windows or Windows • Browser incompatibilities • Consider Tapestry/Cocoon vs. Rails etc…
Apache Tomcat 5.x & Informix JDBC Configuration • Install Tomcat • Copy ifx*.jar to $CATALINA_HOME/common/lib/ • Restart Tomcat – Done! Create new applications under $CATALINA_HOME/webapps/. Create a WEB-INF directory in application dir, e.g: $CATALINA_HOME/webapps/jspdemo/WEB-INF
JSP Application Directory Layout • *.html, *.jsp, etc.. • /WEB-INF/web.xml • Web Application Deployment Descriptor • /WEB-INF/classes/ • Java class files required by application. • /WEB-INF/lib/ • JAR files used by application.
JSP Example – Simple Select $CATALINA_HOME/webapps/jspdemo/demo1.jsp: <%@ page import="java.sql.*" errorPage="error.jsp"%> <head> <title>JSP Demo 1</title> </head> <body> <ul> <h3>Customers by city</h3><br/><% // initialize Informix JDBC driverClass.forName("com.informix.jdbc.IfxDriver");….
Connect and Create Statement …// connection URLString url = "jdbc:informixsqli://mymachine:1526/stores_demo” + “:INFORMIXSERVER=ol_myserver"; // get database connectionConnection conn = DriverManager.getConnection(url, "informix", “mypasswd"); // create statement and execute queryStatement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery( "select city, company from customer order by 1,2");%>…
JSP Example – Display Results <table border=1><%// process result setwhile (rs.next()) { %><tr> <td><b><%=rs.getString(1)%></b></td> <td><%=rs.getString(2)%></td> </tr><%} %></table>
JSP Example – Close Objects <%// close ResultSet and Statement objectsrs.close();stmt.close(); // close connectionconn.close(); %></ul></body>
Error Handling error.jsp: <%@ page language="java" isErrorPage="true"%> <head><title>An error has occurred</title></head> <body><center><h1>Oops</h1> </center><br></br><ul> <font size=+1>Something bad happened...<br></br> <ul> <font color="red"><%=exception.toString()%></font> </ul><br>Try to stay calm, I'm sure there is a rational explanation.</br></font></ul> </body>
JSP Authentication Options • Handle your own authentication • Use a standard Tomcat Realm • JDBCRealm • DataSourceRealm • JNDIRealm (LDAP based authentication) • MemoryRealm (conf/tomcat-users.xml). • JAASRealm • Implement your own Realm plug-in
Implementing a JDBCRealm • Write a login page • Write a login error page • Create a user table • Create a user roles table • Add a Realm definition to server.xml • Add security-constraint, login-config and security-role definitions to WEB-INF/web.xml
Tomcat Realm login page <head><title>Authentication Page</title></head> <body> <center><h2>Please log in to view the customer database</h2><br/><br/> <form method="POST" action="j_security_check"> <table><tr><td>Username: <input type="text" size="15" maxlength="32" name="j_username"> </td></tr><tr><td> Password: <input type="password" size="15" maxlength="32" name="j_password"> </td></tr><tr> <td><input value="Login" type="submit"> <input value="Clear" type="reset"></td> </tr></table></form></center> </body>
Tomcat Realm Login Error Page <head><title>Authentication Error!</title></head><body><center><h1>Access Denied!</h1><br/><br/><a href="javascript:history.back(1)">Tryagain?</a></center> </body>
JDBCRealm User Tables Make sure your database is logged! create table users(username varchar(32) unique, password varchar(32)); create table roles(username varchar(32), rolename varchar(32));insert into users values("guyb", "test");insert into users values("user2", "test2");insert into roles values("guyb", "admin");insert into roles values("guyb", "manager");insert into roles values("user2", "custAdmin");
Define JDBCRealm in conf/server.xml <!-- Comment out the old Realm definition --> <Realm className="org.apache.catalina.realm.JDBCRealm" driverName="com.informix.jdbc.IfxDriver" connectionURL= "jdbc:informixsqli://mymachine:1526/stores_demo:INFORMIXSERVER=ol_myserver"; connectionName="informix" connectionPassword="mypasswd" userTable="users" userNameCol="username" userCredCol="password" userRoleTable="roles" roleNameCol="rolename"/>
Add security-constraint to WEB-INF/web.xml <security-constraint><web-resource-collection><web-resource-name>Authorization Test</web-resource-name><description>custAdmin role</description><url-pattern>/*</url-pattern><http-method>GET</http-method><http-method>POST</http-method><http-method>PUT</http-method><http-method>DELETE</http-method></web-resource-collection><auth-constraint> <description>These roles allowed</description> <role-name>custAdmin</role-name></auth-constraint> </security-constraint>
Add login-config and security-role to web.xml <login-config><auth-method>FORM</auth-method><realm-name>Protected Area</realm-name><form-login-config> <form-login-page>/login.jsp</form-login-page> <form-error-page>/loginerror.jsp</form-error-page> </form-login-config> </login-config> <security-role><description>custAdmin role only</description><role-name>custAdmin</role-name> </security-role>
Session Management • Once logged in, access user name with request.getUserPrincipal().getName(), e.g.<h3>Hello<%=request.getUserPrincipal().getName()%></h3> • Tomcat provides a “session” object, e.g.session.setAttribute("userName“,request.getUserPrincipal().getName());session.setAttribute("loggedIn", "1");if (session.getAttribute("loggedIn“).equals("1") { … }
Pagination Problem • Display output in pages, 10 rows at a time, with next and previous buttons. Solution • Use the IDS 10.0 SELECT SKIP offset option with FIRST e.g.select SKIP 20 FIRST 10 col1, col2 from tab1 • Keep a count of rows and pass the count as a parameter to the JSP program. Use parameter to dynamically generate the next SKIP value
Inserting Binary Files Problem • Insert binary files from a browser into an Informix database Solution • Use the Jakarta Commons FileUpload Package with the PreparedStatement.setBinaryStream() Method
Inserting Binary File – HTML Upload Form <form action="docupload.jsp" method="post" enctype="multipart/form-data"> <input type="file" name="docfile"/><input type="submit" name="Action" value="Upload"/> </form>
Inserting Binary File – Get FileInputStream <%@ page import="org.apache.commons.fileupload.*, java.io.* %> DiskFileUpload dfu = new DiskFileUpload();List fileItems = dfu.parseRequest(request);Iterator itr = fileItems.iterator();FileInputStream docstream = null; dfu.setSizeMax(10000000); // throw exception if > 10 Mb while(itr.hasNext()) { FileItem fi = (FileItem) itr.next(); if (!fi.isFormField()) { // only process files here, not form fields docfilename = fi.getName(); docsize = fi.getSize(); docstream = (FileInputStream) fi.getInputStream(); }
Inserting Binary File – Insert into Table if (docsize > 0) { // insert into document table String sqlStr = "insert into document values("'" + docfilename + "',?)“ PreparedStatement pstmt = conn.prepareStatement(sqlStr); pstmt.setBinaryStream(1, docstream, (int) docsize); pstmt.executeUpdate(); pstmt.close();}
Downloading Binary Files Problem • Select a binary file from a database and stream it to the browser Solution • Set content type to APPLICATION/OCTET-STREAM • Use the ResultSet.getBinaryStream() method
Downloading Binary Files <%@ page import="java.sql.*, java.io.*, " errorPage="error.jsp"%><% // Important – do not print linefeeds or text before streaming file..… String sqlStr = "select docdata from document where filename = " + docfilename;ResultSet rs = stmt.executeQuery(sqlStr);rs.next(); // set content typeresponse.setContentType("APPLICATION/OCTET-STREAM");response.setHeader("Content-Disposition", "attachment; filename=\"" + filename + "\""); FileInputStream fileData = (FileInputStream) rs.getBinaryStream(1); // stream file to browserwhile ((i = fileData.read()) != -1) out.write(i);out.close(); %>
JSP Connection Pools • JSP applications can be slowed down by frequent connects/disconnects • Apache Tomcat comes with Jakarta Commons Database Connection Pool (commons-dbcp) • Straightforward to configure and use for most database systems
Creating an Informix JSP Connection Pool • Add a Context entry to conf/server.xml • Add a Resource reference to WEB-INF/web.xml • In application initialize Context and get DataSource from Context. • Get Connection object from DataSource
Connection Pool Example – Server.xml Add Context entry to $CATALINA_HOME/conf/server.xml …<Context path="/jspdemo" docBase=“jspdemo" debug="0" reloadable="true" crossContext="true"> <Resource name="jdbc/jspdemo" auth="Container" type="javax.sql.DataSource" maxActive="20" maxIdle="10" maxWait="1000" username="informix" password=“mypasswd" driverClassName="com.informix.jdbc.IfxDriver“ url="jdbc:informix-sqli://mymachine:1526/stores_demo:INFORMIXSERVER=ol_myserver"/> </Context>…. </Host>
Connection Pool Example – Web.xml Add Resource reference to: $CATALINA_HOME/webapps/myapp/WEB-INF/web.xml <?xml version="1.0" encoding="ISO-8859-1"?><web-app xmlns=http://java.sun.com/xml/ns/j2ee xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance xsi:schemaLocation=http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd version="2.4"> <resource-ref> <description>Informix Datasource example</description> <res-ref-name>jdbc/jspdemo</res-ref-name> <res-type>javax.sql.DataSource</res-type> <res-auth>Container</res-auth></resource-ref> </web-app>
Connection Pool – Application Changes <%@ page import="java.sql.*,javax.naming.*,javax.sql.*" errorPage="error.jsp"%> … <% // get database connectionContext initContext = new InitialContext();Context envContext = (Context) initContext.lookup("java:/comp/env");DataSource ds = (DataSource) envContext.lookup("jdbc/jspdemo");Connection conn = ds.getConnection();// replaces:// Connection conn = DriverManager.getConnection(url, user, passwd);…
What is AJAX? • Asynchronous JavaScript and XML • Dynamically update parts of an HTML page by means of JavaScript calls to server routines
AJAX Components • JavaScript function to call server routine via a browser independent XMLHttpRequest object • JavaScript processResponse() function to handle response from server and update page • Server routine to display updated data
AJAX Example – Triggering the Update Give an ID to the section of the page to update – in this case an HTML table column – the AJAX update is triggered here by moving the mouse over the column (onMouseOver) <tr> <td><b><%=city%></b></td> <td id="customer<%=custno%>"> <a href="javascript:custContact(<%=custno%>)" onMouseOver="javascript:custContact(<%=custno%>)"><%=company%></a> </td> </tr>
AJAX Example – XMLHttpRequest Object <script language="Javascript" type="text/javascript"> <!-- function createRequestObject() { // return appropriate request object for browser (Mozilla/IE) if (window.ActiveXObject) return new ActiveXObject("Microsoft.XMLHTTP"); else return new XMLHttpRequest(); } var xmlHttp = createRequestObject();
AJAX Example – Call Server Routines var elementId = ''; // AJAX call to display contact details for a customerfunction custContact(cust) { elementId = 'customer' + cust; xmlHttp.open('get', 'ccity_serv.jsp?cust=' + cust); xmlHttp.onreadystatechange = processResponse; xmlHttp.send(null);} // AJAX call to revert display to company namefunction closeContact(cust) { elementId = 'customer' + cust; xmlHttp.open('get', 'ccity_serv.jsp?closeCust=' + cust); xmlHttp.onreadystatechange = processResponse; xmlHttp.send(null);}
AJAX Example – Process Response // set ID tag to output from AJAX requestfunction processResponse() { if (xmlHttp.readyState == 4) { if (xmlHttp.status == 200) document.getElementById(elementId).innerHTML = xmlHttp.responseText; else document.getElementById(elementId).innerHTML = '<font color="red">Error: ' + xmlHttp.status + '</font>'; }} --> </script>
AJAX Example – Server Routines The server routines only display the HTML required to update the section of the page specified by the ID tag.. String cust = request.getParameter("cust"), closeCust = request.getParameter("closeCust"); if (cust != null) { … // execute select stmt to get contact details and display a table } else if (closeCust != null) {…// execute select stmt to get company name and display it }
AJAX Server Routine - Cust if (cust != null) { rs = stmt.executeQuery("select fname, lname, company, " + " address1, address2, city, state, zipcode from customer where " + "customer_num = " + cust); rs.next(); String comp = rs.getString("company").trim(); %> <table><tr><td> <table border=1><tr><td bgcolor="pink"><font size=+1> <%=rs.getString("fname")%> <%=rs.getString("lname").trim()%>,<br/> <%=comp%>,<br/> <%=rs.getString("address1").trim()%>,<br/> …
AJAX Server Routine - Cust <% if (rs.getString("address2") != null) { %> <%=rs.getString("address2").trim()%>,<br/> <% } %> <%=rs.getString("city")%><%=rs.getString("state")%> <%=rs.getString("zipcode")%></font> </td></tr></table></td><td> <a href="javascript:closeContact(<%=cust%>)" onMouseOver="javascript:closeContact(<%=cust%>)">Close</a></td></tr> </table> <% }
AJAX Server Routine - closeCust // re-display the original HTML showing customer name else if (closeCust != null) { rs = stmt.executeQuery("select company from customer where " + "customer_num = " + closeCust); rs.next(); String comp = rs.getString("company").trim(); %> <a href="javascript:custContact(<%=closeCust%>)" onMouseOver="javascript:custContact(<%=closeCust%>)"><%=comp%></a> <% }
Session I10 Java and IDS: Part 2 - JSP Guy Bowerman IBM Information Management guyb@us.ibm.com