Download Results - Andrew.cmu.edu

Document related concepts
no text concepts found
Transcript
JDBC
1
2
3
4
Some introductory database terminology
Basic JDBC
Servlets
JDBC and servlets
Gary Alperson helped developed these slides.
Database Terminology
• Database:
A shared collection of logically related
data (and a description of this data) designed to meet the
information needs of an organization
• Relation: A table with columns and rows
• Attribute: A named column of a relation
• Tuple: A row in a relation
Definitions from Database Systems
by Connolly, Begg, and Strachan
Sample Table
broker
b_id lname
1
2
3
4
5
6
7
Smith
Jones
Reynolds
Chang
Smith
Thompson
Frendun
fname
John
Hannah
Leon
Donna
Deborah
Daniel
Laura
broker
b_id lname
1
2
3
4
5
6
7
Smith
Jones
Reynolds
Chang
Smith
Thompson
Frendun
fname
John
Hannah
Leon
Donna
Deborah
Daniel
Laura
Attribute
broker
b_id lname
Tuple
1
2
3
4
5
6
7
Smith
Jones
Reynolds
Chang
Smith
Thompson
Frendun
fname
John
Hannah
Leon
Donna
Deborah
Daniel
Laura
SQL
• Data Definition Language (DDL)
– Create tables
– Modify tables
– Delete (drop) tables
• Data Manipulation Language (DML)
– Insert data
– Update data
– Select data
Select Statement
We will use this data for our examples
broker
b_id lname
1
2
3
4
5
6
7
Smith
Jones
Reynolds
Chang
Smith
Thompson
Frendun
fname
John
Hannah
Leon
Donna
Deborah
Daniel
Laura
From the broker table, select the contents of
the last name attribute
Query
Results
lname
SELECT lname
FROM broker;
Smith
Jones
Reynolds
Chang
Smith
Thompson
Frendun
SQL is not case sensitive. Key SQL words are capitalized
and line breaks are inserted by convention.
From the broker table, select all attributes
Query
Results
broker
SELECT *
FROM broker;
b_id lname
1
2
3
4
5
6
7
* Acts as a wildcard
Smith
Jones
Reynolds
Chang
Smith
Thompson
Frendun
fname
John
Hannah
Leon
Donna
Deborah
Daniel
Laura
From the broker table, select all attributes
where the last name is Smith
Query
Results
broker
SELECT *
FROM broker
WHERE lname = ‘Smith’;
b_id lname
1 Smith
5 Smith
•Note that the string is enclosed by single quotes
•The contents of a string are case sensitive
fname
John
Deborah
Use AND or OR to connect multiple where
clauses
Query
SELECT *
FROM broker
WHERE lname = ‘Smith’
AND fname = ‘John’;
Results
b_id lname
1 Smith
fname
John
Example with two Tables
broker
b_id lname
1
2
3
4
5
6
7
Smith
Jones
Reynolds
Chang
Smith
Thompson
Frendun
fname
customer
customer
id b_id
John
Hannah
Leon
Donna
Deborah
Daniel
Laura
1
2
3
4
5
6
7
lname fname
1
1
2
2
2
3
4
LeParc Wilson
AnstinceDevon
Tabor Mark
Lenks Sandy
PhillipsonRichard
Kini
Raghu
Kim
David
One-to-many relationship
•Each broker may have many customers
•Each customer is only affiliated with one broker
•The b_id joins both tables by identifying the unique broker
that each customer is associated with
Cartesian Product
broker. broker. broker. id customer. broker. broker.
b_id
lname fname
b_id
lname fname
When you do a query on
multiple tables, SQL begins by
creating the Cartesian product,
which combines each tuple
from one relation from every
tuple of the other relation.
(Actual SQL implementations
are free to compute the resulting
table efficiently,i.e., the actual
Cartesian product may not
be generated at all.)
1
1
1
1
1
1
1
2
2
2
2
2
2
2
3
3
3
3
3
3
3
4
4
4
4
4
4
4
Smith
Smith
Smith
Smith
Smith
Smith
Smith
Jones
Jones
Jones
Jones
Jones
Jones
Jones
Reynolds
Reynolds
Reynolds
Reynolds
Reynolds
Reynolds
Reynolds
Chang
Chang
Chang
Chang
Chang
Chang
Chang
John
John
John
John
John
John
John
Hannah
Hannah
Hannah
Hannah
Hannah
Hannah
Hannah
Leon
Leon
Leon
Leon
Leon
Leon
Leon
Donna
Donna
Donna
Donna
Donna
Donna
Donna
1
2
3
4
5
6
7
1
2
3
4
5
6
7
1
2
3
4
5
6
7
1
2
3
4
5
6
7
1
1
2
2
2
3
4
1
1
2
2
2
3
4
1
1
2
2
2
3
4
1
1
2
2
2
3
4
LeParc
Anstince
Tabor
Lenks
Phillipson
Kini
Kim
LeParc
Anstince
Tabor
Lenks
Phillipson
Kini
Kim
LeParc
Anstince
Tabor
Lenks
Phillipson
Kini
Kim
LeParc
Anstince
Tabor
Lenks
Phillipson
Kini
Kim
Wilson
Devon
Mark
Sandy
Richard
Raghu
David
Wilson
Devon
Mark
Sandy
Richard
Raghu
David
Wilson
Devon
Mark
Sandy
Richard
Raghu
David
Wilson
Devon
Mark
Sandy
Richard
Raghu
David
Query
SELECT *
FROM customer, broker
WHERE broker.b_id = 1;
Results
broker. broker. broker. id customer. broker. broker.
b_id
lname fname
b_id
lname fname
1
1
1
1
1
1
1
Smith
Smith
Smith
Smith
Smith
Smith
Smith
John
John
John
John
John
John
John
1
2
3
4
5
6
7
1
1
2
2
2
3
4
LeParc
Anstince
Tabor
Lenks
Phillipson
Kini
Kim
Wilson
Devon
Mark
Sandy
Richard
Raghu
David
SQL does not realize that the b_id in the customer table is the
same as the b_id in the broker table unless you join them in the
where clause.
Cartesian Product
Query
SELECT *
FROM customer, broker
WHERE broker.b_id = 1
AND broker.b_id = customer.b_id;
Results
broker. broker. broker. id customer. broker. broker.
b_id
lname fname
b_id
lname fname
1 Smith
1 Smith
John
John
1
2
1 LeParc
Wilson
1 Anstince Devon
Java’s JDBC
• Allows access to any ANSI SQL-2 DBMS
• Does its work in terms of SQL
• The JDBC has classes that represent:
database connections
SQL Statements
Result sets
database metadata
• Can be connected to ODBC
• Many drivers exists
Basic Steps in using JDBC
1. Create a driver object.
2. The driver object will inform the Driver Manager that it is available
3. Create a database URL. This needs to point to the database to
which you want to connect.
4. Ask the DriverManager for a Connection object. The manager
must be told what driver you need and the URL in 3.
5. Get a Statement object from the Connection.
6. Execute a query or an update on the Statement.
7. Handle results.
8. Close the connection.
Create the driver
Example:
Class.forName(“oracle.jdbc.driver.OracleDriver”).newInstance();
When a new instance of the driver is created it will inform
the DriverManager class of its existence.
Create the database URL
The exact format depends on the particular driver.
Examples:
String host = “dbhost.yourcompany.com”;
String dbName = “somename”;
int port = 1234;
String oracleURL = “jdbc:oracle:thin@” + host +
“:” + port + “:” + dbName;
Build a Connection object
• java.sql.Connection is an interface
• Within the context of a Connection, SQL statements are executed
and results are returned.
• A Connection object is able to provide information describing
the database as a whole through its getMetaData method().
• The default Connection automatically commits changes after
executing each statement. If auto commit has been disabled,
an explicit commit must be done or database changes will not
be saved.
Build a Connection object
Connection c = DriverManager.getConnection( oracleURL,
“mm6”,
“seseme”);
Get a Statement from the
Connection
The Statement interface has two subinterfaces
•
PreparedStatement extends Statement
This is an object that represents a precompiled SQL
statement.
•
CallableStatement extends PreparedStatement
The interface used to execute SQL stored procedures.
Get a Statement from the
Connection
c.setAutoCommit(false);
Statement s = con.createStatement();
s.executeUpdate(command1);
s.executeUpdate(command2);
e.executeUpdate(command3);
// Now we are free to
c.commit();
// or..
c.rollback();
The Statement Object may
produce a ResultSet
ResultSet rs = s.executeQuery(“SELECT * FROM Broker”);
while (rs.next()) {
// examine each row of the result set
String n = rs.getString(columnNumber);
double f = rs.getDouble(“SomeColumnName”);
}
// each get method tries to make a reasonable type conversion
// get may be used with integer column numbers starting
// at 1 or a column name
The Statement Object may return
an int
int rowsChanged = s.executeUpdate(“CREATE TABLE” + … );
Executes an SQL INSERT, UPDATE or DELETE statement.
In addition, SQL statements that return nothing, such as
SQL DDL statements, can be executed.
Returns:
either the row count for INSERT, UPDATE or DELETE
or 0 for SQL statements that return nothing
Throws:
SQLException - if a database access error occurs
An Example
From both tables select the last names of all customers whose
broker’s last name is Smith but whose broker ID is not 1.
The SQL
SELECT customer.lname
FROM customer, broker
WHERE broker.lname = ‘Smith’
AND broker.b_id <> 1
AND broker.b_id = customer.b_id;
Executing a query in Java
// Statement aStatement = statement got from connection
String last = “Smith”;
int nonID = 1;
String q = “SELECT customer.lname FROM customer, broker” +
“WHERE broker.lname = \’” + last + “\’ AND broker.b_id” +
“<>” + nonID + “AND broker.b_id = customer.b_id;”);
ResultSet rs = aStatement.executeQuery(q);
•The slash (\) is the escape character. It precedes the single quote to tell Java
to include that quote in the String
•The String last is outside of the double quotes, because it must be
concatonated with the String sent to the database, but it falls within the single
quotes so that SQL treats it as a string
•nonID does not go within single quotes since it is numeric
•Since the String is an SQL statement, it uses = and <> rather than == and !=
Java Servlets
• Part I Server and servlet basics
• Part II Session Tracking and Servlet
Collaboration
• Part III Connecting to database
Part I : Server and Servlet Basics
•
•
•
•
NetworkServer.java and EchoServer.java
PostForm.html
GetForm.html
More HTML form examples
NetworkServer.java
// NetworkServer.java
Adapted from "Core Servlets
// and Java Server Pages"
// by Marty Hall
No Tomcat server.
import java.net.*;
Just this code.
import java.io.*;
public class NetworkServer {
private int port;
private int maxConnections;
protected void setPort(int port) { this.port = port; }
public int getPort() { return port; }
protected void setMaxConnections(int max) {
maxConnections = max;
}
public int getMaxConnections() { return maxConnections; }
public NetworkServer(int port, int maxConnections) {
setPort(port);
setMaxConnections(maxConnections);
}
// Wait for a connections until maxConnections.
// On each connection call handleConnection() passing
// the socket. If maxConnections == 0 loop forever
public void listen() {
int i = 0;
try {
ServerSocket listener = new ServerSocket(port);
Socket server ;
while((i++ < maxConnections) || (maxConnections == 0)) {
server = listener.accept(); // wait for connection
handleConnection(server);
}
} catch (IOException ioe) {
System.out.println("IOException : " + ioe);
ioe.printStackTrace();
}
}
// Open readers and writers to socket.
// Display client's host name to console.
// Read a line from the client and display it on the console.
// Send "Generic network server" to the client.
// Override this method.
protected void handleConnection(Socket server)
throws IOException {
BufferedReader in = new BufferedReader( InputStream for
reading bytes
new InputStreamReader(
server.getInputStream() ));
Flush buffer
on println
PrintWriter out = new PrintWriter(
server.getOutputStream(),true);
Readers and Writers
to work with characters
System.out.println("Generic network server: got connection from "+
server.getInetAddress().getHostName() + "\n" +
"with first line '" + in.readLine() + "'");
out.println("Generic network server");
To server’s
server.close();
console.
}
To client.
public static void main(String args[]) {
NetworkServer test = new NetworkServer(6502, 5);
test.listen();
}
}
Compile, Run and Visit
Client
Server
C:\McCarthy\www\46-928\examples\networking>java NetworkServer
Generic network server: got connection from localhost
with first line 'GET / HTTP/1.0'
EchoServer.java
/* From Core Servlets, Marty Hall
An HTTP Request header example Notes
GET /path/file.html HTTP/1.0
Accept: text/html
Accept: audio/x
User-agent: MacWeb
Request terminated by two returns
HTTP defines dozens of
possible headers.
The whitespace is required.
Accept header fields
tell the server MIME types
(Multipurpose Internet
Mail Extension)
that are handled by the
browser.
Still no Tomcat
EchoServer.java
An HTTP Response header example
HTTP 1.0 200 OK
Server: NCSA/1.4.2
MIME-version: 1.0
Content-type: text/html
Content-length: 107
Response code
MIME type
Blank line
<html>
:
:
</html>
The client must interpret
this MIME encoded data.
HTTP General form
<method> <resource identifier> <HTTP Version> <crlf>
[<Header> : <value>] <crlf>
: : :
[<Header> : <value>] <crlf>
a blank line
[entity body]
The resource identifier field specifies the name of the target
resource; it's the URL stripped of the protocol and the server
domain name. When using the GET method, this field will also
contain a series of name=value pairs separated by ‘&’. When using
a POST method, the entity body contains these pairs.
The HTTP version identifies the protocol used by the client.
*/
// Adapted from Core Servlets and JavaServerPages
// by Marty Hall, chapter 16
import java.net.*;
import java.io.*;
import java.util.StringTokenizer;
public class EchoServer extends NetworkServer {
protected int maxRequestLines = 50;
// Post data is brought in
// as a single string.
protected String serverName = "EchoServer";
public static void main(String a[]) {
int port = 6502;
new EchoServer(port,0);
}
// loop forever
public EchoServer(int port, int maxConnections) {
super(port,maxConnections); // call base class constructor
listen();
// call base class listen()
}
// listen calls handleConnection()
// Overrides base class handleConection and is called by listen()
public void handleConnection(Socket server) throws IOException {
// Assign readers and writers to the socket
BufferedReader in = new BufferedReader(
new InputStreamReader(
server.getInputStream() ));
PrintWriter out = new PrintWriter(server.getOutputStream(),true);
// Announce connection to console
System.out.println(serverName + " got connection from "+
server.getInetAddress().getHostName() + "\n");
String inputLines[] = new String[maxRequestLines];
int i;
for(i = 0; i < maxRequestLines; i++) {
inputLines[i] = in.readLine();
if(inputLines[i] == null) break; // client closed connection
if(inputLines[i].length() == 0) { // blank line
// maybe done or maybe post
if(usingPost(inputLines)) {
// readPostData reads into a single string
// at location i+1
readPostData(inputLines,i,in);
// i was not changed in the procedure so
// bump it one past the post data string
i = i + 2;
}
break;
// we’re done either way
}
}
}
printHeader(out);
for(int j = 0; j < i; j++) {
out.println(inputLines[j]);
}
// HTTP + HTML
printTrailer(out);
server.close();
// Closing HTML
//Request Data
private void printHeader(PrintWriter out) {
HTTP Response
out.println(
headers plus HTML.
"HTTP/1.0 200 OK\r\n"
+
"Server: " + serverName + "\r\n" +
"Content-Type: text/html\r\n" + “\r\n” +
"<!DOCTYPE HTML PUBLIC "
+
"\"-//W3C//DTD HTML 4.0 Transitional//EN\">\n" +
"<HTML>\n"
+
"<HEAD>\n"
+
" <TITLE>" + serverName + " Results</TITLE>\n" +
"</HEAD>\n"
+
"\n" + "<BODY BGCOLOR=\"#FDF5E6\">\n" +
"<H1 ALIGN=\"CENTER\">" + serverName +
" Results</H1>\n" +
"Here is your request line and request headers\n" +
"sent by your browser:\n" +
"<PRE>“ );
// honors whitespace
}
private void printTrailer(PrintWriter out) {
// Close HTML
out.println("</PRE>\n" +
"</BODY>\n" +
"</HTML>\n");
}
// Checks if post
private boolean usingPost(String[] inputs) {
return (inputs[0].toUpperCase().startsWith("POST"));
}
// Read the post data as a single array of char and place it all
// in one string.
private void readPostData (String inputs[], int i, BufferedReader in)
throws IOException {
int contentLength = contentLength(inputs);
char postData[] = new char[contentLength];
in.read(postData, 0, contentLength);
// All of the post data is converted to a single string
inputs[++i] = new String(postData,0,contentLength);
}
// The header fields may arrive in any order.
// Search for and return the CONTENT-LENGTH.
private int contentLength(String inputs[]) {
String input;
for(int i = 0; i < inputs.length; i++) {
if(inputs[i].length() == 0) break;
input = inputs[i].toUpperCase();
if(input.startsWith("CONTENT-LENGTH")) return (getLength
}
return (0);
}
// Return the integer associated with the second token.
private int getLength(String length) {
StringTokenizer tok = new StringTokenizer(length);
tok.nextToken();
return (Integer.parseInt(tok.nextToken()));
}
}
PostForm.html
<!-- PostForm.html -->
<html>
<head>
<title>Post Form</title>
Visit the port
</head>
<body>
<form method="post" action="http://localhost:6502">
Hi, what is your name?
<input type="text" name = "name"> <p>
What is your age?
<input type="text" name = "age"> <p>
<input type = "submit">
</form>
</body>
</html>
PostForm.html Browser
EchoServer Response Using POST
Size of
POST data
Name value pairs
with spaces as ‘+’
etc.
GetForm.html
<!-- GetForm.html -->
<html>
<head>
<title>Get Form</title>
</head>
<body>
<form method="get" action="http://localhost:6502">
Hi, what is your name?
<input type="text" name = "name"> <p>
What is your age?
<input type="text" name = "age"> <p>
<input type = "submit">
</form>
</body>
</html>
GetForm.html Browser
EchoServer Response Using GET
GET data
A Form With Checkboxes
<!-- CheckBox.html -->
<html>
<head>
<title>CheckBoxes</title>
</head>
<body BGCOLOR="WHITE">
<form action="http://localhost:6502">
<dl>
<dt> Select Pizza Toppings </dt>
<dd><Input type = "CheckBox" name = "Pepperoni"> Pepperoni
<dd><Input type = "CheckBox" name = "Sausage"> Sausage
<dd><Input type = "CheckBox" name = "Extra Cheese"> Extra Cheese
<dd><Input type = "CheckBox" name = "Mushrooms"> Mushrooms
<p> <input type = "submit">
</dl>
</form>
</body>
CheckBoxes Browser
CheckBox Response
Data from client
RadioBoxes HTML
<!-- Radio.html -->
<html>
<head>
<title>Radio Buttons</title>
</head>
<body BGCOLOR="WHITE">
<form action="http://localhost:6502">
<dl>
<dt> Please Vote </dt>
<!– Definition list -->
<!- The term to be defined left margin-->
<!-- Item definitions indented and below -->
<dd><Input type = "Radio" name = "president" value= "Bush"> <b>George W. Bush</b>
<dd><Input type = "Radio" name = "president" value = "Gore"> Al Gore
<dd><Input type = "Radio" name = "president" value = "Buchanan"> Pat Buchanan
<dd><Input type = "Radio" name = "president" value = "Nader"> Ralph Nader
<p> <input type = "submit">
</dl>
</form>
</body>
</html>
RadioBoxes Browser
EchoServer Response
Reading Form Data With Servlets
Under Tomcat
// QueryData.java -- Handle the voting form in radio.html
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
We have less
work to do.
public class QueryData extends HttpServlet {
public void doPost(HttpServletRequest req,
HttpServletResponse response)
throws ServletException,
IOException {
doGet(req, response);
}
public void doGet(HttpServletRequest req,
HttpServletResponse response)
throws ServletException,
IOException
{
String newPresident = req.getParameter("president");
response.setContentType("text/html");
PrintWriter out = response.getWriter();
String docType = "<!DOCTYPE HTML PUBLIC \"//W3C//DTD” +
“HTML 4.0 ";
docType += "Transitional//EN\">\n";
out.println(docType + "<HTML>\n" +
"<HEAD><TITLE>Presidential Servlet" + "</TITLE>” +
“</HEAD>\n" +
"<BODY>\n" +
"<H1>The new president is "+ newPresident + "</H1>\n" +
"</BODY></HTML>");
}
}
<!-- Radio.html (Modified for servlets)-->
<html>
<head>
Tomcat’s port
<title>Radio Buttons</title>
servlet
</head>
<body BGCOLOR="WHITE">
<form action="http://localhost:8080/servlet/QueryData">
<dl>
<dt> Please Vote </dt>
<dd><Input type = "Radio" name = "president" value= "Bush">
<b>George W. Bush</b>
<dd><Input type = "Radio" name = "president" value = "Gore"> Al Gore
<dd><Input type = "Radio" name = "president" value = "Buchanan"> Pat Buchan
<dd><Input type = "Radio" name = "president" value = "Nader"> Ralph Nader
<p> <input type = "submit">
</dl>
</form>
</body>
</html>
Radio HTML in the browser
The Servlet’s Response
Handling CheckBoxes
<!-- CheckBox.html -->
<html>
<head>
servlet
<title>CheckBoxes</title>
</head>
<body BGCOLOR="WHITE">
<form action="http://localhost:8080/servlet/PizzaData">
<dl>
<dt> Select Pizza Toppings </dt>
<dd><Input type = "CheckBox" name = "Pepperoni"> Pepperoni
<dd><Input type = "CheckBox" name = "Sausage"> Sausage
<dd><Input type = "CheckBox" name = "Extra Cheese"> Extra Cheese
<dd><Input type = "CheckBox" name = "Mushrooms"> Mushrooms
<p> <input type = "submit">
</dl>
</form>
</body>
Pizza Toppings
Servlet Response
PizzaData Servlet
// PizzaData.java -- Handle the toppings selection from pizza.html
import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class PizzaData extends HttpServlet {
public void doPost(HttpServletRequest req,
HttpServletResponse response)
throws ServletException,
IOException {
doGet(req, response);
}
public void doGet(HttpServletRequest req,
HttpServletResponse response)
throws ServletException,
Enumerate over the
IOException
input.
{
response.setContentType("text/html");
PrintWriter out = response.getWriter();
String finalString = "";
Enumeration paramNames = req.getParameterNames();
while(paramNames.hasMoreElements()) {
String paramName = (String) paramNames.nextElement();
finalString += paramName + ":" ;
finalString += req.getParameter(paramName) + "<p>";
}
String docType = "<!DOCTYPE HTML PUBLIC \"//W3C//DTD”
+ “ HTML 4.0 ";
docType += "Transitional//EN\">\n";
out.println(docType +
"<HTML>\n" +
"<HEAD><TITLE>Pizza Selections" + "</TITLE>” +
“</HEAD>\n" +
"<BODY>\n" +
"<H1>" + finalString + "</H1>\n" +
"</BODY></HTML>");
}
}
Part II Session Tracking and
Servlet Collaboration
• First we will use a shared object
• Then we’ll use the new Session Tracking API
Session Tracking with Servlets
HTTP is a stateless protocol.
We must have each user introduce themselves in some way.
We’ll look at traditional session tracking and then look at the
Session Tracking API.
Traditional Session Tracking
• User Authorization
• Hidden Form fields
• URL Rewriting
• Persistent cookies
We’ll look at the first and last.
User Authorization
• The web server requests the user name and password.
The information is available to any servlet that needs it.
• The browser resends the name and password with each
subsequent request.
• Data about the user and the user’s state can be saved in a shared
object.
Shared Objects
• A convenient way to store data associated with a user.
•There are likely to be many servlets running.
• They can collaborate through a shared object.
• Only one instance of the shared object should exist.
• It has to be available (in the classpath) of the servlets
that needs it.
• It will be used by several threads and therefore should
protect itself against simultaneous access.
• We’ll look at a shared object and two servlets that use it.
VisitTracker.java
// Servlet collaboration can be done through a shared object.
// Any servlet has access to this object and it only has one
// instance.
// It maintains a hash table of names and dates.
// Sections of code that must not be executed simultaneously
// are called critical sections. Java provides the synchronized
// keyword to protect these critical sections. For a synchronized
// instance method, Java obtains an exclusive lock on the class
// instance.
import java.util.*;
public class VisitTracker {
private Map nameDatePairs;
private static VisitTracker instance = new VisitTracker();
private VisitTracker() {
// private constructor
nameDatePairs = new HashMap();
}
public static VisitTracker getInstance() { return instance; }
synchronized public void addVisit(String userName) {
nameDatePairs.put(userName, new Date());
}
synchronized public Date lastVisit(String name) {
Date d = (Date)nameDatePairs.get(name);
return d;
}
}
User Authorization
• Administered by the web server – Tomcat
• Edit Tomcat’s deployment descriptor
• From within the servlet use String name = req.getRemoteUser();
to access the user name.
• We have to assign user names and passwords.
tomcat-users.xml
<tomcat-users>
<user name="tomcat" password="tomcat" roles="tomcat" />
<user name="role1" password="tomcat" roles="role1" />
<user name="both" password="tomcat" roles="tomcat,role1" />
<user name="mike" password="tomcat" roles="student" />
</tomcat-users>
• The following will keep track of the date of the last visit.
// UserAuthorizationDemo.java
// This servlet reads from Tomcat and finds the name of the
// authorized user. It then adds it to a hash table storing
// the time of this visit. It makes use of VisitTracker.
import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class UserAuthorizationDemo extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
res.setContentType("text/plain");
PrintWriter out = res.getWriter();
String name = req.getRemoteUser(); // ask the server
if(name == null) {
System.out.println("The system administrator should protect" +
" this page.");
}
else {
out.println("This user was authorized by the server:" + name);
VisitTracker visit = VisitTracker.getInstance();
Date last = visit.lastVisit(name);
if(last == null) out.println("Welcome, you were never here before");
else out.println("Your last visit was on " + last);
visit.addVisit(name);
}
}
}
Cookies
• A cookie is a bit of information sent by a web server
to a browser that can later be read back from that browser.
• The server can take that bit of information and use it as a
key to recover information about prior visits. This
information may be in a database or a shared object.
• Cookies are read from the request object by calling
getCookies() on the request object.
• Cookies are placed in the browser by calling addCookie()
on the response object.
Using Cookies
// CookieDemo.java
// This servlet uses a cookie to determine when the
// last visit by this browser occurred. It makes use of
// the VisitTracker object.
// Cookies normally expire as soon as the browser exits.
// We want the cookie to last one year and so we use
// setMaxAge(seconds) on the cookie.
import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class CookieDemo extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse res
throws ServletException, IOException {
res.setContentType("text/plain");
PrintWriter out = res.getWriter();
Cookie[] c = req.getCookies();
// If this person has been here before then we should have
// a cookiedemouser field assigned to a unique id.
String id = null;
if (c!=null) { // we may have the cookie we are after
for (int i=0;i<c.length;i++) {
if (c[i].getName().equals("cookiedemouser")) {
id = c[i].getValue();
}
break;
}
}
if (id == null) {
// They have not been here before and need a
// cookie. We get a unique string (with respect
// to this host)and make sure it is of the 'query string' form.
// It uses the clock. Don’t turn the clock back!
String uid = new java.rmi.server.UID().toString();
id = java.net.URLEncoder.encode(uid);
Cookie oreo = new Cookie("cookiedemouser",id);
oreo.setMaxAge(60*60*24*365);
res.addCookie(oreo);
}
VisitTracker visit = VisitTracker.getInstance();
Date last = visit.lastVisit(id);
if(last == null) out.println("Welcome, you were never here befor
else out.println("Your last visit was on " + last);
visit.addVisit(id);
}
The New Session Tracking API
• Support may vary depending on the server.
• Implemented with cookies or with URL rewriting if cookies
fail (URL rewriting requires help from the servlet).
• Every user of the site is associated with a
javax.servlet.http.HttpSession object
• The session object can hold any arbitrary set of Java objects.
• Servlets collaborate by accessing the session object.
• The following example abstracts away shared object concerns.
• All valid sessions are grouped together in a HttpSessionContext
object
The Session Tracking API
// SessionDemo.java
// The session object associated with this user/browser is available
// to other servlets.
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import java.util.*;
public class SessionDemo extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
res.setContentType("text/plain");
PrintWriter out = res.getWriter();
// Get the current session object. Create one if none exists.
HttpSession session = req.getSession(true);
// Get the Date associated with this session
Date d = (Date)session.getAttribute("dateofvisit");
if(d == null) out.println("Your first time, welcome!");
else out.println("Your last visit was on " + d);
session.setAttribute("dateofvisit", new Date());
}}
Part III Connecting to the
database
Notes taken from “Java Programming with Oracle JDBC”
By Donald Bales
Per-Transaction Connections
Dedicated Connections
Session Connections
Per-Transaction Connection
Each visit gets its own connection.
Servlet
init() {
load the driver and inform the DriverManager
}
doxxx() {
get a connection
:
operate on statements, result sets…
:
close connection
}
Per-Transacation Connection
// Form Oracle JDBC by Bales
import java.io.*;
import java.sql.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class TransactionConnectionServlet extends HttpServlet {
public void init(ServletConfig config) throws ServletException {
super.init(config);
try {
// load the driver
Class.forName("oracle.jdbc.driver.OracleDriver").newInstance();
}
catch (ClassNotFoundException e) {
throw new UnavailableException(
"TransactionConnection.init() ClassNotFoundException: " +
e.getMessage());
}
catch (IllegalAccessException e) {
throw new UnavailableException(
"TransactionConnection.init() IllegalAccessException: " +
e.getMessage());
}
catch (InstantiationException e) {
throw new UnavailableException(
"TransactionConnection.init() InstantiationException: " +
e.getMessage());
}
}
public void doGet (HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("<html>");
out.println("<head>");
out.println("<title>A Per Transaction Connection</title>");
out.println("</head>");
out.println("<body>");
Connection connection = null;
try {
// establish a connection
connection = DriverManager.getConnection(
"jdbc:oracle:thin:@dssw2k01:1521:orcl", "scott", "tiger");
}
catch (SQLException e) {
throw new UnavailableException(
"TransactionConnection.init() SQLException: " +
e.getMessage());
}
Statement statement = null;
ResultSet resultSet = null;
String userName = null;
try {
// test the connection
statement = connection.createStatement();
resultSet = statement.executeQuery(
"select initcap(user) from sys.dual");
if (resultSet.next())
userName = resultSet.getString(1);
}
catch (SQLException e) {
out.println(
"TransactionConnection.doGet() SQLException: " +
e.getMessage() + "<p>");
}
finally {
if (resultSet != null)
try { resultSet.close(); } catch (SQLException ignore) { }
if (statement != null)
try { statement.close(); } catch (SQLException ignore) { }
}
if (connection != null) {
// close the connection
try { connection.close(); } catch (SQLException ignore) { }
}
out.println("Hello " + userName + "!<p>");
out.println("You're using a per transaction connection!<p>");
out.println("</body>");
out.println("</html>");
}
public void doPost(
HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
doGet(request, response);
}
}
A Dedicated Connection
Servlet
init() {
load driver and inform manager
open connection
}
doxxx() {
use connection
commit transaction
}
destroy {
when servlet container is brought down
close the connection
}
A Dedicated Connection
One connection per servlet
Open during life of servlet
All users of this servlet use the same connection
Oracle’s connection class’s methods are thread safe
Under this approach, servlets do not share connections
A Dedicated Connection
// From the book Oracle JDBC by Bales
import java.io.*;
import java.sql.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class DedicatedConnectionServlet extends HttpServlet {
Connection connection;
long
connected;
public void init(ServletConfig config)
throws ServletException {
super.init(config);
try {
// load the driver
Class.forName("oracle.jdbc.driver.OracleDriver").newInstance();
}
catch (ClassNotFoundException e) {
throw new UnavailableException(
"DedicatedConnection.init() ClassNotFoundException: " +
e.getMessage());
}
catch (IllegalAccessException e) {
throw new UnavailableException(
"DedicatedConnection.init() IllegalAccessException: " +
e.getMessage());
}
catch (InstantiationException e) {
throw new UnavailableException(
"DedicatedConnection.init() InstantiationException: " +
e.getMessage());
}
try {
// establish a connection
connection = DriverManager.getConnection(
"jdbc:oracle:thin:@dssw2k01:1521:orcl", "scott", "tiger");
connected = System.currentTimeMillis();
}
catch (SQLException e) {
throw new UnavailableException(
"DedicatedConnection.init() SQLException: " +
e.getMessage());
}
}
public void doGet(
HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("<html>");
out.println("<head>");
out.println("<title>A Dedicated Connection</title>");
out.println("</head>");
out.println("<body>");
Statement statement = null;
ResultSet resultSet = null;
String userName = null;
try { // test the connection
statement = connection.createStatement();
resultSet = statement.executeQuery(
"select initcap(user) from sys.dual");
if (resultSet.next())
userName = resultSet.getString(1);
}
catch (SQLException e) {
out.println(
"DedicatedConnection.doGet() SQLException: " +
e.getMessage() + "<p>");
}
finally {
if (resultSet != null)
try { resultSet.close(); } catch (SQLException ignore) { }
if (statement != null)
try { statement.close(); } catch (SQLException ignore) { }
}
out.println("Hello " + userName + "!<p>");
out.println(
"This Servlet's database connection was created on " +
new java.util.Date(connected) + "<p>");
out.println("</body>");
out.println("</html>");
}
public void doPost(
HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
doGet(request, response);
}
public void destroy() {
// close the connection
if (connection != null)
try { connection.close(); } catch (SQLException ignore) { }
}
}
A Session Connection
Servlet
init() {
load the driver and inform the driver manager
}
doxxx() {
establish an HTTP Session object that holds
the database connection
If the session expires we must notify
the connection to close
}
A Session Connection
We need an HTTPSessionBindingListener to close the
connection when the session expires.
HTTPSession
SessionConnection
Implements HTTPSessionBindingListener
When this session expires the system will call the valueUnBound()
method in the HTTPSessionBindingListener.
SessionConnection
// From Oracle JDBC by Bales
import java.sql.*;
import javax.servlet.http.*;
public class SessionConnection
implements HttpSessionBindingListener {
Connection connection;
public SessionConnection() {
connection = null;
}
public SessionConnection(Connection connection) {
this.connection = connection;
}
public Connection getConnection() {
return connection;
}
public void setConnection(Connection connection) {
this.connection = connection;
}
public void valueBound(HttpSessionBindingEvent event) {
if (connection != null) {
System.out.println("Binding a valid connection");
}
else {
System.out.println("Binding a null connection");
}
}
public void valueUnbound(HttpSessionBindingEvent event) {
if (connection != null) {
System.out.println(
"Closing the bound connection as the session expires");
try { connection.close(); } catch (SQLException ignore) { }
}
}
}
SessionLogin
import java.io.*;
import java.sql.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class SessionLogin extends HttpServlet {
public void init(ServletConfig config)
throws ServletException {
super.init(config);
try {
// load the driver
Class.forName("oracle.jdbc.driver.OracleDriver").newInstance();
}
catch (ClassNotFoundException e) {
throw new UnavailableException(
"Login init() ClassNotFoundException: " + e.getMessage());
}
catch (IllegalAccessException e) {
throw new UnavailableException(
"Login init() IllegalAccessException: " + e.getMessage());
}
catch (InstantiationException e) {
throw new UnavailableException(
"Login init() InstantiationException: " + e.getMessage());
}
}
public void doGet(
HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("<html>");
out.println("<head>");
out.println("<title>Login</title>");
out.println("</head>");
out.println("<body>");
HttpSession session = request.getSession();
SessionConnection sessionConnection =
(SessionConnection)session.getAttribute("sessionconnection");
Connection connection = null;
if (sessionConnection != null) {
connection = sessionConnection.getConnection();
}
if (connection == null) {
String userName = request.getParameter("username");
String password = request.getParameter("password");
if (userName == null || password == null) {
// prompt the user for her username and password
out.println("<form method=\"get\" action=\"SessionLogin\">");
out.println("Please specify the following to log in:<p>");
out.println("Username: <input type=\"text\" " +
"name=\"username\" size=\"30\"><p>");
out.println("Password: <input type=\"password\" " +
"name=\"password\" size=\"30\"><p>");
out.println("<input type=\"submit\" value=\"Login\">");
out.println("</form>");
}
else { // create the connection
try {
connection = DriverManager.getConnection(
"jdbc:oracle:thin:@dssw2k01:1521:orcl", userName, password);
}
catch (SQLException e) {
out.println("Login doGet() " + e.getMessage());
}
if (connection != null) {
// store the connection
sessionConnection = new SessionConnection();
sessionConnection.setConnection(connection);
session.setAttribute("sessionconnection", sessionConnection);
response.sendRedirect("SessionLogin");
return;
}
}
}
else {
String logout = request.getParameter("logout");
if (logout == null) {
// test the connection
Statement statement = null;
ResultSet resultSet = null;
String userName = null;
try {
statement = connection.createStatement();
resultSet = statement.executeQuery(
"select initcap(user) from sys.dual");
if (resultSet.next())
userName = resultSet.getString(1);
}
catch (SQLException e) {
out.println("Login doGet() SQLException: " + e.getMessage()
+ "<p>");
finally {
if (resultSet != null)
try { resultSet.close(); } catch (SQLException ignore) { }
if (statement != null)
try { statement.close(); } catch (SQLException ignore) { }
}
out.println("Hello " + userName + "!<p>");
out.println("Your session ID is " + session.getId() + "<p>");
out.println("It was created on " +
new java.util.Date(session.getCreationTime()) + "<p>");
out.println("It was last accessed on " +
new java.util.Date(session.getLastAccessedTime()) + "<p>");
out.println("<form method=\"get\" action=\"SessionLogin\">");
out.println("<input type=\"submit\" name=\"logout\" " +
"value=\"Logout\">");
out.println("</form>");
}
else {
// close the connection and remove it from the session
try { connection.close(); } catch (SQLException ignore) { }
session.removeAttribute("sessionconnection");
out.println("You have been logged out.");
}
}
out.println("</body>");
out.println("</html>");
}
public void doPost(
HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
doGet(request, response);
}
}
Related documents