Upload
willis-lawrence
View
217
Download
4
Embed Size (px)
Citation preview
Guy BowermanIBM Information Management
Session: I10
Wed, October 4, 2006 • 11:00 a.m. – 12:00 a.m.
Platform: Informix
Java and IDS: Part 2 - JSP
2
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
3
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…
4
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
5
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.
6
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 driver Class.forName("com.informix.jdbc.IfxDriver"); ….
7
Connect and Create Statement
… // connection URL String url = "jdbc:informixsqli://mymachine:1526/stores_demo” + “:INFORMIXSERVER=ol_myserver";
// get database connection Connection conn = DriverManager.getConnection(url, "informix", “mypasswd");
// create statement and execute query Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery( "select city, company from customer order by 1,2");%>…
8
JSP Example – Display Results
<table border=1><% // process result set while (rs.next()) { %> <tr> <td><b><%=rs.getString(1)%></b></td> <td><%=rs.getString(2)%></td> </tr><% } %></table>
9
JSP Example – Close Objects
<% // close ResultSet and Statement objectsrs.close();stmt.close();
// close connectionconn.close(); %></ul></body>
10
Error Handlingerror.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>
13
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
14
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
15
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>
16
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>
17
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");
18
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"/>
19
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>
20
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>
21
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") { … }
23
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
25
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
26
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>
27
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(); }
28
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();}
29
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
30
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();
%>
31
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
32
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
33
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>
34
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>
35
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);…
36
What is AJAX?
• Asynchronous JavaScript and XML
• Dynamically update parts of an HTML page by means of JavaScript calls to server routines
38
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
39
AJAX Example – Triggering the Update
Give an ID to the section of the page to update – in this case anHTML table column – the AJAX update is triggered here by movingthe 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>
40
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();
41
AJAX Example – Call Server Routines
var elementId = ''; // AJAX call to display contact details for a customer
function 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);}
42
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>
43
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
}
44
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/> …
45
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><%
}
46
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><% }