Upload
garry-powers
View
217
Download
0
Embed Size (px)
Citation preview
SE 370: Programming Web Services
Week 6: Cron, SSL, & SOAPCopyright © Steven W. Johnson
February 1, 2013
Chronos: Greek god of time
Cron is a time-based scheduler
Unix-based tool
Runs jobs at specific times, fixed intervals
Cron:
4
A daemon (dee-muhn):
“an attendant power, or spirit”
runs in the background
handles service requests
calls other programs, processes as needed
executes commands based on time, events
runs when called (dormant)
Cron:
5
Typical uses:
system maintenance
routine messaging (email advertisements)
system administration
routine audit reports
regular accounting reports
inventory control
Cron:
6
Utility that is part of (housed on) a web server
Must be ‘turned on’
Holds a list of files to be run at specific times
Executes the files as directed
Cron:
7
* * * * * command to be executed ┬ ┬ ┬ ┬ ┬ │ │ │ │ │ │ │ │ │ │ │ │ │ │ └───── day of week (0 - 7) (0 or 7 are Sunday, or use names) │ │ │ └────────── month (1 - 12) │ │ └─────────────── day of month (1 - 31) │ └──────────────────── hour (0 - 23) └───────────────────────── min (0 - 59)
* = “any or all if applies”
01 * * * * root echo "This command is run at one min past every hour" 17 8 * * * root echo "This command is run daily at 8:17 am" 17 20 * * * root echo "This command is run daily at 8:17 pm" 00 4 * * 0 root echo "This command is run at 4 am every Sunday" 4 * * Sun root echo "So is this" 42 4 1 * * root echo "This command is run 4:42 am every 1st of the month" 01 * 19 07 * root echo "This command is run hourly on the 19th of July“
Cron:
9
Basic form of the Corn command (Unix):
Cron:
1010
Minutes [0-59] | Hours [0-23] | | Days [1-31] | | | Months [1-12] | | | | Days of the Week [Numeric, 0-6]| | | | | * * * * * absolutepath.html
30 8 * * 6 //Every Saturday at 8:30 am
0 0 1 * * //midnight first day of month
0 */2 * * * //Every other hour (0, 2, 4)
Files needed found in ‘UniServerCron’ folder
UniServer’s version of Cron, cron.ini
Web server based Cron
UniServer Cron:
11
UniServer Cron is 64-bit
Must edit with Notepad++
Install Notepad++ and change association in Cron
Change association:
Folders menu
Change default program
Re-start computer
UniServer Cron:
13
Other (better) fix:
Change configuration fileC:\UniServer\uni_con\config_menu\main_menu.html
Replace ‘notepad’ with ‘notepad++’ (many times)
UniServer Cron:
14
;##############################################################################;# Uniform Server Cron Configuration cron.ini ;# Used by script run_cron.vbs;# V1.0;# ----------------------------------------------------------------------------;# 1) Web applications that require a script to be periodically run (cron job) ;# specify a URL path (what you would type into a browser) to run that script.;# 2) Command-line scripts (.bat,.php,.vbs) require an absolute path to be specified.;# 3) Each script to run is defined in a separate block with the following format:;# [dtdns] – Each block starts with a unique name enclosed in square brackets;# note no spaces allowed.;# start = - Initial start time. With the following format:;# Y-M-D H:M:S - Note: 24 hour clock;# period = - How often to run script from the above reference start time;# Values: hourly, daily, weekly, monthly or numeric in seconds ;# path = - a) For a web applications full URL of the script.;# e.g. http://localhost/drupal/cron.php;# b) Command-line (CLI) use an absolute path with back-slashes;# e.g. C:\UniServer\uni_con\cron\test_cron_1.bat;# ref = - A timestamp updated by cron script. Set initial value to blank;#;# Note 1 Cron automatically updates (ref). Initially adds start-time set above;# to period. Subsequent runs, set ref to current time + period. ;# Note 2 To change start time first set a new value for start and delete the;# ref number, save file. The script will run at the new date and time;# set and there after at a rate you defined for period. ;# 4) To use pre-configured CLI blocks dtdns and db_backup uncomment to enable.;# 5) To use pre-configured web blocks drupal and moodle uncomment to enable.;# Note: Command-line paths to scripts contained in sub-folders bellow UniServer;# are automatically updated (portable). Paths outside UniServer require;# manually changing.;##############################################################################
16
;[dtdns];start = 2011-04-7 13:20:00 ;period = 600 ; 10 Mins as required by DtDNS;path = C:\UniServer\uni_con\dtdns_updater\Run_dtdns_updater.bat;ref =
;[db_backup];start = 2011-09-21 2:00:00;period = hourly;path = C:\UniServer\uni_con\db_backup\Run_db_backup.bat;ref =
;[moodle];start = 2011-09-21 2:10:00;period = hourly;path = http://localhost/moodle/admin/cron.php;ref =
;[drupal];start = 2011-09-21 2:30:00;period = hourly;path = http://localhost/drupal/cron.php;ref =
;[Test_cron_1];start = 2011-11-14 18:30:00;period = 300;path = C:\UniServer\uni_con\cron\cron_test\test_cron_1.bat;ref =
;=== END Config ===============================================================
Cron job
Cron job
Cron job
Cron job
Cron job
Cron jobs: (UniServer)
defined in Cron.ini
UniServer\uni_con\cron\cron.inio
listing of jobs and when to perform
‘;’ is a comment
UniServer Cron:
17
;[Test_cron_3];start = 2011-09-21 2:50:00;period = hourly;path = C:\UniServer\uni_con\cron\cron_test\test_cron_3.php;ref =
Cron jobs: (UniServer)
job names must be unique
time uses 24-hour clock
period in text: (hourly, daily, weekly, monthly)
seconds in numbers
ref is time last run
UniServer Cron:
18
;[Test_cron_3];start = 2011-09-21 2:50:00;period = hourly;path = C:\UniServer\uni_con\cron\cron_test\test_cron_3.php;ref =
Cron jobs: (UniServer)
path is absolute
web format or directory format
leave ‘ref’ blank (timestamp)
UniServer Cron:
19
;[Test_cron_3];start = 2011-09-21 2:50:00;period = hourly;path = C:\UniServer\uni_con\cron\cron_test\test_cron_3.php;ref =
Use Cron to insert a record in a table
Turn on UniServer
Create ‘tatlidb’ (text file in folder)
Create ‘tbltest’
Lab: UniServer Cron
20
CREATE TABLE `tbltest` ( `id` int(11) NOT NULL AUTO_INCREMENT, `firstname` varchar(25) NOT NULL, `lastname` varchar(25) NOT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
‘UniServerCron’ folder
Move ‘crontest.php’ into ‘www’ folder
Update your database’s username, password
Lab: UniServer Cron
21
Edit one of the Cron jobs listed (remove ‘;’)
Lab: UniServer Cron
23
[Test_of_Cron]start = 2013-09-21 2:50:00 //some time in near FUTUREperiod = 180 //seconds, or 3 minutespath = http://localhost/crontest.phpref =
When done:
save the changes; close file; stop UniServer
start UniServer, start Cron
Controller: on/off switch for Cron
Lab: UniServer Cron
24
Cron runs 3 minutes AFTER start defined
Cron does not update web page in browser
Manually update if you want to see
Ultimate test; look in table (refresh)
Lab: UniServer Cron
25
Cron in NetBeans:
26
NetBeans is an IDE
Not really
Nothing comparable to UniServer Cron
Glassfish uses timer services held in:
Enterprise Java Beans (EJB)
Maven projects
Can also be placed in Tomcat
Either way, must be installed
From the Obsidian site:
Cron for NetBeans:
Features/benefits: Obsidian Quartz Cron4j SpringReal-time schedule changes/Real-time Job configuration Yes Not native NoAd-hoc Job Submission Yes No NN NoConfigure job conflicts Yes No No NoCoe- and XML-Free job configuration Yes No No NoJob event subscription/notification Yes No No NoCustom listeners No Yes Yes NoJob chaining Yes Custom listeners NoUI for monitoring/management Yes No No NoZero configuration clustering and Load sharing Yes No No NoScripting language support in jobs (JS, Groovy, Python) Yes No No NoScheduling precision Minute Second Minute MilliREST API for job scheduling Yes No No NoCustom calendar support No Yes No No
Application-based
Java-based Cron tool; must be added to NetBeans
Works from within Java applications
Replaces the Java 2 ‘java.util.Timer’
Cron4j:
29
Like Unix Cron:
Cron4j:
30
Minutes [0-59] | Hours [0-23] | | Days [1-31] | | | Months [1-12] | | | | Days of the Week [Numeric, 0-6]| | | | | * * * * * absolutepath.html 5 * * * * //every hour, :05
15 8 * * Mon //every Monday at 8:15
* 12 16 * Mon //every Monday the 16, each minute
59 11 * * 1-5 //11:59am, Monday-Friday
59 23 * * * //Every day at 23:59
A collection of scheduler instances in a class
Requires appropriate import(s)
To work:
add JAR to libraries
add class to .java page
update the correct instance; set time
run .java class
Cron4j:
31
Quickstart code:
38
import it.sauronsoftware.cron4j.Scheduler;
public class Quickstart { public static void main(String[] args) { // Creates a Scheduler instance. Scheduler s = new Scheduler(); // Schedule a once-a-minute task. s.schedule("* * * * *", new Runnable() { public void run() { System.out.println("Another minute ticked away..."); } }); // Starts the scheduler. s.start(); // Will run for ten minutes. try { Thread.sleep(1000L * 60L * 10L); } catch (InterruptedException e) { ; } // Stops the scheduler. s.stop(); }}
Lab: Cron4j
Add the import to ‘CronService’
39
import it.sauronsoftware.cron4j.Scheduler;
public class Quickstart { public static void main(String[] args) { // Creates a Scheduler instance. Scheduler s = new Scheduler(); // Schedule a once-a-minute task. s.schedule("* * * * *", new Runnable() { public void run() { System.out.println("Another minute ticked away..."); } }); // Starts the scheduler. s.start(); // Will run for ten minutes. try { Thread.sleep(1000L * 60L * 10L); } catch (InterruptedException e) { ; } // Stops the scheduler. s.stop(); }}
Lab: Cron4j
Add the import to ‘CronService’
40
package com.stevejohnson.cronserver;
import javax.jws.WebService;import javax.jws.WebMethod;import javax.jws.WebParam;import it.sauronsoftware.cron4j.Scheduler;
/** * * @author Steve */@WebService(serviceName = "CronService")public class CronService {
/** * This is a sample web service operation */ @WebMethod(operationName = "hello") public String hello(@WebParam(name = "name") String txt) { return "Hello " + txt + " !"; }}
Lab: Cron4j
Strip off the public class ‘Quickstart’
Copy/paste main class inside ‘CronService’
41
public static void main(String[] args) { // Creates a Scheduler instance. Scheduler s = new Scheduler(); // Schedule a once-a-minute task. s.schedule("* * * * *", new Runnable() { public void run() { System.out.println("Another minute ticked away..."); } }); // Starts the scheduler. s.start(); // Will run for ten minutes. try { Thread.sleep(1000L * 60L * 10L); } catch (InterruptedException e) { ; } // Stops the scheduler. s.stop();}
Lab: Cron4j
Place the main class inside your .java file
42
@WebService(serviceName = "CronService")public class CronService { public static void main(String[] args) { // Creates a Scheduler instance. Scheduler s = new Scheduler(); // Schedule a once-a-minute task. s.schedule("* * * * *", new Runnable() { public void run() { System.out.println("Another minute ticked away..."); } }); // Starts the scheduler. s.start(); // Will run for ten minutes. try { Thread.sleep(1000L * 60L * 10L); } catch (InterruptedException e) { ; } // Stops the scheduler. s.stop(); }
Lab: Cron4j
Open ‘Source Packages’ - com
Rt. Click ‘CronService.java’ in Project window
Run
Output window opens at bottom of NetBeans
‘Another minute ticked away’ will appear
43
Lab: Cron4j
s.schedule("* * * * *", new Runnable() { public void run() { System.out.println("Another minute ticked away..."); }});
try { Thread.sleep(1000L * 60L * 10L); //10 minutes}
A more adaptable scheduler class
To work, permissions must be set
44
Lab: Cron4j
public static void main(String[] args) { // Declares the file. File file = new File("web\\index.jsp"); //'root' is Project folder // Creates the scheduler. Scheduler scheduler = new Scheduler(); // Schedules the file. //scheduler.scheduleFile(); // Starts the scheduler. scheduler.start(); // Stays alive for five minutes. try { Thread.sleep(5000); } catch (InterruptedException e) { ; } // Stops the scheduler. scheduler.stop();}
Part of MS Windows
Cron tool at the OS level
Program – Accessories – System Tools – Task Scheduler
45
Task Scheduler
Create Basic Task – add name
Select when to schedule (day)
Select the time to schedule (moment)
Identify type of task (Start a program)
Browse in file to open
46
Task Scheduler
Call a batch (.bat) file to start your files
Batch file: script with commands
Job Control Language
49
Batch files:
@echo offcd C:\Users\Steve\My Documents\NetBeansProjects\WeatherForecast\build\web\WEB-INF\lib\REM run the program"C:\Program Files\Java\jdk1.7.0_17\bin\java.exe" -jar "C:\Users\Steve\My Documents\NetBeansProjects\WeatherForecast\build\web\WEB-INF\lib\cron4j-2.2.5.jar"
Store tracks JIT inventory
Total transfers in (build a database)
Totals sold
Total transferred out
Lab:JIT Inventory
52
Make client
Create database ‘inventory’
write web application to connect to DB
query products where onhand<minstock
send purchase request
Today:
53
Write Cron function to run client-side app.
run inventory query
send order to supplier
Cron not supported in Glassfish*
Today:
54
Lab: CronEntry
55
placeorder
result
fulfillorder
Prior web services:
end user supplied data through a form
Lab: CronEntry
56
placeorder
result
determineorder
fulfillorder
This web service:
client side run by CRON
Server side service is the same
Displayed is a database (‘sample’) and its driver
Similar idea: database and connection file
Lab: CronEntry
58
Start the database server:
rt. click on ‘Java DB’
start server
output text appears showing start
Lab: CronEntry
59
The data can be entered using:
SQL statements
SQL editor
External SQL script*
Lab: CronEntry
65
id sku produtname minstock maxstock onhand
1 185348 78921 32” HDTV 6 12 6
2 412545 87458 Remote Control 8 14 9
3 311248 94135 Satellite Receiver 5 8 3
INSERT INTO SJOHNSON.PRODUCTS VALUES (1,'186348 78921','32” HDTV',6,12,6)INSERT INTO SJOHNSON.PRODUCTS VALUES (2,'412545 87458','Remote Control',8,14,9)INSERT INTO SJOHNSON.PRODUCTS VALUES (3,'312248 94135','Satellite Receiver',5,8,3)
SQL statements run in the SQL Editor window
rt. click on table name – ‘Execute Command’
enter SQL into Command window
rt. click – ‘Run Statement’
Lab: CronEntry
66
INSERT INTO SJOHNSON.PRODUCTS VALUES (1,'186348 78921','32” HDTV',6,12,6)
Use the SQL Editor:
rt. click on ‘Products’ table – ‘View Data’
click ‘Insert Record’ button
Lab: CronEntry
67
Create separate database for server
Create ‘order’ database:
Rt. Click on ‘Java DB’
‘Create Database’
Lab: CronEntry
70
Name: ‘order’
Username: first name-first letter lastname
Password: as you wish
Creates database and driver
Lab: CronEntry
71
Create table ‘products’:
open ‘STEVEJ’ (your_name)
rt. click on ‘Tables’ - ‘Create Table…’
name: ‘orderentry’
Lab: CronEntry
73
Data will be added by client web service
Data to be sent by client:
customernumber (who)
sku (what they want)
quantity ordered (how many)
Lab: CronEntry
75
Real life SIGNIFICANTLY more complex:
vendors have many addresses
check credit
check stock
variable pricing levels
multiple orders of products
1 item in stock
1 item backordered
Lab: CronEntry
76
Client side more complex also:
‘onhand’ is calculated (sub-query)
dates/times on all transactions
table to receive order results
products ordered in lots
Lab: CronEntry
77
Server database now built
Minimize the driver in ‘Services’ view
Make server side service using Web Application
Lab: CronEntry
78
Add operation ‘PlacedOrders’:
id int
customernumber string
sku string
qtyordered int
Lab: CronEntry
84
Go back to ‘Source’ view
Lab: CronEntry
87
package steve.johnson;
import javax.jws.WebService;import javax.jws.WebMethod;import javax.jws.WebParam;
@WebService(serviceName = "OrderEntryService")public class OrderEntryService {
/** * Web service operation */ @WebMethod(operationName = "PlacedOrders") public String PlacedOrders(@WebParam(name = "id") int id, @WebParam(name = "customernumber") String customernumber, @WebParam(name = "sku") String sku, @WebParam(name = "qtyordered") int qtyordered) { //TODO write your implementation code here: return null; }}
‘import’ classes used by the database connection
Similar to ‘include’ in C
Lab: CronEntry
88
import javax.jws.WebService;import javax.jws.WebMethod;import javax.jws.WebParam;
import java.sql.Connection;import java.sql.DriverManager;import java.sql.SQLException;import java.sql.Statement;
Data needed to create a connection to the DB
Goes in the “//TODO” area
Lab: CronEntry
89
int qtyordered) {
String host = "jdbc:derby://localhost:1527/order"; String user = "user"; //my username String pass = "password"; //my password
The connection string to the DB
The ‘insert’ query defined (with parameters)
The execution of the query
The return string (NOT professional)
Lab: CronEntry
90
try { Connection con = DriverManager.getConnection(host, user, pass); Statement stmt = con.createStatement(); String SQL = "INSERT INTO orderentry VALUES ("+id+", '“ +customernumber+"', '"+sku+"', "+qtyordered+")"; stmt.executeUpdate(SQL); return "Order successfully entered";}
The error message
NOT professional
Lab: CronEntry
91
catch (SQLException err) { return "Problem with order";}
92
package steve.johnson;
import javax.jws.WebService;import javax.jws.WebMethod;import javax.jws.WebParam;
import java.sql.Connection;import java.sql.DriverManager;import java.sql.SQLException;import java.sql.Statement;
@WebServicepublic class InventoryOrder {
@WebMethod(operationName = "orderentry") public String orderentry(@WebParam(name = "id") int id, @WebParam(name = "customernumber") String customernumber, @WebParam(name = "sku") String sku, @WebParam(name = "qtyordered") int qtyordered) {
String host = "jdbc:derby://localhost:1527/order"; String user = "stevej"; String pass = "izmir"; try { Connection con = DriverManager.getConnection(host, user, pass); Statement stmt = con.createStatement(); String SQL = "INSERT INTO orderentry VALUES ("+id+", '"+customernumber+"', '"+sku+"', "+qtyordered+")"; stmt.executeUpdate(SQL); return "Order successfully entered"; } catch (SQLException err) { return "Problem with order"; } }}
Save the page
Deploy the service (rt. click on project – Deploy)
Test the service:
open “Web Services” folder
rt. click ‘OrderEntryService’ – Test Service…
Lab: CronEntry
93
Run the code (green arrow)
If ‘connection refused: connect’: start server
Fix: start the server
Lab: CronEntry
94
Look in your DB table for an entry
Open ‘Services’ tab – find jdbc driver for ‘order’
Open your name (SteveJ) – open ‘Tables’
Rt. click on ‘orderentry’ and ‘View Data…’
Web service is built
Lab: CronEntry
97
Add ‘imports’ for the database
Lab: CronEntry
105
--%>
<%@ page import="java.sql.Connection" %><%@ page import="java.sql.DriverManager" %><%@ page import="java.sql.SQLException" %><%@ page import="java.sql.Statement" %><%@ page import="java.sql.ResultSet" %>
Code appears in .jsp file
This code must run query on ‘inventory’ andsend result to ‘order’
Lab: CronEntry
106
Run query, get result, update variables
Connection string for ‘products’
Generates a ResultSet (a Recordset)
Lab: CronEntry
107
<% String host = "jdbc:derby://localhost:1527/inventory"; String user = "user"; String pass = "password"; Connection con = DriverManager.getConnection(host, user, pass); Statement stmt = con.createStatement(); String SQL = "SELECT sku, onhand, maxstock FROM products WHERE onhand<minstock"; ResultSet rs = stmt.executeQuery(SQL);
Plays one record from resultset
ID and customernumber must be inserted
ID should not be entered*
‘customernumber’ not handled professionally
Lab: CronEntry
108
rs.next();int id=921;String customernumber = "ABCD";String sku = rs.getString("sku");int qtyordered = rs.getInt("maxstock") - rs.getInt("onhand");
109
<% String host = "jdbc:derby://localhost:1527/inventory"; String user = "sjohnson"; String pass = "ieugo"; Connection con = DriverManager.getConnection(host, user, pass); Statement stmt = con.createStatement(); String SQL = "SELECT sku, onhand, maxstock FROM products WHERE onhand<minstock"; ResultSet rs = stmt.executeQuery(SQL); rs.next(); int id=921; String customernumber = "ABCD"; String sku = rs.getString("sku"); int qtyordered = rs.getInt("maxstock") - rs.getInt("onhand"); try {
steve.johnson.OrderEntryService_Service service = new steve.johnson.OrderEntryService_Service();
steve.johnson.OrderEntryService port = service.getOrderEntryServicePort();
java.lang.String result = port.operation(id, customernumber, sku, qtyordered);
out.println("Result = "+result); } catch (Exception ex) { }%>
Add a table to track quantity on hand at company
One entry for each item on the ‘inventory’ table
If order > qty return ‘backordered’
Do not accept order
Assignment: CronEntry continued
110
SKU Quantity on hand
SE 370: Programming Web Services
Week 6: Cron, SSL, & SOAPCopyright © Steven W. Johnson
February 1, 2013
Both classified as application servers
GlassFish: port 4848
Tomcat: port 8080
GlassFish & Tomcat:
113
Access their interface: http://localhost:port
Turn on NetBeans
Make sure GlassFish is started
GlassFish & Tomcat:
114
Default username is ‘admin’
Password: look at ‘Properties’ of GlassFish
Password in cleartext didn’t copy for me
GlassFish & Tomcat:
116
Port 8080 actually connected to Catalina
Reports as GlassFish
GlassFish & Tomcat:
119
Catalina:ServletHTTP server
Coyote:HTTP connector
Jasper:JSP engine
Secure Sockets Layer
Symmetric key technology, two-way data
Invented by Netscape, 1994
Part of Netscape 2
Lead engineer: Taher Elgamal
SSL:
120cacm.acm.org
121http://www.codesecurely.org/Wiki/print.aspx/Security_Code_Reviews/Data_Validation
Application
Presentation
Session
Transport
Network
Data Link
Physical
Application
Presentation
Session
Transport
Network
Data Link
Physical
Packets
SSL SSL
SSL protects entire OSI model
SSL:
Invented by Netscape (1996), part of Netscape 2
TLS (1999) similar idea
Not inter-operable, but do same thing
TLS generally has stronger* encryption
SSL:
122*differences are very minor
Mission: transmit private data on public systems
Provides confidentiality through encryption
2-way symmetric key system
Differs from hashing: one-way asymmetric
Size of key = time to break encryption
SSL:
123
SSL:
124
Symmetric:Same key encrypts and decrypts
Asymmetric:One key encrypts. Different key decrypts
read/write read/write
readwrite
SSL/TLS
Emaildocuments
When to use:
passing any confidential information
usernames and passwords
credit card numbers
student ids
any identifying number, string, etc
Plus, any content on pages that are SSL
SSL:
125
SSL communications has a dedicated port
443 for UniServer (https://localhost/)
8181 for NetBeans (https://localhost:8181/)
Both require https:// protocol
UniServer does not require a defined port
SSL:
126
Both require a certificate from ‘CA’:
Verisign
TrusTe
Microsoft, Netscape, others
Create your own (untrusted)
Server cert. holds public, private keys
SSL:
127SSL
Generate a certificate:
open UniServer interface
open ‘Apache’, choose ‘General Certificate’
UniServer SSL:
128
Click ‘Generate’ button
Add information as you see fit (not real)
Real life: must purchase from CA
Click ‘Run Generate’ to create
UniServer SSL:
129
SSL is operational (built into) in GlassFish
(Untrusted) certificate is ready to go
Turn on GlassFish
Use https://localhost:8181
NetBeans SSL:
135
Lab: BusApplication for TürkiyeKoç:
index page: number of tickets purchased
cannot oversell the bus, tickets 54 ₺
purchase page: buy tickets (SSL – the web service)
give credit card number, PIN
pick seat page: pick from unsold seats by map
bus has 16 seats 1A – 4D
select from seats available (point-click)
140
Lab: BusReturn array holding seats purchased, final price
Update database
Give receipt with seat assignments
Page is prepared: ‘seating.html’
141
Lab: BusWeb pages in application:
142
Number of tickets:
CardPIN
Buy tickets:
54
3, 162
Pick seats:
3
SUM(seats ‘open’)
SUM(seats ‘open’)
UPDATE seat status
Reciept:
144
Lab: Bus‘seatstbl’ has three fields:
seat (1A, 2C, etc)
status (open, sold, pick)
layout (used to order query
Lab: BusAdd table data for 16 seats (1A – 4D)
Rt. Click on table – Execute Command
145
INSERT INTO SJOHNSON.SEATSTBL VALUES('1A', 'open', 13);INSERT INTO SJOHNSON.SEATSTBL VALUES('1B', 'open', 9);INSERT INTO SJOHNSON.SEATSTBL VALUES('1C', 'open', 5);INSERT INTO SJOHNSON.SEATSTBL VALUES('1D', 'open', 1);INSERT INTO SJOHNSON.SEATSTBL VALUES('2A', 'open', 14);INSERT INTO SJOHNSON.SEATSTBL VALUES('2B', 'open', 10);INSERT INTO SJOHNSON.SEATSTBL VALUES('2C', 'open', 6);INSERT INTO SJOHNSON.SEATSTBL VALUES('2D', 'open', 2);INSERT INTO SJOHNSON.SEATSTBL VALUES('3A', 'open', 15);INSERT INTO SJOHNSON.SEATSTBL VALUES('3B', 'open', 11);INSERT INTO SJOHNSON.SEATSTBL VALUES('3C', 'open', 7);INSERT INTO SJOHNSON.SEATSTBL VALUES('3D', 'open', 3);INSERT INTO SJOHNSON.SEATSTBL VALUES('4A', 'open', 16);INSERT INTO SJOHNSON.SEATSTBL VALUES('4B', 'open', 12);INSERT INTO SJOHNSON.SEATSTBL VALUES('4C', 'open', 8);INSERT INTO SJOHNSON.SEATSTBL VALUES('4D', 'open', 4);
Lab: Bus‘Credit card’ table:
not a real credit card system (see Şef Steve)
point: transmit data, reply in SSL
credit card numbers are 5 digits long
PINs are 4 digits long
all transactions will be approved
no data, all data is INSERTed
146
Lab: BusJSP: server side; executes before page sent
JavaScript: client side; executes after page sent
150
Lab: BusStart with ‘index’
Mission:
get number of tickets required
check open seats on the bus
Requires:
form to get number of tickets
connect to DB to count open seats
No web service or SSL needed151
Lab: BusNeeded on ‘index’:
Delete ‘Hello World’
Change title to “Tickets Needed”
form
table (3 <tr>)
text input
Submit
Open Palette (Window – IDE Tools – Palette)
153
Lab: Bus
155
Finished HTML:<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Tickets Needed:</title> </head> <body> <form name="tickets" action="approve.jsp" method="POST"><table border="0" cellpadding="4"> <tr> <td>Tickets to Purchase:</td> </tr> <tr> <td><input type="text" name="quantity" id="quantity" value="" size= "2" autofocus="autofocus" />td> </tr> <tr> <td><input type=“button" value="Get Tickets" name=“button" /></td> </tr> </table> </form> </body></html>
Lab: Bus
156
Add this CSS:
<style> table { margin-left: auto; margin-right: auto; margin-top: 30px; } td { text-align: center; padding: 5px; } #quantity { text-align: center; }</style>
Lab: Bus
157
When submitted, POST quantity, price (final)
Use JavaScript to:
calculate price: 54 * number of tickets
insert final price into hidden field ‘onblur’
<input type="button" value="Get Tickets" name="button" onclick="calculate()"/>
<script> function calculate() { tickets = document.getElementById("quantity").value; totalprice = 54 * tickets; totalprice = totalprice.toFixed(2); window.location = "approve.jsp?quantity="+tickets+"&price="+totalprice; }</script>
Lab: Bus
158
Check open seat count versus ticket request
Must be done in JSP:
can’t be done on index without reload
reload this page and then go on (better choice)
check on the ‘approve’ page
Lab: Bus
159
‘approve.jsp’:
GET ‘quantity’ and ‘price’ off URL
save ‘quantity’ into session variable ‘tickets’
save ‘price’ into session variable ‘price’
test tickets <= open seats
get credit card number and PIN
use web service to approve card
Lab: Bus
161
‘approve.jsp’:
delete ‘Hello World’, title: ‘Purchase Tickets’
from the Palette:
form
table
text inputs
button
Lab: Bus
163
‘approve.jsp’:
Add the quantity and price to the page face
<form name="approval" action="" method="post"> <table border="0" cellpadding="3"> <tr> <td>Tickets Purchased:</td> <td><%=request.getParameter("quantity")%></td> </tr> <tr> <td>Total Price:</td> <td><%=request.getParameter("price")%></td> </tr>
Lab: BusAdd the style rules:
165
<style> table { margin-left: auto; margin-right: auto; margin-top: 30px; } td { text-align: right; padding: 3px; } #mid { text-align: center; }</style>
Lab: BusFixes to the HTML:
166
<table border="0" cellpadding="3"> <tr> <td>Tickets Purchased:</td> <td><%=request.getParameter("quantity")%></td> </tr> <tr> <td>Total Price:</td> <td><%=request.getParameter("price")%></td> </tr> <tr> <td>Card Number:</td> <td id="mid"><input type="text" name="cardnumber" value="" autofocus="autofocus" size="10" placeholder="Card Number" /></td> </tr> <tr> <td>PIN:</td> <td id="mid"><input type="text" name="pin" value="" size="10" placeholder="PIN" /></td> </tr> <tr> <td></td> <td id="mid"><input type="submit" value="Purchase" name="Submit" /></td> </tr></table>
Lab: Bus
169
<%@page import="java.sql.Statement"%><%@page import="java.sql.DriverManager"%><%@page import="java.sql.Connection"%><%@page import="java.sql.ResultSet"%><% // create global variables Integer qty = Integer.parseInt(request.getParameter("quantity")); session.setAttribute("tickets", qty); //sets session var Float total = Float.parseFloat(request.getParameter("price")); session.setAttribute("price", total); //global variable Integer openseats=0; String host = "jdbc:derby://localhost:1527/busdb"; String user = "user"; String pass = "pass";
Connection con = DriverManager.getConnection(host, user, pass); Statement stmt = con.createStatement(); String SQL = "SELECT COUNT(status) as seats FROM seatstbl WHERE status='open'"; ResultSet rs = stmt.executeQuery(SQL);
Lab: Bus
170
if (rs.next()) { openseats = rs.getInt("seats"); } Integer tickets = Integer.parseInt(request.getParameter("quantity"));
rs.close(); //close what you open stmt.close(); con.close();
if (tickets > openseats) { pageContext.forward("index.jsp"); //need better error routine }%>
Session variable isn’t set yet, so can’t use
Lab: BusCreate web service to connect to Bank
Credit cards: 5-digit number
PIN: 4-digit number
All cards are accepted and approved
More complete credit card system: Şef Steve
171
Lab: BusUse the ‘creditcards’ table for SteveBank:
connect to table
insert data
return ‘approved’
175
@WebService(serviceName = "SteveBank")public class SteveBank {
/** * Web service operation */ @WebMethod(operationName = "authorize") public String authorize(@WebParam(name = "cardnumber") String cardnumber, @WebParam(name = "pin") String pin, @WebParam(name = "amount") float amount) { //TODO write your implementation code here: return null; }}
Lab: Bus
176
@WebService(serviceName = "SteveBank")public class SteveBank {
/** * Web service operation */ @WebMethod(operationName = "authorize") public String authorize(@WebParam(name = "cardnumber") String cardnumber, @WebParam(name = "pin") String pin, @WebParam(name = "amount") float amount) { String host = "jdbc:derby://localhost:1527/busdb"; String user = "user"; String pass = "pass"; try { Connection con = DriverManager.getConnection(host, user, pass); Statement stmt = con.createStatement(); String SQL = "INSERT INTO creditcards VALUES ('"+cardnumber+"', '"+pin+"', "+amount+")"; stmt.executeUpdate(SQL); return "Approved"; } catch (SQLException err) { return "Problem with order "+err; } }}
Lab: BusAdd imports and parameters (clean up errors)
Deploy the project
177
import java.sql.Connection;import java.sql.DriverManager;import java.sql.SQLException;import java.sql.Statement;import javax.jws.WebService;import javax.jws.WebMethod;import javax.jws.WebParam;
@WebService(serviceName = "SteveBank")public class SteveBank {
/** * Web service operation * @param cardnumber * @param pin * @param amount * @return
Lab: BusTest the web service:
Open Web Services folder
Rt. Click on ‘SteveBank’ – Test Web Service
178
Lab: BusOn ‘approve.jsp’:
181
<% if(request.getParameter("Submit") != null) { try {
com.stevebank.client.SteveBank_Service service = new com.stevebank.client.SteveBank_Service();
com.stevebank.client.SteveBank port = service.getSteveBankPort();
String cardnumber = request.getParameter("cardnumber");String pin = request.getParameter("pin");float amount =
Float.parseFloat(request.getParameter("price"));
java.lang.String result = port.authorize(cardnumber, pin, amount) } catch (Exception ex) {
// TODO handle custom exceptions here } pageContext.forward("seating.jsp?tickets=" +session.getAttribute("tickets")); }%>
Lab: Bus‘seating’ allows customer to choose their seat
Can choose and un-choose
Total choices == tickets purchased
Seat status tracked in database (open, sold, pick)
Page uses JavaScript and JSP
183
Lab: BusBuild web page first: add the style sheet
185
<style> img { margin: 0px; display: block; margin-bottom: -1px; margin-top: -1px; } table { width: 200px; margin-left: auto; margin-right: auto; margin-top: 30px; } td { width: 40px; padding-left: 8px; } .rwindow { padding-top: 8px; border-top: 1px solid #000000; } .raisle { padding-bottom: 15px; }
.laisle { padding-top: 15px; } .lwindow { padding-bottom: 8px; border-bottom: 1px solid #000000; } #title { text-align: center; padding-bottom: 20px; width: 100%; } #legendr { height: 25px; text-align: right; } #legendl { height: 25px; width: 48px; text-align: left; padding-left: -8px; }</style>
Lab: BusJavaScript to change selected seat color
186
<script> var assign = []; function updatemap(status, seat) { if (status === "open") { document.getElementById(seat).innerHTML = "<img src='pick.png' width='28' height='25' alt='"+seat+"' title='"+seat+"' onClick=\"updatemap('pick', '"+seat+"')\">"; //one line
assign.push(seat); } if (status === "pick") { document.getElementById(seat).innerHTML = "<img src='open.png' width='28' height='25' alt='"+seat+"' title='"+seat+"' onClick=\"updatemap('open', '"+seat+"')\">"; //one line i = assign.indexOf(seat); if (i > -1) { assign.splice(i, 1);
} } if (status === "driver") alert ("This is the driver's seat"); if (status === "sold") alert ("This seat is already sold"); }</script>
Lab: BusContact the database:
187
<% try { String host = "jdbc:derby://localhost:1527/busdb"; String user = "user"; String pass = "pass"; Connection con = DriverManager.getConnection(host, user, pass); Statement stmt = con.createStatement(); String SQL = "SELECT seat, status FROM seatstbl ORDER BY layout ASC"; ResultSet rs = stmt.executeQuery(SQL); String seat; //variables used in ResultSet; data typing String status; %>
188
<body> <form name="reservations" method="post" action=""> <table cellspacing="0"> <tr> <td colspan="5" height="50" id="title">Transaction Approved<br>Choose your seat by clicking on it</td> </tr> <tr> <td class="rwindow"> </td> <td class="rwindow" id="1D"><img src="open.png" width="28" height="25" alt="1D" title="1D" onclick="updatemap('open', '1D')"></td> <td class="rwindow" id="2D"><img src="open.png" width="28" height="25" alt="2D" title="2D" onclick="updatemap('open', '2D')"></td> <td class="rwindow" id="3D"><img src="open.png" width="28" height="25" alt="3D" title="3D" onclick="updatemap('open', '3D')"></td> <td class="rwindow" id="4D"><img src="open.png" width="28" height="25" alt="4D" title="4D" onclick="updatemap('open', '4D')"></td> </tr> <tr> <td class="raisle"> </td> <td class="raisle" id="1C"><img src="open.png" width="28" height="25" alt="1C" title="1C" onclick="updatemap('open', '1C')"></td> <td class="raisle" id="2C"><img src="open.png" width="28" height="25" alt="2C" title="2C" onclick="updatemap('open', '2C')"></td> <td class="raisle" id="3C"><img src="open.png" width="28" height="25" alt="3C" title="3C" onclick="updatemap('open', '3C')"></td> <td class="raisle" id="4C"><img src="open.png" width="28" height="25" alt="4C" title="4C" onclick="updatemap('open', '4C')"></td> </tr> <tr> <td class="laisle"> </td> <td class="laisle" id="1B"><img src="open.png" width="28" height="25" alt="1B" title="1B" onclick="updatemap('open', '1B')"></td> <td class="laisle" id="2B"><img src="open.png" width="28" height="25" alt="2B" title="2B" onclick="updatemap('open', '2B')"></td> <td class="laisle" id="3B"><img src="open.png" width="28" height="25" alt="3B" title="3B" onclick="updatemap('open', '3B')"></td> <td class="laisle" id="4B"><img src="open.png" width="28" height="25" alt="4B" title="4B" onclick="updatemap('open', '4B')"></td> </tr> <tr> <td class="lwindow"><img src="driver.png" width="28" height="25" alt="Driver's Seat" title="Driver's Seat" onClick="updatemap('driver', '0A')"></td> <td class="lwindow" id="1A"><img src="open.png" width="28" height="25" alt="1A" title="1A" onclick="updatemap('open', '1A')"></td> <td class="lwindow" id="2A"><img src="open.png" width="28" height="25" alt="2A" title="2A" onclick="updatemap('open', '2A')"></td> <td class="lwindow" id="3A"><img src="open.png" width="28" height="25" alt="3A" title="3A" onclick="updatemap('open', '3A')"></td> <td class="lwindow" id="4A"><img src="open.png" width="28" height="25" alt="4A" title="4A" onclick="updatemap('open', '4A')"></td> </tr> </table> <table cellspacing="0"> <tr> <td class="laisle"> </td> <td id="raisle"><img src="open.png" width="28" height="25" alt="Open" title="Open"></td> <td id="legendl">Open</td> <td id="raisle"><img src="sold.png" width="28" height="25" alt="Sold" title="Sold"></td> <td id="legendl">Sold</td> </tr> </table> <table cellspacing="0"> <tr> <td colspan="5" id="title">Please choose your <!-- var --> seats</td> </tr> <tr> <td colspan="5" id="title"><input type="submit" name="Submit" value="Submit"></td> </tr> </table> </form></body>
189
<% } rs.next(); seat = rs.getString("seat"); status = rs.getString("status"); if (seat.equals("4A")) { %> <td class="lwindow" id="4A"><img src="<%=status%>.png" width="28" height="25" alt="4A" title="4A" onClick="updatemap('<%=status%>', '4A')"></td> <% } rs.close(); stmt.close(); con.close();}
Lab: BusRow 4A shown
Clear RAM of stored data and memory leaks
190
<td class="rwindow" id="1D"><img src="open.png" width="28" height="25" alt="1D" title="1D" onClick="updatemap('open', '1D')"></td>
Lab: Bus‘onclick’ placed on seat; pass status, location
‘open’ will become a variable from DB
open.png
sold.png
pick.png (selected)
Lab: BusMove four images into the web folder
open, sold, pick, driver
Drag-drop (copy) into ‘WEB-INF’ folder.
Must be in same folder as ‘seating’
191
Lab: BusSeat map should now work
Selected seats kept in array ‘assign’ (1D, 2A)
Array passed to ‘receipt’
192
Lab: BusFixing the seats:
‘onSubmit’ array sent to ‘receipt’
table seats updated to ‘sold’
ResultSet has seat, status
193
open.png
Lab: BusPlace JSP code immediately above <tr>:
connection to database
SELECT query to get current seat status
ResultSet to put status into the images
194
<% try { String host = "jdbc:derby://localhost:1527/busdb"; String user = "sjohnson"; String pass = "juneau"; Connection con = DriverManager.getConnection(host, user, pass); Statement stmt = con.createStatement(); String SQL = "SELECT seat, status FROM seatstbl ORDER BY layout ASC"; ResultSet rs = stmt.executeQuery(SQL); String seat; String status; %>
Lab: Bus
195
<% rs.next(); seat = rs.getString("seat"); status = rs.getString("status"); %> <td class="rwindow" id="1D"><img src="<%=status%>.png" width="28" height="25" alt="1D" title="1D" onclick="updatemap('<%=status%>', '1D')"></td>
Lab: BusConnect the image map to the table ‘seatstbl’
Number of seats purchased: ‘tickets’
Can be ‘getParameter’ or ‘session.getAttribute’
196
<td colspan="5" id="title">Please choose <%=session.getAttribute("tickets")%> seats</td>
function finish() { //add to current <script> window.location = "receipt.jsp?data="+assign; }</script>
Lab: Bus‘Receipt’ uses parameters, session variables:
number of tickets (session var ‘tickets’)
total price (session var ‘price’)
seats assigned, array in URL (parameter)
197
Lab: BusBuild the page:
Not a form, uses a table
displays ‘dynamic’ data from the ‘data’ array
Needed:
table (3 rows, 2 columns)
198
Loops on array count
Lab: SSL‘receipt.jsp’:
capture seat assignment array; split
update ‘seatstbl’
print out receipt
‘data’ comes in as a string; split into an array
199
<%@page import="java.text.DecimalFormat"%><%@page import="java.sql.ResultSet"%><%@page import="java.sql.Statement"%><%@page import="java.sql.DriverManager"%><%@page import="java.sql.Connection"%><% String data = request.getParameter("data"); String[] assign = data.split(","); Integer count = assign.length;
Lab: SSL‘receipt.jsp’:
update ‘seatstbl’
200
String host = "jdbc:derby://localhost:1527/busdb"; String user = "user"; String pass = "pass"; Connection con = DriverManager.getConnection(host, user, pass); Statement stmt = con.createStatement(); for (int i=0; i<count; i++) { String SQL = "UPDATE seatstbl SET status='sold' WHERE seat='"+assign[i]+"'"; stmt.executeUpdate(SQL); }
stmt.close(); con.close();%>
Lab: SSLSecurity and validation:
What happens if two people buy the same seat?
201
Open ‘seating’ at same time
Lab: BusPrint out receipt (table)
202
<table> <tr> <td colspan="2" class="center"><h2>Your Receipt </h2></td> </tr> <tr> <td class="center">Seat</td> <td class="center">Price</td> </tr> <% for (int i=0; i<count; i++) { %> <tr> <td class="center"><%=assign[i]%></td> <td class="right">54.00</td> </tr> <% } float total=count*54; String texttotal = total+"0"; %> <tr> <td class="right">Total:</td> <td class="right"><%=texttotal%></td> </tr></table>
Lab: BusPrint out receipt (the style rules)
203
<style> table { width: 200px; margin-left: auto; margin-right: auto; margin-top: 30px; padding: 4px; } .right { text-align: right; } .center { text-align: center; }</style>
Lab: BusLast thing: SSL
Web services – rt. Click on SteveBank
Select ‘Edit Web Service Attributes’
205
Write the code to handle a withdrawal from an ATM
Web service communicates between ATM, bank:
authorize transaction
alert for more cash
ATM-bank transmissions in SSL
Assignment: ATM
214
Constraints on withdrawals:
money must be in account
money must be available in the machine
Authorize only if both are true
Maximum withdrawal: 1,000
ATM uses smallest number of notes to dispense money
Assignment: ATM
215
ATM has a database of cash on hand
Alert when any note is less than five
Current inventory of money:
Assignment: ATM
216
Currency Quantity
10 6
20 6
50 20
100 15
Bank has database of accounts with transactions
Database and data provided (MySQL)
Transaction: withdrawals only
Withdrawal information:
Account
PIN
timestamp
amount of withdrawal
machine id: ‘1500482’
Assignment: ATM
217
Customer data:
two customers
PIN is last three digits of account number
Assignment: ATM
219
Field Customer Customer
Accountid 1 2
Account 12345 12346
Surname Yeni Zeybek
Givenname Ali Bahar
Pin 345 346
Balance 1000 5000
Page templates:
Assignment: ATM
220
logint.html amount.html
withdraw.html
overdrawn.html
nocash.html