[jdbc, servlets, jsp, jstl]activenet ® adv java [jdbc, servlets, jsp, jstl] by suryanarayana #202,...
TRANSCRIPT
ActiveNET®
Adv Java [JDBC, Servlets, JSP, JSTL]
By Suryanarayana
#202, Manjeera Plaza, Opp: Aditya Park Inn,
Ameerpet, HYD-38 Call: 98 48 111 288
Visit: www.activenetinformatics.com
Mail to: [email protected]
JDBC JDBC JDBC JDBC
(Java Data Base Connectivity)
By SuryanarayanaBy SuryanarayanaBy SuryanarayanaBy Suryanarayana
ActiveNET
Content:
What is JDBC?
DB Connectivity Architectures
JDBC Architectures
JDBC Interfaces, Classes
JDBC 4 Drivers
DML, DRL statements execution using Statement interface
DML statements execution using PreparedStatement interface
Executing DRL/SELECT Statement using ResultSet
ResultSet limitations
ResultSet 2.0 features (Scrollable, Updatable)
Calling functions and procedures using CallableStatement
Transactions (ACID properties) implementation in JDBC
Atomicity
Consistency & Isolation
Savepoints in JDBC
What is JDBC?
JDBC (Java DataBase Connectivity) is an API (Application Programming Interface) for connecting java
program to various Databases. JDBC is developed based on SAG’s (SQL Access Group) CLI (Call Level
Interface) specification. Based on SAG CLI specification only Microsoft’s ODBC and all other Database
vendors writes their drivers.
SAG is a group of software companies formed in 1989 to define and promote standards for database
portability and inter-operability. Initial members are Oracle Corp, Informix, Ingres, DEC, Tandem, Sun
and HP.
o Connect to Database using JDBC driver class, url, username and password
o Create a Statement
o Execute DDL/DML statements using executeUpdate() that returns rows effected in
Database
o Execute DRL statement using executeQuery() that returns ResultSet object
o Extract data from ResultSet object
o and close all the ResultSet, Statement and Connection objects
****************************The END****************************
DB Connectivity Architectures
DDL - Data Definition Language - CREATE, ALTER, DROP
DML - Data Manipulation Language - INSERT, UPDATE, DELETE
DRL - Data Retrieval Language - SELECT
DCL - Data Control Language - COMMIT, ROLLBACK
So far we connected to Oracle DB in two ways:
1) SQL Prompt
2) SQL Developer
3) DB Home Page
4) JDBC (now we are connecting)
Connecting through SQL Prompt:
Open command prompt-> type sqlplus.exe
Username: am1
Password: am1
SQL> type DDL/DML/DRL statements
Connecting through SQL Developer:
Click on sqldeveloper.exe
double on am1 connection
SQL editor will open-> type DDL/DML/DRL statements
Connecting through JDBC:
Oracle DB is implemented in C. Multiples of thousands of functions are implemented to run Oracle
DB. But some of the important functions are: OCI - Oracle CallLevel Interface
Oci_connect(username, password, connect_string)
oci_execute (dml)
oci_fetch_all(drl)
oci_close()
The above said functions are C functions.
Similary MySQL functions prefix with "mySQL", SQL Server functions prefix with "sql", IBM DB2
functions prefixc with "db2".
If front developer (VB,PB,D2K,JDBC) wants to connect to DB, they must call DB C/native functions.
But the same front end developer want to connect to diff DBs, diff DB functions must be learnt and
used. This increases Front End developer burden.
To avoid this burden, MS (Microsoft) developed a product called ODBC (Open DB Connectivity). MS
with diff DB vendor teams developed one-one ODBC driver for each DB (Oracle ODBC Driver,
MySQLODBC Driver, DB2 ODBC Driver etc).
So FE dev need to learn only one set of functions (ODBC functions) to connect to any DB.
Because DBs, ODBC drivers, and FE softwares are all written in C so that FEs can call C functions
directly.
But coming to Java Developers, they can call only Java functions but not C functions.
For that a team call "JavaSoft" in Sun Microsystems developed a Java class called "JdbcOdbcDriver".
The methods of JOD class calls ODBC C functions.
JDBC Drivers:
i. Type I Driver - JDBC-ODBC Driver
ii. Type II Driver - Java-Native API Driver
iii. Type III Driver - All Java Net Driver
iv. Type IV Driver - Java Native Protocol Driver
Type I Driver:
Name: JDBC-ODBC Driver
Vendor: JavaSoft a division of Sun MicroSystems
ODBC Driver by Microsoft/DB vendor
Software: JDK Software
PATH/CLASSPATH: F:\Program Files\Java\jdk1.8.0_144\jre\lib\rt.jar
Driver Classname: sun.jdbc.odbc.JdbcOdbcDriver
URL: jdbc:odbc:odbcdsnname
Arch: Java Program-> JDBC API-> ODBC API-> ODBC-> DB native API-> DB
Adv:
* by changing dsnname we can connect to any DB.
* JOD driver comes with JDK, ODBC comes with OS/DB, hence not seperate soft installation is
needed.
Disadv:
* OS dependent, this driver is available only on Windows.
* only local DB connectivity, no remote DB connectivity.
Descr: JDBC Program -> JdbcOdbcDriver-> ODBC Driver for Oracle-> Oracle native functions
Type II Driver:
Name: Java-Native API driver
Vendor: DB vendor
Software: DB Software
PATH: F:\oraclexe\app\oracle\product\11.2.0\server\bin
CLASSPATH: F:\oraclexe\app\oracle\product\11.2.0\server\jdbc\lib\ojdbc6.jar
Driver Classname: oracle.jdbc.driver.OracleDriver
URL: jdbc:oracle:oci:@XE
Arch: Java Program-> JDBC API-> DB native API-> DB
Adv:
* Fastest among all JDBC drivers (less no of layers & API)
* OS independent
* No seperate software, comes with DB
Disadv:
* local DB connectivity
Descr: JDBC Program -> Oracle Driver -> Oracle native functions
Type IV Driver:
Name: Java Native Protocol Driver
Vendor: DB vendor like Oracle
Software: DB Software
PATH: F:\oraclexe\app\oracle\product\11.2.0\server\bin
CLASSPATH: F:\oraclexe\app\oracle\product\11.2.0\server\jdbc\lib\ojdbc6.jar
Driver classname: oracle.jdbc.driver.OracleDriver
URL: jdbc:oracle:thin:@localhost:1521:XE
Arch:JDBC Program-> Oracle Driver-> Oracle DB SOcket running in port no 1521-> DB
Adv:
* local & Remote DB connectivity
* Platform / OS dependent
Disadv:
* Driver is DB specific
Type III Driver:
Name: All Java Net Driver
Vendor: IDS Software
Software: IDSS422XE.exe
PATH: C:\IDSServer
CLASSPATH: C:\IDSServer\classes\jdk14drv.jar
Driver classname: ids.sql.IDSDriver
URL: jdbc:ids://localhost:12/conn?dsn='oraclesysdsn'
Arch: JDC Program-> IDSDriver-> IDSServer-> ODBC Driver-> DB
Adv:
* OS independent
* Driver DB independent/connects to any DB
* local & remote DB connectivity
Disadv:
* Separate license is required
JDBC interfaces & classes:
interfaces: Driver, Connection, Statement, PreparedStatement, CallableStatement, ResultSet,
ResultSetMetaData, DatabaseMetaData
classes: DriverManager, Types, SQLException
PATH & CLASSPATH setting for JDBC drivers:
PATH
C:\Windows;C:\Windows\System32;F:\oraclexe\app\oracle\product\11.2.0\server\bin;F:\Program
Files\Java\jdk1.6.0_45\bin;C:\IDSServer
CLASSPATH:.;F:\Program Files\Java\jdk1.6.0_45\lib\tools.jar;F:\Program
Files\Java\jdk1.6.0_45\lib\dt.jar;F:\Program Files\Java\jdk1.6.0_45\jre\lib\rt.jar;
F:\oraclexe\app\oracle\product\11.2.0\server\jdbc\lib\ojdbc6.jar;C:\IDSServer\classes\jdk14drv.jar
DSN creations for Type I & III drivers:
DSN creation for Type I:
Start-> Control Panel-> Administrative Tools-> DataSources (ODBC)-> User DSN-> Click Add-> Select
"Oracle in XE"->
DSN Name:oracledsn
TNS Service Name: oracledsn
User ID: am1
click on OK-> OK
DSN creation for Type III:
same way we need to create one dsn in System DSN named "oraclesysdsn"
JDBC Drivers Test Program:
JDBC API comes with JDK in rt.jar, the API exist in java.sql package.
// JDBCConnTest.java
import java.sql.*;
class JDBCConnTest {
public static void main(String rags[]) throws Exception {
// First statement is JDBC driver loading; throws ClassNotFoundException
// Type I
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
// Type II & IV
// Class.forName("oracle.jdbc.driver.OracleDriver");
// Type III
// Class.forName("ids.sql.IDSDriver");
// Second statement is establishing connection to DB using DriverManager class; throws
SQLException
// Type I
Connection con=DriverManager.getConnection("jdbc:odbc:oracledsn", "am1", "am1");
// Type II
// Connection con=DriverManager.getConnection("jdbc:oracle:oci:@XE", "am1", "am1");
// Type IV
// Connection con=DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:XE",
"am1", "am1");
// Type III
//Connection con=DriverManager.getConnection("jdbc:ids://localhost:12/conn?dsn'
oraclesysdsn'", "am1", "am1");
System.out.println(con);
}
}
Note: In the above program we need often comment and uncomment to connect through different
drivers to DB. But in real time the driver must be loaded dynamically to connect to diff DBs.
Dynamic Jdbc Driver Connectivity program:
jdbc.properties
# jdbc.driver=sun.jdbc.odbc.JdbcOdbcDriver
# jdbc.url=jdbc:odbc:oracledsn
jdbc.driver=oracle.jdbc.driver.OracleDriver
jdbc.url=jdbc:oracle:oci:@XE
# jdbc.url=jdbc:oracle:thin:@localhost:1521:XE
# jdbc.driver=ids.sql.IDSDriver
# jdbc.url=jdbc:ids://localhost:12/conn?dsn='oraclesysdsn'
jdbc.user=am1
jdbc.pass=am1
// DBConn.java (Factory class)
import java.sql.*;
import java.util.*;
import java.io.*;
class DBConn {
// factory method
public static Connection getConn() throws Exception {
// to load properties file
Properties p=new Properties();
p.load(new FileInputStream("jdbc.properties"));
// to load driver
Class.forName(p.getProperty("jdbc.driver"));
// to establish Connection
Connection con=DriverManager.getConnection(p.getProperty("jdbc.url"),
p.getProperty("jdbc.user"), p.getProperty("jdbc.pass"));
return con;
}
}
// DBConnTest.java
import java.sql.*;
class DBConnTest {
public static void main(String rags[]) throws Exception {
Connection con=DBConn.getConn();
System.out.println(con);
}
}
create table dept (deptno number primary key,
deptname varchar2(20),
loc varchar2(20));
create table emp (eid number primary,
first_name varchar2(30),
last_name varchar2(30),
salary number,
hire_date date,
job_id varchar2(30),
mgr_id number reference emp(eid),
deptno number references dept(deptno));
DML, DRL statements execution using Statement interface
Executing INSERT, UPDATE, DELETE Statements using Statement interface:
The following program contains SQL INSERT statement hardcoded with values, hence it is static
insertion.
// StmtTest1.java
import java.sql.*;
class StmtTest1 {
public static void main(String rags[]) throws Exception {
Connection con = DBConn.getConn();
Statement stmt=con.createStatement();
int i=stmt.executeUpdate("INSERT INTO dept VALUES (7, 'Consulting', 'GNagar')");
System.out.println(i+" record inserted");
stmt.close();
con.close();
}
}
The following program dynamically takes dept details from STDIN and inserts record into DB
// StmtTest2.java
import java.sql.*;
import java.util.*;
class StmtTest2 {
public static void main(String rags[]) throws Exception {
Connection con = DBConn.getConn();
Statement stmt=con.createStatement();
Scanner sc=new Scanner(System.in);
int deptno=sc.nextInt();
String deptname=sc.next();
String loc=sc.next();
int i=stmt.executeUpdate("INSERT INTO dept VALUES ("+deptno+",'"+deptname+"',
'"+loc+"')");
System.out.println(i+" record inserted");
stmt.close();
con.close();
}
}
The following program updates dept details
// StmtTest3.java
import java.sql.*;
class StmtTest3 {
public static void main(String rags[]) throws Exception {
Connection con=DBConn.getConn();
Statement stmt=con.createStatement();
int i=stmt.executeUpdate("UPDATE dept SET loc='GNagar' WHERE deptno IN
(9,10)");
System.out.println(i+" records updated");
stmt.close();
con.close();
}
}
The following program deletes range of records from DB
// StmtTest4.java
import java.sql.*;
import java.sql.*;
class StmtTest4 {
public static void main(String rags[]) throws Exception {
Connection con=DBConn.getConn();
Statement stmt=con.createStatement();
int i=stmt.executeUpdate("DELETE FROM dept WHERE deptno BETWEEN 9 AND
10");
stmt.close(); con.close();
}
}
In JDBC Driver creates Connection, Connection creates Statement, PreparedStatement,
CallableStatement.
Connection interface is having 3 methods called:
• Statement createStatement();
• PreparedStatement prepareStatement(String sql);
• CallableStatement prepareCall(String callToFuncOrProc);
Statement interface is having 3 method called:
• int executeUpdate(String dmlStmts);
• ResultSet executeQuery(String
• boolean execute(String dmlOrDrl)
// StmtRSTest5.java
import java.sql.*;
class StmtRSTest5 {
public static void main(String rags[]) throws Exception {
Connection con=DBConn.getConn();
Statement stmt=con.createStatement();
ResultSet rs=stmt.executeQuery("SELECT * FROM dept");
// ResultSet is cursor pointing to records fetched in the DB buffer
// initially it points to before first record
// rs.next() moves cursor position to record
while(rs.next()) {
System.out.print
System.out.print(rs.getString(2)+"
System.out.println(rs.getString(3));
}
// reaches to after last
rs.close(); stmt.close(); con.close();
Statement interface is having 3 method called:
int executeUpdate(String dmlStmts);
ResultSet executeQuery(String drmlStmt);
boolean execute(String dmlOrDrl)
public static void main(String rags[]) throws Exception {
Connection con=DBConn.getConn();
Statement stmt=con.createStatement();
stmt.executeQuery("SELECT * FROM dept");
// ResultSet is cursor pointing to records fetched in the DB buffer
// initially it points to before first record
// rs.next() moves cursor position to record-by-record
while(rs.next()) {
System.out.print(rs.getInt(1)+"\t");
System.out.print(rs.getString(2)+"\t");
System.out.println(rs.getString(3));
// reaches to after last
rs.close(); stmt.close(); con.close();
// ResultSet is cursor pointing to records fetched in the DB buffer
}
}
Inserting records into emp table dynamically using Statement object:
// StmtTest6.java
import java.util.*;
import java.sql.*;
class StmtTest6 {
public static void main(String rags[]) throws Exception {
Connection con=DBConn.getConn();
Statement stmt=con.createStatement();
Scanner sc=new Scanner(System.in);
int eid=sc.nextInt();
String fname=sc.next();
String lname=sc.next();
double sal=sc.nextDouble();
String hdate=sc.next();
String jobid=sc.next();
int mgrid=sc.nextInt();
int deptno=sc.nextInt();
int i=stmt.executeUpdate("insert into emp values
("+eid+",'"+fname+"','"+lname+"',"+sal+",'"+hdate+"','"+jobid+"',"+mgrid+","+deptno+")");
System.out.println(i+" record inserted");
stmt.close();
con.close();
}
}
alter table emp modify eid number(2);
insert into emp values (10, 'xyz', 'lmn', 10000.00, '1-Jan-00', 'Faculty', 2, 3);
Statement Vs PreparedStatement:
con.createStatement() method returns Statement object. At the time of creating Statement object,
Statement object doesn't bound to any SQL command. Statement is having 2 methods for DML
operations they are executeUpdate(dml) and execute(dml), executeQuery(drl) method for DRL
operation. But in Statement.executeUpdate() method we need to add column values in ' and "
quotations to dynamically pass values. The quotation leads to confuse in syntax. Second point is in
executeUpdate() method every time we will pass the same SQL command or a different SQL
command. Each SQL command processing & execution takes 7 steps.
Instead of using Statement object for insert, update, delete, if we use PreparedStatement one is
performance increases because while creating PreparedStatement itself we will give SQL command:
PreparedStatement pstmt=con.prepareStatement("INSERT INTO emp VALUES (?,?,?,?,?,?,?,?)");
// SQL command goes to DB, processes and its execution planid comes back to pstmt object
pstmt.setInt(1, 11);
pstmt.setString(2, "XYZ");
pstmt.setInt(8, 3);
pstmt.executeUpdate(); // during this method call planid, colnames & its values goes to execution
plan, values goes into plan & the plan will execute. SQL command is not processed again and again,
hence with PreparedStatement performance increases.
This will increase the performance. If 5 records want to be executed SQL statement goes to DB only
once, 6 steps will executes, planid comes to pstmt object, after setting values through setInt(),
setString() methods and call executeUpdate(), then planid, colnames and values goes to plan and
only plan executes many times on DB.
Second one is instead of passing values in SQL command we are passing "IN Parameters as ?
symbol", this will eases the SQL syntax.
// PstmtTest7.java
import java.sql.*;
import java.util.*;
class PstmtTest7 {
public static void main(String rags[]) throws Exception {
Connection con=DBConn.getConn();
Statement stmt=con.createStatement();
PreparedStatement pstmt=con.prepareStatement("insert into emp VALUES
(?,?,?,?,?,?,?,?)");
// pk generation logic
// retrieve last PK, increment that value by 1
int eid=0;
ResultSet rs=stmt.executeQuery("SELECT max(eid) FROM emp");
if(rs.next()) {
eid=rs.getInt(1);
}
eid++;
// setting values into pstmt
pstmt.setInt(1, eid);
pstmt.setString(2, rags[0]);
pstmt.setString(3, rags[1]);
pstmt.setDouble(4, Double.parseDouble(rags[2]));
// convert String 1-3-2016 into java.sql.Date object
StringTokenizer st=new StringTokenizer(rags[3], "-");
int date=Integer.parseInt(st.nextToken());
int month=Integer.parseInt(st.nextToken());
month=month-1;
int year=Integer.parseInt(st.nextToken());
year=year-1900;
java.sql.Date hdate=new java.sql.Date(year, month, date);
pstmt.setDate(5, hdate);
pstmt.setString(6, rags[4]);
pstmt.setInt(7, Integer.parseInt(rags[5]));
pstmt.setInt(8, Integer.parseInt(rags[6]));
int i=pstmt.executeUpdate();
System.out.println(i+" record inserted");
pstmt.close();
con.close();
}
}
Writing a function to fetch salary from emp using eid
create or replace function fetch_emp_sal_by_eid(eid1 IN NUMBER) return NUMBER AS
v_sal emp.salary%TYPE;
-- v_sal NUMBER;
BEGIN
SELECT salary INTO v_sal FROM emp WHERE eid = eid1;
RETURN v_sal;
END;
/
Test the function on SQL Developer/SQL Prompt:
select fetch_emp_sal_by_eid(2) from dual;
Function calling CallableStatement:
// CStmtTest8.java
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.Types;
import java.util.Scanner;
public class CStmtTest8 {
public static void main(String[] args) throws Exception {
Connection con = DBConn.getConn();
CallableStatement cstmt = con.prepareCall("{?=call fetch_emp_sal_by_eid(?)}");
Scanner sc=new Scanner(System.in);
System.out.println("Enter EID");
int eid=sc.nextInt();
cstmt.setInt(2, eid);
cstmt.registerOutParameter(1, Types.DOUBLE);
cstmt.execute();
System.out.println(cstmt.getDouble(1));
cstmt.close();
con.close();
}
}
Procedure creation in SQL Developer:
create or replace procedure fetch_emp_details_by_eid(eid1 IN NUMBER,
fname OUT VARCHAR2, sal OUT NUMBER, job OUT VARCHAR2) AS
BEGIN
SELECT first_name, salary, desig INTO fname, sal, job FROM emp WHERE eid = eid1;
END;
/
Calling procedure from JDBC using CallableStatement:
// CStmtTest9.java
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.Types;
import java.util.Scanner;
public class CStmtTest9 {
public static void main(String[] args) throws Exception {
Connection con = DBConn.getConn();
CallableStatement cstmt = con.prepareCall("{call fetch_emp_details_by_eid
(?,?,?,?)}");
Scanner sc=new Scanner(System.in);
System.out.println("Enter EID");
int eid=sc.nextInt();
cstmt.setInt(1, eid);
cstmt.registerOutParameter(2, Types.VARCHAR);
cstmt.registerOutParameter(3, Types.DOUBLE);
cstmt.registerOutParameter(4, Types.VARCHAR);
cstmt.execute();
System.out.println(cstmt.getString(2));
System.out.println(cstmt.getDouble(3));
System.out.println(cstmt.getString(4));
cstmt.close();
con.close();
}
}
Your Assignments
insert record into dept using PreparedStatement
select al the records from emp using ResultSet
So far we covered ResultSet 1.0. As we know RS1.0 is a pointer pointing to DB buffer into which
records are fetched. RS1.0 is a unidirectional. Means after getting ResultSet we need to use rs.next()
to move from before first row to afterLast row and in each row we need to fetch columns using
rs.getInt(1), rs.getString(2) etc functions. Once ResultSet cursor reaches to afterLast record we can
move backward (afterLast row to beforeFirst row).
Hence in JDBC 2.0 a new ResultSet is introduced named Scrollable, Sensitive and Updatable
ResultSet.
How to create RS2.0? Scrollable-Sensitive RS
Statement stmt=con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,
ResultSet.CONCUR_READ_ONLY);
ResultSet rs=stmt.executeQuery(sql);
How to create RS2.0? Scrollable-Sensitive-updatable RS
Statement stmt=con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,
ResultSet.CONCUR_UPDATABLE);
ResultSet rs=stmt.executeQuery(sql);
Below is a Program on Scrollable and Sensitive ResultSet
// RSScrollSensTest8.java
import java.sql.*;
class RSScrollSensTest8 {
public static void main(String rags[]) throws Exception {
Connection con=DBConn.getConn();
Statement stmt=con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,
ResultSet.CONCUR_READ_ONLY);
ResultSet rs=stmt.executeQuery("SELECT * FROM emp");
while(rs.next()) {
System.out.println(rs.getInt(1)+" "+rs.getString("first_name")+"
"+rs.getString("job_id")+" "+rs.getDouble("salary"));
}
// to delay the program
System.in.read();
/* program prompts for user input, once ENTER key is pressed, program resumes */
/*
open sqlplus
UPDATE emp SET salary=15000.00 WHERE eid=6;
COMMIT;
*/
while(rs.previous()) {
rs.refreshRow();
System.out.println(rs.getInt(1)+" "+rs.getString("first_name")+"
"+rs.getString("job_id")+" "+rs.getDouble("salary"));
}
rs.last();
System.out.println(rs.getString("first_name"));
rs.first();
System.out.println(rs.getString("first_name"));
rs.absolute(6);
System.out.println(rs.getString("first_name")+rs.getDouble("salary"));
rs.close(); stmt.close(); con.close();
}
}
RS2.0 scrollable methods:
rs.next(), rs.previous(), rs.beforeFirst(), rs.afterLast(), first(), last(), absolute(int rowno)
RS 2.0 updatable methods:
update:
rs.absolute(6); rs.updateDouble(4, 15000.00); rs.updateRow();
delete:
rs.absolute(11); rs.deleteRow();
insert:
rs.moveToInsertRow();
rs.updateInt(1, 12);
rs.updateString(2, "Upendra");
rs.updateDouble(4, 20000.00);
rs.insertRow();
Below is a Program on Scrollable and Sensitive ResultSet
// RSUpdatableTest9.java
import java.sql.*;
class RSUpdatableTest9 {
public static void main(String rags[]) throws Exception {
Connection con=DBConn.getConn();
Statement stmt=con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,
ResultSet.CONCUR_UPDATABLE);
ResultSet rs=stmt.executeQuery("SELECT * FROM emp");
// update:
rs.absolute(6); rs.updateDouble(4, 15000.00); rs.updateRow();
// delete:
// rs.absolute(11); rs.deleteRow();
// insert:
/* rs.moveToInsertRow();
rs.updateInt(1, 12);
rs.updateString(2, "Upendra");
rs.updateDouble(4, 20000.00);
rs.insertRow(); */
rs.close(); stmt.close(); con.close();
}
}
Calling Functions and Procedures on DB using CallableStatement:
Oracle consists of SQL & PL/SQL. SQL is meant for DDL, DML, DRL, DCL. SQL operations we will
execute on SQLPrompt, SQL Editor and from JDBC programs. PL/SQL also we can execute from the
same 3 options. Because we are having SQL to manipulate and retrieve data from DB why we need
PL/SQL? PL/SQL stands for Programming Language with SQL.
For example we want to hike 5% sal to emps of Development department. i) The logic consists of
retrieve all the emps of Dev dept. ii) Fetch each sal into one local var iii) Cal 5% sal hike on sal iv) Add
that amt to existing sal to get new sal v) write update statement to update each emp sal with eid
and sal. vi) commit the tx.
To write such a above logic we can write it in java using JDBC API or in the DB if we want to write we
can create a function or procedure. Call that function or procedure from JDBC using
CallableStatement.
create a function in Oracle DB:
open SQL Developer
CREATE or REPLACE FUNCTION fetch_emp_sal_func (eid1 IN NUMBER) RETURN NUMBER AS
-- sal1 is a local var in function
sal1 NUMBER;
-- sal1 emp.salary%TYPE; -- anchored data type
BEGIN
-- on SQL prompt we will write
-- SELECT salary from emp; salary will be printed on SQL prompt.
-- But in PL/SQL when we write SELECT statement on COLUMNS
-- we need to assign the selected COLUMNS into local variables using INTO clause
SELECT salary INTO sal1 FROM emp WHERE eid=eid1;
RETURN sal1;
END;
/
Calling PL/SQL function from PL/SQL anonymous block:
What is anonymous block?
In PL/SQL if the code want to be reusable then we need to write PL/SQL code in function/procedure
and the same can be called for many times. If not if the PL/SQL code want to be execute instantly
then we need to write it in anonymous block. anonymous block code is not resuable.
SET SERVEROUTPUT ON;
DECLARE
sal1 emp.salary%TYPE;
BEGIN
-- In Java = is the assignment operator.
-- In PL/SQL assignment operator is :=. Local vars must
-- be initialized using :=
sal1:= fetch_emp_sal_func(1);
DBMS_OUTPUT.PUT_LINE('eid 1 sal is '||sal1);
END;
/
create one more function to fetch job_id using eid:
creating function:
CREATE OR REPLACE FUNCTION fetch_emp_jobid_func (eid1 IN NUMBER) RETURN VARCHAR2 AS
-- declaring local var using anchored data type
job_id1 emp.job_id%TYPE;
BEGIN
SELECT job_id INTO job_id1 FROM emp WHERE eid=eid1;
RETURN job_id1;
END;
/
calling function from anonymous block:
SET SERVEROUTPUT ON;
DECLARE
desig emp.job_id%TYPE;
BEGIN
desig:=fetch_emp_jobid_func(1);
DBMS_OUTPUT.PUT_LINE('emp desig is '||desig);
END;
/
Difference b/w function and procedure:
• Function returns a value
• Procedure doesn't return a value.
Function can return only one value.
Though procedure cannot return value procedure can take any number of IN, OUT and INOUT
parameters. Through many OUT parameters we can get any number of values.
create a procedure to fetch sal, job_id, deptno using eid:
CREATE OR REPLACE PROCEDURE fetch_emp_allcols_proc (eid1 IN NUMBER, salary1 OUT NUMBER,
job_id1 OUT VARCHAR2, deptno1 OUT NUMBER) IS
-- no local var are required because OUT params are there
BEGIN
SELECT salary, job_id, deptno INTO salary1, job_id1, deptno1 FROM emp WHERE eid=eid1;
END;
/
calling procedure:
SET SERVEROUTPUT ON;
DECLARE
desig emp.job_id%TYPE;
sal emp.salary%TYPE;
dno emp.deptno%TYPE;
eid1 NUMBER:=&eid; -- substitution var
BEGIN
fetch_emp_allcols__proc (eid1, sal, desig, dno);
DBMS_OUTPUT.PUT_LINE('eid '||eid1||' salary is '||sal||' desig is '||desig||' deptno is
'||dno);
END;
/
Write a procedure to update salaries of particular dept and display their total sal increment
amount:
CREATE OR REPLACE PROCEDURE emp_sal_upd_by_deptno_proc (dno IN NUMBER, hike IN
NUMBER, noeu OUT NUMBER, sosia OUT NUMBER) IS
-- declaring cursor
CURSOR emp_cur IS SELECT * FROM emp WHERE deptno=dno;
-- declare one local var of type emp record
emp_rec emp%ROWTYPE;
-- declare one local var for no of records
counter NUMBER:=0;
-- increment amount
incr_amt NUMBER:=0;
tot_amt NUMBER:=0;
BEGIN
OPEN emp_cur; -- open cursor
LOOP
FETCH emp_cur INTO emp_rec; -- fetch cursor
EXIT WHEN emp_cur%NOTFOUND;
incr_amt := emp_rec.salary * hike;
tot_amt := tot_amt + incr_amt;
UPDATE emp SET salary = emp_rec.salary + incr_amt WHERE eid = emp_rec.eid;
counter := counter+1;
END LOOP;
COMMIT;
CLOSE emp_cur; -- close cursor
noeu := counter;
sosia := tot_amt;
END;
/
calling procedure on SQL Prompt/SQL Developer:
SET SERVEROUTPUT ON;
DECLARE
dno NUMBER:=&deptno;
hike NUMBER:=&hike;
noeu NUMBER;
sosia NUMBER;
BEGIN
emp_sal_upd_by_deptno_proc (dno, hike, noeu, sosia);
DBMS_OUTPUT.PUT_LINE('In deptno '||dno||' no of emps updated '||noeu||' sum of sal
incremented '||sosia);
END;
/
function: fetch_emp_sal_func
function: fetch_emp_jobid_func
procedure: fetch_emp_allcols__proc
procedure: emp_sal_upd_by_deptno_proc
calling function fetch_emp_sal_func using CallableStatement:
------------------------------------------------------------
// CallFunc10.java
import java.sql.*;
class CallFunc10 {
public static void main(String rags[]) throws Exception {
Connection con=DBConn.getConn();
CallableStatement cstmt=con.prepareCall("{?=call fetch_emp_sal_func(?)}");
int eid = Integer.parseInt(rags[0]);
cstmt.setInt(2, eid);
cstmt.registerOutParameter(1, Types.DOUBLE);
cstmt.execute(); // function calls now
double sal = cstmt.getDouble(1);
System.out.println("Emp is "+eid+" sal is "+sal);
cstmt.close(); con.close();
}
}
calling function fetch_emp_jobid_func using CallableStatement:
// CallFunc11.java
import java.sql.*;
class CallFunc11 {
public static void main(String rags[]) throws Exception {
Connection con=DBConn.getConn();
CallableStatement cstmt=con.prepareCall("{?=call fetch_emp_jobid_func(?)}");
int eid=Integer.parseInt(rags[0]);
cstmt.setInt(2, eid);
cstmt.registerOutParameter(1, Types.VARCHAR);
cstmt.execute();
String desig=cstmt.getString(1);
System.out.println("Emp id "+eid+" job_id is "+desig);
cstmt.close(); con.close();
}
}
calling procedure fetch_emp_allcols__proc using CallableStatement:
// CallProc12.java
import java.sql.*;
class CallProc12 {
public static void main(String rags[]) throws Exception {
Connection con=DBConn.getConn();
CallableStatement cstmt=con.prepareCall("{call fetch_emp_allcols__proc(?,?,?,?)}");
int eid=Integer.parseInt(rags[0]);
cstmt.setInt(1, eid);
cstmt.registerOutParameter(2, Types.DOUBLE);
cstmt.registerOutParameter(3, Types.VARCHAR);
cstmt.registerOutParameter(4, Types.INTEGER);
cstmt.execute();
System.out.print("Emp id "+eid+"\t");
System.out.print("sal is "+cstmt.getDouble(2)+"\t");
System.out.print("Desig is "+cstmt.getString(3)+"\t");
System.out.println("Deptno is "+cstmt.getInt(4));
cstmt.close();con.close();
}
}
Calling procedure emp_sal_upd_by_deptno_proc using CallableStatement:
// CallProc13.java
import java.sql.*;
class CallProc13 {
public static void main(String rags[]) throws Exception {
Connection con=DBConn.getConn();
CallableStatement cstmt=con.prepareCall("{call
emp_sal_upd_by_deptno_proc(?,?,?,?)}");
int deptno=Integer.parseInt(rags[0]);
double hike=Double.parseDouble(rags[1]);
cstmt.setInt(1, deptno);
cstmt.setDouble(2, hike);
cstmt.registerOutParameter(3, Types.INTEGER);
cstmt.registerOutParameter(4, Types.DOUBLE);
cstmt.execute();
System.out.print("In deptno "+deptno+"\t");
System.out.print("after giving hike of "+hike+"\t");
System.out.print("The no of emps updated "+cstmt.getInt(3)+"\t");
System.out.println("and their sum of hike amount is "+cstmt.getDouble(4));
cstmt.close(); con.close();
}
}
Storing and Retreving Images:
How to store and retrive binary data to and from database.
In Oracle DB the data types are NUMBER, CHAR, VARCHAR2, DATE, BLOB, CLOB, REF.
• BLOB - Binary Large Object
• CLOB - Character Large Object
Using BLOB we can store images, audio, video, flash etc files into DB.
Using CLOB we can store character based document for ex: word, excel, txt files etc.
NUMBER - 38 digits value
CHAR - upto 4000 characters
VARCHAR - upto 4000 characters
BLOB & CLOB - upto 4GB
CREATE TABLE mypictures (id NUMBER PRIMARY KEY, name VARCHAR2(20), img BLOB);
// ImageStore14.java
import java.sql.*;
class ImageStore14 {
public static void main(String rags[]) throws Exception {
Connection con=DBConn.getConn();
PreparedStatement pstmt=con.prepareStatement("INSERT INTO mypictures VALUES
(?,?,?)");
pstmt.setInt(1, 1);
pstmt.setString(2, "MyName");
java.io.FileInputStream fis=new
java.io.FileInputStream("C:\\Users\\Public\\Pictures\\Sample Pictures\\Chrysanthemum.jpg");
pstmt.setBinaryStream(3, fis);
int i=pstmt.executeUpdate();
System.out.println(i+" record inserted");
pstmt.close();
con.close();
}
}
// ImageRestore15.java
import java.sql.*;
import java.io.*;
class ImageRestore15 {
public static void main(String rags[]) throws Exception {
Connection con=DBConn.getConn();
Statement stmt=con.createStatement();
ResultSet rs=stmt.executeQuery("SELECT * FROM mypictures");
if(rs.next()) {
System.out.println(rs.getInt(1));
System.out.println(rs.getString(2));
InputStream in=rs.getBinaryStream(3);
FileOutputStream fos=new FileOutputStream("MyPicture.jpg");
int i=in.read();
while(i!=-1) {
fos.write(i);
i=in.read();
}
}
rs.close(); stmt.close(); con.close();
}
}
RowSets:
In JDK JDBC API exist in java.sql package. javax.sql is a JDBC extension package. This package contains
some additional feature classes called RowSets and Connection Pooling.
RowSet (i)
|
----------------------------------------
| |
JdbcRowSet(i) CachedRowSet(i)
|
-------------------------------------------------------------
| | |
FilteredRowSet(i) JoinRowSet(i) WebRowSet(i)
JDBC 3.0 feature RowSet:
RowSet is a base interface to all its sub interfaces. This this interface doesn't have any end user
functionality.
JdbcRowSet:
JdbcRowSet is a connected RowSet. Along with JdbcRowSet, RS1.0, RS 2.0 are also a connected
resultsets because ResultSet is a pointer to DB buffer. Each method call such as next() and get()
methods on ResultSet goes to DB buffer. For example to fetch records from emp table (contains 8
columns and 10 records/rows), ResultSet makes 98 n/w calls to DB. Same way JdbcRowSet also
functions. Hence ResultSet 1.0, 2.0 and JdbcRowSet are expensive. JdbcRowSet is also a scrollable
(next(), forward()), sensitive & updatable resultset.
CachedRowSet:
CachedRowSet is a disconnected rowset, that means initially we need to fetch records using
resultset, after fetching in CachedRowSet there is one method exist named populate(rs). populate()
method populates records from DB buffer to Java buffer. After populating records into Java buffer
we can disconnect from DB (con.close()). But still CachedRowSet survives, we can scroll up &
downwards directions. Hence CachedRowSet is also a scrollable resultset but not senstive and
updatable.
// JdbcRowSetDemo16.java
import javax.sql.rowset.JdbcRowSet;
import com.sun.rowset.JdbcRowSetImpl;
class JdbcRowSetDemo16 {
public static void main(String rags[]) throws Exception {
Class.forName("oracle.jdbc.driver.OracleDriver");
JdbcRowSet jrs=new JdbcRowSetImpl();
jrs.setUrl("jdbc:oracle:thin:@localhost:1521:XE");
jrs.setUsername("am1");
jrs.setPassword("am1");
jrs.setCommand("SELECT * FROM dept");
jrs.execute();
// forward fetch/navigation
while(jrs.next()) {
System.out.print(jrs.getString(1)+"\t");
System.out.print(jrs.getString(2)+"\t");
System.out.println(jrs.getString(3));
}
// backward fetch/navigation
while(jrs.previous()) {
System.out.print(jrs.getString(1)+"\t");
System.out.print(jrs.getString(2)+"\t");
System.out.println(jrs.getString(3));
}
jrs.close();
/*
In JbbcRowSet we are providing/supplying URL, username, password and
SQL command through setter methods and calling excute(). The moment we will call execute()
method JdbcRowSet internally creates con,stmt & rs object, but they are not exposed in JDBC
program. Once JdbcRowSet is closed that internally closes con, stmt & rs objects.
*/
}
}
// CachedRowSetDemo17.java
import javax.sql.rowset.CachedRowSet;
import com.sun.rowset.CachedRowSetImpl;
import java.sql.*;
class CachedRowSetDemo17 {
public static void main(String rags[]) throws Exception {
Connection con=DBConn.getConn();
Statement stmt=con.createStatement();
ResultSet rs=stmt.executeQuery("SELECT * FROM dept");
CachedRowSet crs=new CachedRowSetImpl();
crs.populate(rs); // data copies into java buffer
// to prove crs as disconnected rowset, close the con
rs.close(); stmt.close(); con.close();
// crs object is still alive
// forward fetch/navigation
while(crs.next()) {
System.out.print(crs.getString(1)+"\t");
System.out.print(crs.getString(2)+"\t");
System.out.println(crs.getString(3));
}
// backward fetch/navigation
while(crs.previous()) {
System.out.print(crs.getString(1)+"\t");
System.out.print(crs.getString(2)+"\t");
System.out.println(crs.getString(3));
}
crs.close(); // now java buffer closes
}
}
Transactions:
To implement Transactions we need to satisfy ACID properties:
• Atomicity
• Consistency &
• Isolation
• Durability
Atomicity:
All-or-none basis.
In a business transaction more than one SQL operation may involve, if all the SQL operations are
successful then only the entire transaction should be committed, if any one SQL operations fails in a
overall transaction the entire transaction should be rollbacked.
In JDBC it is mandatory to implement Atomicity because on SQL Prompt by default the auto commit
is false, hence if we perform DML operation on SQL Prompt, the updation may not committed by
default, we need to explicitly issue commit or rollback. Whereas in JDBC the moment DML operation
executes on DB the changes will be automatically committed even though the remaining SQL
operations fails.
Hence in JDBC soon after obtaining con object, we need to call con.setAutoCommit(false);
perform more than one DML operation using stmt.executeUpdate(),
verify whether all SQL operations are successful or not, if all are successful then issue con.commit(),
otherwise issue con.rollback();
create account & txlog tables.
create table account (accno number primary key, bal number);
create table txlog (txid number primary key, amt number, fromaccno number, toaccno number,
txstatus number);
insert into account values (1, 10000.00);
insert into account values (2, 20000.00);
commit;
// AtomicityDemo18.java
import java.sql.*;
class AtomicityDemo18 {
public static void main(String rags[]) throws Exception {
Connection con=DBConn.getConn();
Statement stmt=con.createStatement();
con.setAutoCommit(false);
int i=stmt.executeUpdate("update account set bal=bal-"+rags[1]+" where
accno="+rags[0]);
int j=stmt.executeUpdate("update account set bal=bal+"+rags[1]+" where
accno="+rags[2]);
if(i==1 && j==1) {
con.commit();
System.out.println("TX Success");
} else {
con.rollback();
System.out.println("TX Failed");
}
stmt.close();
con.close();
}
}
java AtomicityDemo18 1 1000.00 3
java AtomicityDemo18 1 1000.00 2
Consistency & Isolation:
To achieve consistency we need to prevent inconsistency by applying isolation levels.
Types of inconsistencies:
i. Dirty Read
ii. Non-repeatable Read
iii. Phantom Read
Isolation Levels:
• Connection.TRANSACTION_NONE
• Connection.TRANSACTION_READ_UNCOMMITTED
• Connection.TRANSACTION_READ_COMMITTED
• Connection.TRANSACTION_REPEATABLE_READ
• Connection.TRANSACTION_SERIALIZABLE
To prevent Dirty Read - TRANSACTION_READ_COMMITTED
To prevent Non-repeatable Read - TRANSACTION_REPEATABLE_READ
To prevent Phantom Read - TRANSACTION_SERIALIZABLE
What is Dirty Read:
When a TX reads uncommitted changes made by others such a read is called as Dirty Read.
open two SQL prompts:
SQL Prompt #1
SQL> update account set bal=bal-10 where accno=1;
SQL> select * from account where accno=1;
9960
SQL Prompt #2
SQL> select * from account where accno=1;
9970 - it's a No Dirty Read
9960 - it's a Dirty Read
SQL> SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
SQL> select * from account where accno=1;
The same Dirty Read Problem if want to be prevented in JDBC, we need to write:
con.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
What is Non/Un-Repeatable Read
In a TX, balance shown on a record may not be shown again due to because of concurrently
executed TX on the same record.
TX #1
select * from account where accno=1;
9970
TX #2
update account set bal=bal-8000.00 where accno=1;
commit;
select * from account where accno=1;
1970
TX #1
select * from account where accno=1;
1970
Non-repeatable read occur due to because concurrent access on the same record. To prevent we
must apply:
con.setTransactionIsolation(Connection.TRANSACTION_REPEATABLE_READ); This will apply lock on
record.
Phantom Read:
In a TX, in between a select & update/select on a table, the number of records shown may increase
or decrease because of concurrent insert/delete on the same table. New records may come/appear
or existing record may disappear in between SQL operations on the same table of the same TX is
treated as Phantom Read Problem.
To prevent this issue TRANSACTION_SERIALIZABLE isolation level.
con.setTransactinIsolation(Connection.TRANSACTION_SERIALIZABLE);
Conclusion:
During SELECT - apply READ COMMITTED
During UPDATE - apply REPEATABLE READ
During INSERT/DELETE - apply SERIALIZABLE
Servlets
ServletsServletsServletsServlets By SuryanarayanaBy SuryanarayanaBy SuryanarayanaBy Suryanarayana
ActiveNET
Course Content:
i) Introduction to Web application & Web site projects
ii) Java Web application directory structure
iii) Develop, deploy and run first web application in java
iv) Introduction to web server, web container, web application, web document, web
component, SevletContext, Servlet, ServletConfig, ServletRequest, ServletResponse,
HttpSession etc.
v) Difference b/w request parameters, initialization parameters and context parameters
and how to pass, receive them in servlet and process / use them.
vi) One form processing example with all the parameters
vii) Difference b/w stateless and stateful servlets
viii) Different types of servlets named GenericServlet and HttpServlet
ix) Achieving Session management and client state persistence in HttpServlet and one
example
x) Different types of session management
1. Cookies, Hidden fields, URL rewriting
xi) Non idem-potency problem and its prevention using token concept
xii) Client state persistence on server using HttpSession object and client state persistence
on client system using Cookies.
xiii) xiii) Servlet-Servlet communication/Inter-servlet communication with the web
application, across web application using RequestDispatcher class forward() and
include() methods, across web servers using Socket programming and other one is using
response.sendRedirect()
xiv) xiv) Developing Filters in Servlets
xv) xv) Importance and usage of Listeners
xvi) xvi) Securing Servlets
xvii) xvii) Pagination in Servlets using Scrollable ResultSet and Pager tags
xviii) xviii) JDBC Connection Pooling in Servlets
xix) xix) File upload processing in servlets
xx) xx) InternationalizatioN in web applications using Locale and ResourceBundle classes
xxi) xxi) Sending email from standalone/servlets using SMTP API
xxii) xxii) Receiving emails using POP3 API
What is the difference between web site projects & web application projects?
A web project which uses only static resources such as .html, .js, .css, .jpg, .gif, .au, .pdf, .swf, .mpg
etc are called as web site projects/static web sites.
A web project which uses dynamic resources along with static resources is called as "web
application projects". Dynamic resources are Servlets, JSP, ASP, PHP, ColdFusion CFM, Ruby on Rails,
Python Djongo. These dynamic resources always exist and run on server system but only produce
dynamic web page output to browser. Static resources such as .html, css, .js, .jpg etc directly
downloads onto browser and runs.
The intention of dynamic resources is whenever user submits a form data from the browser, we
need a server side resource to read the form data, validate, process and store the data to and from
DB. In java we will use JDBC/Hibernate/any ORM framework API to implement servlet/jsp to interact
with databasse on server system.
In web site projects static html files are placed in web site root directory, images are placed in
\images folder, javascript and css are placed in \script and \style folders and so on.
But whereas in web application projects for each technology the web application directory structure
differs. For instance in java web applications the directory structure is:
hello_1
index.html
\script\.js
\style\.css
\images\.jpg
\jsp\.jsp
\WEB-INF
web.xml - to configure servlets, filters, listeners etc
\classes
all compiled servlet .class files must be placed in this folder
other than servlets, like filters or listeners or beans or factory must be placed in packages
under this folder
\lib
3rd party jar files
In PHP based web application projects the html files must be placed in public_html folder.
css
style.css
images
includes
header.php
footer.php
db_connect.php
functions.php
js
validation.js
lib
plugins
uploads
index.php
In ASP.net web application the project directory contains as follows:
• BIN
• App_Code
• App_GlobalResources
• App_LocalResources
• App_WebReferences
• App_Data
• App_Browsers
• App_Themes
Both web site projects and as well web application projects are deployed on local or www server.
Their URL is accessed from client's web browser. Static html pages are downloaded, once they are
filled and submitted by client the server side resources like servlets and jsp, accept the request,
process and responds to clients.
To run server side resources we need both compiler and interpreter because when JSPs requested
for the first time JSP container translates them into servlet, compiled by jsp container using javac
and then servlet container runs them using java interpreter. Whereas servlets are pre-compiled and
placed in web server to run them java interpreter is sufficient.
The classes placed in web application projects must be placed in appropriate namespaces. As we
discussed earlier other than servlet class must be placed in package in java web applications.
Develop, deploy and run first web application in java
To DDR web application along with JDK we need one Java Web Server also.
WebServers:
i) Apache – Tomcat
ii) Mortbay - Jetty
iii) Caucho - Resin
iv) Cheyenne Secure Web Server
Obsolote web servers:
i) ServletRunner - Sun
ii) JWS (Java Web Server) - Sun
iii) Atlanta Corp ServletExec
iv) iPlanet - iPlanet Web Server
v) Macromedia - Cold Fusion Server
vi) Allaire Corp - JRun Web Server
Application Servers:
i) IBM - WebSphere AS
ii) BEA/Oracle - WebLogic AS
iii) RedHat - JBoss AS
iv) Pramati - Pramati AS
v) Fujitsu - AS
vi) HP - AS
vii) Fiorana - Fiorana AS
viii) Progress - AS
ix) Oracle - OC4J / BC4J
Oracle Container for Java / Business Container for Java
x) Caucho - Resin AS
xi) Apache - Geronimo
xii) Sun Microsystems - Sun One/GlassFish
Tomcat Installation:
To install Tomcat we need to download the tomcat zip file or installer file.
If installer file is installed, during installation the path will be prompted C:\Program Files\apache-
tomcat-6.0.37-windows-x86\apache-tomcat-6.0.37, followed by prompting the password of admin
user, port number and JDK installation path.
If ZIP file is extracted then we need to include JAVA_HOME, JRE_HOME and CATALINA_HOME
environment variables that tomcat startup process uses.
JAVA_HOME
D:\Program Files\Java\jdk1.6.0_35
CATALINA_HOME
C:\Program Files\apache-tomcat-6.0.37-windows-x86\apache-tomcat-6.0.37
tomcat
bin\
startup.bat, shutdown.bat
conf\
server.xml, tomcat-users.xml
lib\
servlet-api.jar, jsp-api.jar; catalina.jar
only servlet-api.jar file must be included in CLASSPATH
logs\
catalina.log, host-manager.log, localhost.log, manager.log
webapps\
java web applications like first.war file must be deployed
first.war
E:\active\adv\am36\Servlets\hello_1\
index.html
WEB-INF - directory
web.xml
classes - directory
HelloServlet.java, HelloServlet.class
index.html
<HTML>
<BODY>
<FORM action="./helloServlet">
Name <INPUT type="text" name="name">
<INPUT type="submit" name="submit" value="Say Hello">
</FORM>
</BODY>
</HTML>
To write and compile servlet servlet-api.jar file must be included in CLASSPATH. Servlet API exists in
javax.servlet package. In that one interface is given named Servlet. This interface is having 5
abstract methods that every servlet class must implement.
Instead of implementing from Servlet interface and implement all the 5 abstract methods, to Servlet
interface one adapter class is given named GenericServlet in which all 4 abstract methods are
implemented and one method is left abstract, the abstract method is
public void service(ServletRequest req, ServletResponse resp) throws ServletException, IOException;
First Java Web Application
// HelloServlet.java
import javax.servlet.*;
import java.io.*;
public class HelloServlet extends GenericServlet {
public void service(ServletRequest req, ServletResponse resp) throws ServletException, IOException {
String name=req.getParameter("name").trim();
PrintWriter out=resp.getWriter();
out.println("Hello "+name);
out.flush();
out.close();
}
}
web.xml
<web-app>
<servlet>
<servlet-name>helloServlet</servlet-name>
<servlet-class>HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>helloServlet</servlet-name>
<url-pattern>/helloServlet</url-pattern>
</servlet-mapping>
</web-app>
compile servlet
E:\active\adv\am36\Servlets\first\WEB-INF\classes
javac *.java
make web application or .war (Web ARchieve) file
cd..
cd..
jar -cvf am37first.war *.html WEB-INF
.war file is created. War file is also called as java web application.
Jar command options
c - create a jar
u - update a jar
x - extract data from jar
l - display list of content
v - verbose output on
f - specifying file name
deploy am36first.war into webapps directory of tomcat web server.
and click on <tomcat>\bin\starup.bat
open browser and type
http://localhost:8082/am37first/index.html
As soon as we deploy first web application and start tomcat web server, tomcat extracts the .war file
(Web ARchieve) into the same war named folder. Web applications can be deployed as folders also
directly into tomcat webapps directory. But if we want to deploy web application on remote server
system, the ftp upload will take time to deploy. Hence if we make .war and deploy, the compressed
files will reduce the folder size to more than half of the size of original folder, deployment time
reduces.
During tomcat server startup, tomcat starts 3 processes called
• HTTPEngine (Coyote)
• Servlet container (Catalina)
• and JSP Container (Jasper)
When client requests for a static resource (other than servlet & jsp), the web server redirects the call
to HTTP engine, HTTP engine reads the web application name, into the corresponding folder the
client requested HTML document will be lookuped. If the file is found using input & outputstreams
the HTML file content will be sent to browser. Otherwise 404 file not found error is sent to client
browser.
Client submits the HTML form data to web server. If the request comes to a servlet, Servlet
container runs the servlet. Before running a servlet, at the time of web application deployment or
during server startup, servlet container goes to each web application reads, web.xml file and creates
one new instance of ServletContext object. ServletContext object contains servlet configuration
data. url-pattern mapped to servlet-name, servlet-name mapped to servlet class. Along with this
ServletContext also contains context-params passed from web.xml file. Such all web applications
ServletContext objects are stored with their respective web application name into one more
hashtable.
Servlet instance is created by servlet container in two occasions. If servlet load-on-startup property
is mentioned as 1 or 2 or 3. In the load-on-startup property order the servlet instances are created. If
not mentioned servlet instance is created during first client request to that servlet. As soon as
servlet is instantiated, on the servlet init(ServletConfig sc) method will be called, ServletConfig object
is passed as argument into it. ServletConfig contains all the init-params passed into that servlet
through web.xml. It also contains getServletContext() method from which we can retrieve context
parameters.
Using init and context parameters we can initialize servlet class instance variables such as
Connection, Statement, PreparedStatement, Logger, Connection Pool object object DataSource etc.
******************************************************************************
Context parameters are passed by web developer, passed from web.xml file, in servlet init() method
using servletConfig.getServletContext() we can obtain ServletContext object reference. In service()
method the object must be obtained directly by calling getServletContext() method. Context
parameters are passed into servlet only once through init() method via ServletConfig object. Context
parameters are retrieved using sctxt.getInitParameter(String paramName).
Init Parameters are also passed by web developer, from web.xml file, passed as ServletConfig object
into init() method. init parameters are also retrieved only once in init() method. The parameters can
be retrieved using getInitParameter() method.
Request parameters are the form data filled and submitted by client from HTML form.
ServletContainer/Web Server reads HTTP request, reads request parameters, stores into
ServletRequest/HttpServletRequest object and passed as argument into service() method. Every
client passed his/her form data is passed as request parameters. For every client request new
ServletRequest and ServletResponse objects are created and passed as argument. Once service()
method execution is completed. req and resp objects are destroyed.
******************************************************************************
Including from first client onwards servlet container creates new thread for each client. Passes
servlet instance as argument into new thread starts the thread. The Thread class run method will
invoke service() method on servlet instance. For each client one new thread is created and servlet
instance is executed from multiple threads. Such execution is called as Singleton-MultiThread model.
As soon the code written in the service() method execution is completed, the client corresponding
thread object is destroyed, but servlet instance remains alive.
Servlet container removes servlet instance in two occasions:
i) During web application undeployment
ii) During web server shutdown
While destroying servlet instance, servlet container will call destroy() method. In the destroy()
method we will uninitialize servlet class instance variables.
Second Java Web Application
E:\active\adv\am36\Servlets\params_2
NewEmp.html
NewEmpServlet.java
web.xml
log4j.properties
build.xml
NewEmp.html
<HTML>
<BODY>
<FORM method="post" action="./newEmpServlet" onSubmit="return validateForm()">
<TABLE width="50%" align="center">
<TR>
<TH>First Name</TH>
<TD><INPUT type="text" name="first_name" id="first_name" ></TD>
</TR>
<TR>
<TH>Last Name</TH>
<TD><INPUT type="text" name="last_name" id="last_name"></TD>
</TR>
<TR>
<TH>Salary</TH>
<TD><INPUT type="text" name="salary" id="salary" ></TD>
</TR>
<TR>
<TH>Hire Date <span style="font-size:10px;font-
style:italic;color:red;">(dd/mm/yyyy)</span></TH>
<TD><INPUT type="text" name="hire_date" id="hire_date" ></TD>
</TR>
<TR>
<TH>Job ID</TH>
<TD><INPUT type="text" name="job_id" id="job_id" ></TD>
</TR>
<TR>
<TH>Mgr ID</TH>
<TD><INPUT type="text" name="mgr_id" id="mgr_id" ></TD>
</TR>
<TR>
<TH>Deptno</TH>
<TD><INPUT type="text" name="deptno" id="deptno" ></TD>
</TR>
<TR>
<TH><INPUT type="submit" name="submit" value="Save Emp"></TH>
<TD><INPUT type="reset" name="reset" value="Clear Form"></TD>
</TR>
</TABLE>
</FORM>
</BODY>
<HEAD>
<style>
body{
background-color:"red";
}
</style>
<SCRIPT>
var err=" ";
function validateForm() {
// window.alert('in validateForm');
err=validateFirstName();
err+=validateLastName();
err+=validateSalary();
err+=validateHireDate();
err+=validateJobId();
err+=validateMgrId();
err+=validateDeptNo();
// window.alert('before if');
if(err.length>0) {
window.alert(err);
// window.alert('false');
return false;
} else {
// window.alert('true');
return true;
}
}
function validateFirstName() {
var f_n=window.document.getElementById("first_name");
var value=f_n.value;
if(value.length==0)
return "First Name cannot be null \n";
}
function validateLastName() {
var f_n=window.document.getElementById("last_name");
var value=f_n.value;
if(value.length==0)
return "Last Name cannot be null \n";
}
function validateSalary() {
var f_n=window.document.getElementById("salary");
var value=f_n.value;
if(value.length==0)
return "Salary cannot be null \n";
}
function validateHireDate() {
var f_n=window.document.getElementById("hire_date");
var value=f_n.value;
if(value.length==0)
return "Hire Date cannot be null \n";
}
function validateJobId() {
var f_n=window.document.getElementById("job_id");
var value=f_n.value;
if(value.length==0)
return "Job Id cannot be null \n";
}
function validateMgrId() {
var f_n=window.document.getElementById("mgr_id");
var value=f_n.value;
if(value.length==0)
return "Mgr ID cannot be null \n";
}
function validateDeptNo() {
var f_n=window.document.getElementById("deptno");
var value=f_n.value;
if(value.length==0)
return "Deptno cannot be null \n";
}
</SCRIPT>
</HEAD>
</HTML>
<!--
// window.alert(isNaN(value));
if(isNaN(value)==true)
return "Salary is not a double\n";
/* try {
parseFloat(value);
}catch(err) {
return err+"\n";
}*/
-->
// NewEmpServlet.java
import javax.servlet.*;
import java.io.*;
import java.sql.*;
import org.apache.log4j.*;
import org.apache.commons.validator.routines.*;
public class NewEmpServlet extends GenericServlet {
Connection con;
Statement stmt;
PreparedStatement pstmt;
ResultSet rs;
Logger logger;
public NewEmpServlet() {
System.out.println("NewEmpServlet() called");
}
// first lifecycle method
public void init(ServletConfig sc) throws ServletException {
logger=Logger.getLogger(this.getClass());
ServletContext sctxt=sc.getServletContext();
logger.debug("sctxt obtained");
try {
Class.forName(sctxt.getInitParameter("DRIVER"));
logger.debug("driver class loaded");
con=DriverManager.getConnection(sctxt.getInitParameter("URL"), sc.getInitParameter("USER"),
sc.getInitParameter("PASS"));
logger.debug("con established");
stmt=con.createStatement();
logger.debug("stmt created");
pstmt=con.prepareStatement("INSERT INTO employee VALUES (?,?,?,?,?,?,?,?)");
logger.debug("pstmt created");
}
catch(Exception e) {
e.printStackTrace();
logger.error(e.toString());
}// catch()
}//init()
// second lifecycle method
public void service(ServletRequest req, ServletResponse resp) throws ServletException, IOException
{
PrintWriter out=resp.getWriter();
// read request parameters
String first_name=req.getParameter("first_name").trim();
String last_name=req.getParameter("last_name").trim();
double salary=Double.parseDouble(req.getParameter("salary").trim());
String hire_date=req.getParameter("hire_date").trim();
String job_id=req.getParameter("job_id").trim();
int mgr_id=Integer.parseInt(req.getParameter("mgr_id").trim());
int deptno=Integer.parseInt(req.getParameter("deptno").trim());
logger.debug("Request parameter read");
// server side validations
String err="";
DoubleValidator dv=new DoubleValidator();
if(dv.validate((salary+"")==null)
err+="Salary is not a double value<br>";
DateValidator dav=new DateValidator();
if(dav.validate(hire_date)==null)
err+="HireDate is invalid date<br>";
IntegerValidator iv=new IntegerValidator();
if(iv.validate(mgr_id+"")==null)
err+="Mgr ID is not a valid int<br>";
if(iv.validate(deptno+"")==null)
err+="Deptno is not a valid int<br>";
if(err.length()>0) {
out.println(err);
out.flush();
logger.error(err);
} else {
// DB operations
// insert record into employee table
logger.info("validations are successful");
try {
// generate PK
int eid=0;
rs=stmt.executeQuery("SELECT max(eid) FROM employee");
if(rs.next()) {
eid=rs.getInt(1);
}// if()
eid++;
// record insertion
pstmt.setInt(1, eid);
pstmt.setString(2, first_name);
pstmt.setString(3, last_name);
pstmt.setDouble(4, salary);
java.util.StringTokenizer st=new java.util.StringTokenizer(hire_date, "/");
String date=st.nextToken();
String month=st.nextToken();
String year=st.nextToken();
java.sql.Date sdate=new java.sql.Date((Integer.parseInt(year)-1900), (Integer.parseInt(month)-
1), Integer.parseInt(date));
pstmt.setDate(5, sdate);
pstmt.setString(6, job_id);
pstmt.setInt(7, mgr_id);
pstmt.setInt(8, deptno);
pstmt.executeUpdate();
out.println("employee record inserted, eid is "+eid);
logger.info("employee record inserted, eid is "+eid);
}// try
catch(Exception e) {
e.printStackTrace();
logger.error(e);
}// catch()
}// else
}// service()
// last lifecycle method
public void destroy() {
try {
rs.close(); pstmt.close(); stmt.close(); con.close();
}
catch(Exception e) {
e.printStackTrace();
}// catch()
}// destroy()
}// class
web.xml
<web-app>
<context-param>
<param-name>DRIVER</param-name>
<param-value>oracle.jdbc.driver.OracleDriver</param-value>
</context-param>
<context-param>
<param-name>URL</param-name>
<param-value>jdbc:oracle:thin:@localhost:1521:XE</param-value>
</context-param>
<servlet>
<servlet-name>nes</servlet-name>
<servlet-class>NewEmpServlet</servlet-class>
<init-param>
<param-name>USER</param-name>
<param-value>am36</param-value>
</init-param>
<init-param>
<param-name>PASS</param-name>
<param-value>am36</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>nes</servlet-name>
<url-pattern>/newEmpServlet</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>NewEmp.html</welcome-file>
</welcome-file-list>
</web-app>
log4j.properties
# log4j.rootLogger=debug,stdout,datefile,pattern,html,xml
log4j.rootLogger=debug,stdout,datefile,html
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.TTCCLayout
log4j.appender.datefile=org.apache.log4j.FileAppender
log4j.appender.datefile.File=MyApp.log
log4j.appender.datefile.layout=org.apache.log4j.PatternLayout
log4j.appender.datefile.layout.conversionPattern=%c %C %d %F %l %L %p %r %t - %m%n
log4j.appender.html=org.apache.log4j.FileAppender
log4j.appender.html.File=MyApp.html
log4j.appender.html.layout=org.apache.log4j.HTMLLayout
build.bat
md WEB-INF
md WEB-INF\classes
md WEB-INF\lib
javac -d .\WEB-INF\classes NewEmpServlet.java
copy logj.properties \WEB\classes
copy ojdbc14.jar \WEB\lib
jar -cvf second_form_params.war *.html *.css *.js *.png WEB-INF
copy second_form_params.war %tomcat%\webapps
windows dependent build .bat/.cmd extension file is. we want to platform independent build
processing file. That is ANT.
build.xml
<project name="second_web" default="all">
<target name="init">
<property name="build" value="build"/>
<property name="webinf" value="${build}\WEB-INF"/>
<property name="classes" value="${webinf}\classes"/>
<property name="lib" value="${webinf}\lib"/>
<property name="oraclelib"
value="D:\oraclexe\app\oracle\product\10.2.0\server\jdbc\lib\ojdbc14.jar"/>
<property name="log4jlib" value="D:\apache-log4j-1.2.17\log4j-1.2.17.jar"/>
<property name="commonsvalidatorlib" value="E:\active\adv\am36\commons-validator-1.4.0-
bin\commons-validator-1.4.0\commons-validator-1.4.0.jar"/>
<property name="tomcatdeploy" value="C:\Program Files\apache-tomcat-6.0.37-windows-
x86\apache-tomcat-6.0.37\webapps"/>
</target>
<target name="md" depends="init">
<mkdir dir="${build}"/>
<mkdir dir="${webinf}"/>
<mkdir dir="${classes}"/>
<mkdir dir="${lib}"/>
</target>
<target name="copy" depends="md">
<copy file="NewEmp.html" todir="${build}"/>
<copy todir="${build}">
<fileset dir="." includes="*.js,*.css,*.gif,*.png"/>
</copy>
<copy file="web.xml" todir="${webinf}"/>
<copy file="log4j.properties" todir="${classes}"/>
<copy file="${oraclelib}" todir="${lib}"/>
<copy file="${log4jlib}" todir="${lib}"/>
<copy file="${commonsvalidatorlib}" todir="${lib}"/>
</target>
<target name="compile" depends="copy">
<javac srcdir="." destdir="${classes}" classpath="${commonsvalidatorlib}"/>
</target>
<target name="war" depends="compile">
<jar basedir="${build}" destfile="second_form_params.war"/>
</target>
<target name="deploy" depends="war">
<copy file="second_form_params.war" todir="${tomcatdeploy}"/>
</target>
<target name="delay" depends="deploy">
<sleep milliseconds="1000"/>
</target>
<target name="home" depends="delay">
<exec command="C:\Program Files\Internet Explorer\IEXPLORE.exe
http://localhost:8081/second_form_params/NewEmp.html"/>
</target>
<target name="all" depends="home">
</target>
</project>
In the above servlet we declared con, stmt, pstmt, rs variables as class instance variables. Class
instance variables in servlet are not thread-safe because servlet runs in a singleton-multithread
model. If con, stmt are declared as class instance variables, initialized in init() method and used in
service(). The same con & stmt objects are used by service() method in multiple threads, if on a stmt
object one resultset object is opened and is under use, in another thread process on the same stmt
object if one more rs is opened, the first resultset object implicitly closes. The another problem is in
the above servlet, we retrieved request parameters, validated fields, generated PK value and stored
in DB using pstmt object.
In this process during first client request the service() method execution starts in one thread, the
thread executed upto PK generation, the first thread allocated time is completed, so that second
thread starts its execution, in the second thread also the service() method executed upto PK
generation only. The problem is whichever PK value first thread has retrieved, the same value
service() method in second thread also retrieves and increments for PK. Because of round-robin
fashion of threads execution control comes first thread. First thread successful inserts record into
DB, the first thread process destroys. Second thread execution starts, in second thread the service()
method tries to insert a record with that ID/PK one record is already inserted in the DB in the
previous thread operation.
Apply TRANSACTION_SERIALIZABLE isolation level to prevent this problem, but still declaring con,
stmt & pstmt declared as class instance are not safe from servlet running in multiple threads.
Hence declaring such variables in service() method is recommended. But if declared service()
method performance will be effected and load on DB increases.
The solution is every web server and application server in-turn supports JDBC connection pooling.
Connection pool is also a one of the service runs in web and application servers. In contrast with
JDBC program, connection pooling service don't perform any DB operations instead it will maintain
pool of DB connections. When number of clients requests for more than its initial capacity of
connections, CPMs will increase number of connection two-two more like that up-to maximum
number of connections. If clients request more than DB connections capacity, such client requests
are kept in queue until the existing connection comes back to pool. JDBC applications who
completes their DB operations such JDBC programs releases connection back to pool.
Every web and application server vendor are having their own copy of connection pool
implementation classes. Such all class implement from javax.sql.DataSource interface. java.sql is a
JDBC Core API and javax.sql is an JDBC extension API. This interface is having getConnection()
method that returns Connection object. Web & App server vendors must implement their class from
this interface, implements connection pool implementation on their own, but provides
getConnection() method to get Connection object.
• Apache Software Foundation (ASF) - org.apache.commons.dbcp.BasicDataSource class
• Spring - org.springframework.jdbc.datasource.DriverManagerDataSource,
DelegatingDataSource
Applying connection pooling in the above application:
To know how to configure connection pool in tomcat, we need to start tomcat web server first, open
browser and type http://localhost:8081/
Select Tomcat Documentation
Select JDBC DataSource topic no 9
open tomcat\conf\server.xml
<Context path="/second_form_params" docBase="second_form_params"
unpackWars="true">
<Resource name="jdbc/OP" auth="Container" type="javax.sql.DataSource"
maxActive="10" maxIdle="2" maxWait="10000" username="am36" password="am36"
driverClassName="oracle.jdbc.driver.OracleDriver" url="jdbc:oracle:thin:@localhost:1521:XE"/>
</Context>
</Host>
</Engine>
</Service>
</Server>
open web.xml file of our application
<resource-ref>
<res-ref-name>jdbc/OP</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
open NewEmpServlet.java
import javax.naming.*;
import javax.sql.*;
// Connection con;
// Statement stmt;
// PreparedStatement pstmt;
// ResultSet rs;
DataSource ds;
public void init(ServletConfig sc) throws ServletException {
try {
/*
*/
Context ctxt=new InitialContext();
logger.debug("ctxt created");
ds=(DataSource)ctxt.lookup("java:comp/env/jdbc/OP");
logger.debug("ds obtained ");
}
}
public void service(req,resp)...{
try {
Connection con=ds.getConnection();
Statement stmt=con.createStatement();
PreparedStatement pstmt=con.prepareStatement("INSERT INTO employee VALUES
(?,?,?,?,?,?,?,?)");
ResultSet rs=
}
}
public void destroy() {
System.out.println("NewEmpServlet destroy() method is called");
/*
try{
}catch(Exception e) {}
*/
}
}
Servlets API
Servlet is a Java program that runs on Java Web Server running on server system, accepts request
(HTTP) from the client HTML form, process it on server (validating data, DB operations,
caching/client state persistence) and then responds back to client's browser.
Before Servlets, a web server (a program written in any language bounds server socket to one port
number, waits for the client requests infinitely, creates one socket on server for client, assigns to
one thread and runs) have only HTTP engine (I/O program that reads the client requested file using
inputstream, using outputstream it writes byte-byte or line-line or buffer-buffer onto client system)
When such a HTML documents are downloaded onto client system, filled and resubmitted to web
server again, a program must run on server system to read form data, perform some CRUD
operations and then to respond back to client every language provides classes to run on server. Such
a server side running java class is called as Servlet. In other languages ASP, PHP-PERL, ColdFusion,
Ruby on Rails, Grails for Groovy, CGI for C++ and PHP, XSQL etc
These server side program extends the capabilities of a web server from processing static resources
to dynamic resources.
To run such a servlet one more process runs in web server called Servlet Container. JSP container to
convert JSP to servlet. Again JSP converted servlets are run by servlet container.
To develop servlets developer must implement a class from javax.servlet.Servlet interface.
public interface Servlet {
// lifecycle methods
public void init(ServletConfig sc) throws ServletException ;
public void service(ServletRequest req, ServletResponse resp) throws ServletException, IOException;
public void destroy();
// miscellaneous methods
public String getServletInfo();
public ServletConfig getServletConfig();
}
Developer must implement all the abstract methods. If not developer can extend from 2 Servlet
interface adapter classes
i) GenericServlet
ii) HttpServlet
In GenericServlet except service() all the methods are implemented hence service() method
remained as abstract. Sub class must implement service() method.
Why developer must derive from Servlet interface directly or indirectly and must provide / override
these methods?
Because servlet container is responsible for servlet class lifecycle such as instantiating, asking servlet
to initialize, requesting servlet to process client request and deinitialize class instance variables
before destroying servlet object.
Through servlet interface container can force developer to implement these methods or ensure to
have the same methods.
class GenericServlet
GenericServlet class extended from Object implemented from Servlet, ServletConfig, Serializable
interfaces. Implemented all the methods of Servlet (5), ServletConfig (3) interfaces except service()
method because of that reason GS is also declared as abstract. Why service() is left as abstract
because GS super class must force at-least developer to implement service() method in every
servlet.
The methods of ServletConfig are:
String getInitParameter(String paramName);
Enumeration getInitParameterNames();
ServletContext getServletContext();
String getServletName();
In addition to all the above 8 methods, GenericServlet class is having one additional method called
public void log(String msg) {
getServletContext().log(getServletName()+" : "+msg);
}
one more method is getServletName()
When log() method is used it will write the text into \tomcat\logs\localhost.2014-03-18.log
Servlets are meant to process HTML form requests on server system. But if client wants to make
multiple HTML form requests to get the response back and again if form want to be submitted for
request processing (multiple conversations with web server) then we need to extends servlets from
HttpServlet instead of GenericSevlet.
Most of the real time web applications are all HttpServlet subclasses because client usually submits
username and password to server for login validation. LoginServlet verifies username and password
on server DB, if login successful the servlet sends user mailbox back to browser. From the browser
client makes another request to open the selected mail. Followed by mail content want to be
deleted or resend to another email account. User is making multiple requests to server, as long as
client is doing conversations, server must remember client's user credentials and past conversation
state on the server system.
This process is called as client state persistence.
In order to maintain client state persistence web server/container must manage client's session
management also.
Container in order to manage session, during client's first visit web container generates one 32 char
length unique id (also called as sessionid/rmi UID), during first response the container sends that ID
to browser via "Set-Cookie:jsessionid=32charlen". Browser will remember that id as cookie, from the
second conversation onwards browser resends all the cookies back to server. In those Cookies if
sessionid exist web container will recognize the client passes the same HttpSession object again and
again back into servlet. Servlet will append old conversation state to new conversation state using
setAttribute(name,value), getAttribute(name), removeAttribute(name) and getAttributeNames()
methods. If no jsessionid is found container creates one new HttpSession object, in that it will store
• String sessionid
• boolean isNew
• long creationTime
• long lastAccessedTime
• int maxInactiveInterval
• and one empty hashtable object.
Issuing id during first visit and recognizing client request with that id from second conversation
onwards on server system is called as session management.
Storing and retrieving client conversation state from HttpSession object is called as client state
persistence.
Servlet container can create such a HttpSession object only to the requests coming to HttpServlet.
The reason behind extending Servlet class from HttpServlet is to obtain session management and
client state persistence.
The another reason of extending from HttpServlet is only HTTP protocol 1.1 onwards, cookies
concept introduced with which we can exchange server information to client and vice-versa such as
jsessionid, Locale (displaying web page user interested language), themes etc.
HttpServlet is protocol HTTP protocol dependent whereas GenericServlet is protocol independent.
Third Java Web Application
Developing application on session management and client state persistence using Ecipse IDE:
Create a table in the database:
CREATE TABLE reg1 (regid number primary key,
fname varchar2(30),
lname varchar2(30),
email varchar2(30),
pass varchar2(30),
mobile varchar2(30),
address varchar2(30));
Following are the steps to create a new web application and configure tomcat in Eclipse:
Open Eclipse (any version)
Create a New DynamicWebProject
File-> New-> DynamicWebProject
Project Name: sessionman_3
Click on New Runtime
Choose Apache Tomcat v7.0-> click on Next->
Name: Apache Tomcat v6.0
Tomcat installation directory: D:\ apache-tomcat-7.0.91
JRE: jdk1.8.0_131
Click on Finish
Dynamic Web Module: 3.0
Click on Next
Click on Next
Select Generate web.xml deployment descriptor
Click on Finish
The directory structure looks as below:
sessionman_3
Java Resources
src
Libraries
Apache Tomcat v7.0
EAR Libraries
JRE System Libraries
Web App Libraries
JavaScript Resources
build
WebContent
META-INF
WEB-INF
web.xml
Create a new HTML
Right click on the Project-> New-> HTML
Name: 1.html
<HTML>
<BODY>
<PRE style="border: solid red 5px;text-align:center;text-shadow: lime; ">
<FORM method="post" action="./mfrs">
FName : <input type="text" name="fname">
LName : <input type="text" name="lname">
<input type="hidden" name="formno" value="1">
<input type="submit" name="submit" value="Next">
</FORM>
</PRE>
</BODY>
</HTML>
<!--
<TABLE>
<TR>
<TH>FName</TH>
<TD><input type="text" name="fname"></TD>
</TR>
<TR>
<TH>LName</TH>
<TD><input type="text" name="lname"></TD>
</TR>
<TR>
<TH><input type="hidden" name="fornmno" value="1"></TH>
<TD><input type="submit" name="submit" value="Next"></TD>
</TR>
</TABLE>
-->
Create a New servlet
Right click on the Project-> New-> Servlet
Class name: MFRS
Superclass: javax.servlet.http.HttpServlet
Click on Next
Name: MFRS
URL mappings: /mfrs
Click on Next
Select doPost() method checkbox
and click on Finish
// MFRS Servlet before non-idempotency prevention
// MFRS.java
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class MFRS extends HttpServlet {
public void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
int formno=Integer.parseInt(request.getParameter("formno"));
HttpSession hs=request.getSession();
if(formno == 1) {
// client state persistence
hs.setAttribute("fname", request.getParameter("fname").trim());
hs.setAttribute("lname", request.getParameter("lname").trim());
// second form generation
out.println("<PRE>");
out.println("<FORM method='post' action='./mfrs'>");
out.println("Email <INPUT type='text' name='email'>");
out.println("Pass <INPUT type='password' name='pass'>");
out.println("<INPUT type='hidden' name='formno' value='2'>");
out.println("<INPUT type='submit' name='submit' value='Next'>");
out.println("</FORM>");
out.println("</PRE>");
out.flush();
} else if(formno == 2) {
// client state persistence
hs.setAttribute("email", request.getParameter("email").trim());
hs.setAttribute("pass", request.getParameter("pass").trim());
// third form generation
out.println("<PRE>");
out.println("<FORM method='post' action='./mfrs'>");
out.println("Mobile <INPUT type='text' name='mobile'>");
out.println("Address<textarea name='address'></textarea>");
out.println("<INPUT type='hidden' name='formno' value='3'>");
out.println("<INPUT type='submit' name='submit' value='Finish'>");
out.println("</FORM>");
out.println("</PRE>");
out.flush();
} else {
String fname=hs.getAttribute("fname").toString();
String lname=hs.getAttribute("lname").toString();
String email=hs.getAttribute("email").toString();
String pass=hs.getAttribute("pass").toString();
String mobile=request.getParameter("mobile").trim();
String address=request.getParameter("address").trim();
int regid=0;
try {
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
Connection con=DriverManager.getConnection
("jdbc:odbc:oracledsn","active","activenet");
Statement stmt=con.createStatement();
PreparedStatement pstmt=con.prepareStatement("INSERT INTO
reg1 VALUES (?,?,?,?,?,?,?)");
ResultSet rs=stmt.executeQuery("SELECT max(regid) FROM reg1");
if(rs.next()) {
regid=rs.getInt(1);
}
regid++;
pstmt.setInt(1, regid);
pstmt.setString(2, fname);
pstmt.setString(3, lname);
pstmt.setString(4, email);
pstmt.setString(5, pass);
pstmt.setString(6, mobile);
pstmt.setString(7, address);
pstmt.executeUpdate();
out.println(" Record inserted, regid is "+regid);
}
catch(Exception e) {
e.printStackTrace();
}// catch()
}// else
}// service()
}// class
Deploying web application
Right click on the project-> Run As-> Run on Server, click Next, and click Finish
Accesing the home page of the application:
Open browser and type http://localhost:8081/ sessionman_3/1.html
Fill the 1.html file and click on Next button, you will get 2nd form, fill 2nd form and click on Next, you
will get 3rd form, fill-in 3rd form and click on Finish button, the form will be stored by MFRS into DB
that shows how session management and client state persistence is taking place between client
and server.
The proble lies in the above application is after submitting 3rd
form we will get registration
confirmation page saying your regid is 1, press F5 again the form resubmits to servlet and the
same record inserts once again with new regid.
The MFRS after non-idempotency prevention
// MFRS.java
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class MFRS extends HttpServlet {
public void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
int formno=Integer.parseInt(request.getParameter("formno"));
HttpSession hs=request.getSession();
if(formno == 1) {
// client state persistence
hs.setAttribute("fname", request.getParameter("fname").trim());
hs.setAttribute("lname", request.getParameter("lname").trim());
// second form generation
out.println("<PRE>");
out.println("<FORM method='post' action='./mfrs'>");
out.println("Email <INPUT type='text' name='email'>");
out.println("Pass <INPUT type='password' name='pass'>");
out.println("<INPUT type='hidden' name='formno' value='2'>");
out.println("<INPUT type='submit' name='submit' value='Next'>");
out.println("</FORM>");
out.println("</PRE>");
out.flush();
} else if(formno == 2) {
// client state persistence
hs.setAttribute("email", request.getParameter("email").trim());
hs.setAttribute("pass", request.getParameter("pass").trim());
// third form generation
out.println("<PRE>");
out.println("<FORM method='post' action='./mfrs'>");
out.println("Mobile <INPUT type='text' name='mobile'>");
out.println("Address<textarea name='address'></textarea>");
out.println("<INPUT type='hidden' name='formno' value='3'>");
out.println("<INPUT type='submit' name='submit' value='Finish'>");
out.println("</FORM>");
out.println("</PRE>");
out.flush();
// store one token in session object like a movie ticket
hs.setAttribute("token", new Integer(1));
} else {
if(hs.getAttribute("token")!=null) {
String fname=hs.getAttribute("fname").toString();
String lname=hs.getAttribute("lname").toString();
String email=hs.getAttribute("email").toString();
String pass=hs.getAttribute("pass").toString();
String mobile=request.getParameter("mobile").trim();
String address=request.getParameter("address").trim();
int regid=0;
try {
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
Connection con=DriverManager.getConnection
("jdbc:odbc:oracledsn","active","activenet");
Statement stmt=con.createStatement();
PreparedStatement pstmt=con.prepareStatement("INSERT
INTO reg1 VALUES (?,?,?,?,?,?,?)");
ResultSet rs=stmt.executeQuery("SELECT max(regid) FROM
reg1");
if(rs.next()) {
regid=rs.getInt(1);
}
regid++;
pstmt.setInt(1, regid);
pstmt.setString(2, fname);
pstmt.setString(3, lname);
pstmt.setString(4, email);
pstmt.setString(5, pass);
pstmt.setString(6, mobile);
pstmt.setString(7, address);
pstmt.executeUpdate();
// tear-off token once first time the form is submitted
hs.removeAttribute("token");
out.println(" Record inserted, regid is "+regid);
}
catch(Exception e) {
e.printStackTrace();
}// catch()
}// if()
else {
/* control comes to else block, if token is not present in session
object, that means form is resubmitted again. It is a duplicate form
submission. Display error */
out.println("<font color='red'>Your trying to submit a duplicate form
request");
}
}// else
}// service()
}// class
Alternative ways of session management with the help of Cookies and URL Rewriting:
In Java web applications servlet container manages session management, client state persistence is
managed by web developer using HttpSession object on server system.
Servlet container by default manages session management using Cookies. If Cookies are disabled on
client system, browser cannot receive Cookie:jsessionid=32charlen, browser cannot resend
jsessionid to server, if session id doesn't come in http requests servlet container will treat all such
clients as new client, new httpSession object is created and passed into servlet.
The consequence in the above application is during third form submission the servlet is passed with
a new session object but not the session object that already contains the two previous form data
from such a session object we cannot retrieve old data the registration process cannot be
succeeded.
To alternatively manage session management developer must send jsessionid with id in every
response to browser as a "hidden field" or through "url rewriting", then in the subsequent request
web container will verify jsessionid first in the http request header, if not it will verify url or hidden
field, if id is found then the same initial HttpSession is repeatedly passed into Servlet service()
method.
hidden field
out.println("<input type='hidden' name='jsessionid' value='"+hs.getId()+"'>");
URL rewriting
out.println("<FORM method='post' action='./mfrs; jsessionid="+hs.getId()+"'>" );
MFRS Example after session management with Cookie & URL rewriting
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class MFRS extends HttpServlet {
public void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
int formno=Integer.parseInt(request.getParameter("formno"));
HttpSession hs=request.getSession();
System.out.println(hs.getId());
if(formno == 1) {
// client state persistence
hs.setAttribute("fname", request.getParameter("fname").trim());
hs.setAttribute("lname", request.getParameter("lname").trim());
// second form generation
out.println("<PRE>");
out.println("<FORM method='post'
action='./mfrs;jsessionid="+hs.getId()+"'>");
out.println("<input type='hidden' name='jsessionid'
value='"+hs.getId()+"'>");
out.println("Email <INPUT type='text' name='email'>");
out.println("Pass <INPUT type='password' name='pass'>");
out.println("<INPUT type='hidden' name='formno' value='2'>");
out.println("<INPUT type='submit' name='submit' value='Next'>");
out.println("</FORM>");
out.println("</PRE>");
out.flush();
} else if(formno == 2) {
// client state persistence
hs.setAttribute("email", request.getParameter("email").trim());
hs.setAttribute("pass", request.getParameter("pass").trim());
// third form generation
out.println("<PRE>");
out.println("<FORM method='post'
action='./mfrs;jsessionid="+hs.getId()+"'>");
out.println("<INPUT type='hidden' name='formno' value='3'>");
out.println("Mobile <INPUT type='text' name='mobile'>");
out.println("Address<textarea name='address'></textarea>");
out.println("<input type='hidden' name='jsessionid'
value='"+hs.getId()+"'>");
out.println("<INPUT type='submit' name='submit' value='Finish'>");
out.println("</FORM>");
out.println("</PRE>");
out.flush();
hs.setAttribute("token", new Integer(1));
} else {
if(hs.getAttribute("token")!=null) {
String fname=hs.getAttribute("fname").toString();
String lname=hs.getAttribute("lname").toString();
String email=hs.getAttribute("email").toString();
String pass=hs.getAttribute("pass").toString();
String mobile=request.getParameter("mobile").trim();
String address=request.getParameter("address").trim();
int regid=0;
try {
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
Connection con=DriverManager.getConnection
("jdbc:odbc:oracledsn","active","activenet");
Statement stmt=con.createStatement();
PreparedStatement pstmt=con.prepareStatement("INSERT
INTO reg1 VALUES (?,?,?,?,?,?,?)");
ResultSet rs=stmt.executeQuery("SELECT max(regid) FROM
reg1");
if(rs.next()) {
regid=rs.getInt(1);
}
regid++;
pstmt.setInt(1, regid);
pstmt.setString(2, fname);
pstmt.setString(3, lname);
pstmt.setString(4, email);
pstmt.setString(5, pass);
pstmt.setString(6, mobile);
pstmt.setString(7, address);
pstmt.executeUpdate();
hs.removeAttribute("token");
out.println(" Record inserted, regid is "+regid);
}
catch(Exception e) {
e.printStackTrace();
}// catch()
}// if()
else {
out.println("<font color='red'>Your trying to submit a duplicate form
request");
}
}// else
}// service()
}// class
GET and POST difference
• GET can carry only 255 characters of form data. Post can send unlimited form data.
• In GET form data is appended at the end of URL using ? separator, hence it appears in the
location bar of the browser, for client it seems unsecure. In POST the form data is encoded
and sent through HTTP request body. It wont appear on the browser, it seems secure.
• New form data is posted using POST method. Already existing data on server will be
retrieved using GET method.
• GET method is processed faster that POST because server reads GET content from HTTP
request header, whereas POST data is read from Http request body for that server consumes
some time.
Fourth Java Web Application
Client state persistence on client system using Cookies:
Cookies are client side entities to store server information such as sessionid, user interested
language (Locale), user interested theme etc.
Cookies are created and send from server to client.
To write Cookie from server, the HTTP request header contains statement like this:
Set-Cookie: request header is used.
Cookie contains name, value, Comment, Domain, Max-Age, Path, Secure, Version as its attributes.
Cookies are generally created only with name and value combination.
Cookies are not permanently stored on client's browser. They are having expire time. The exipre
time is set through Max-Age attribute. If value is positive integer specified in terms of seconds.
Cookie will remain for specified number of seconds. If Cookie Max-Age is specified as zero, then as
soon it comes to browser, cookie will be removed. If its Max-Age is specified as negative integer
value the cookie remains until the browser is closed.
javax.servlet package is having one class called Cookie.
RFC 1945 - HTTP / 1.0
RFC 2616 - HTTP / 1.1
RFC 2109 - State management HTTP 1.1 protocol using Cookies
Cookie class in javax.servlet.http package creates Cookie structure object on server system Using
resp.addCookie() method the cookie can be set to HTTP request header.
In HTTP response using Set-Cookie, the cookie will be set.
Cookie class constructor takes name and value as argument. It is having setter and getter methods
to store additional attributes (comment, domain, Max-Age, path, secure, version).
The limitation of Cookie is its size can be upto 4KB, from each server browser can accept 20 cookies,
altogether a browser can accommodate 300 cookies.
Open Eclipse and create a DynamicWebProject
Follow the previous procedure to create DynamicWebProject
Name: cookies_4
Create a HTML file
<!-- ShoppingCart.html -->
<HTML>
<BODY>
<PRE>
<FORM method="get" action="./shoppingCartServlet">
Prod Name <input type="text" name="prodName">
Qty <input type="text" name="qty">
<input type="submit" name="submit" value="Add cart">
<input type="submit" name="submit" value="Update cart">
<input type="submit" name="submit" value="Find cart">
<input type="submit" name="submit" value="Delete cart">
<input type="submit" name="submit" value="View All Items">
</FORM>
</PRE>
</BODY>
</HTML>
// ShoppingCartServlet.java
public class ShoppingCartServlet extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException,
IOException {
String submit=req.getParameter("submit");
if(submit.equals("Add cart")) {
Cookie ck=new Cookie(req.getParameter("prodName").trim(),
req.getParameter("qty").trim());
resp.addCookie(ck);
resp.getWriter().println("Item added to cart");
} else
if(submit.equals("Update cart")) {
Cookie ck=new Cookie(req.getParameter("prodName").trim(),
req.getParameter("qty").trim());
resp.addCookie(ck);
resp.getWriter().println("cart updated");
} else
if(submit.equals("Find cart")) {
Cookie ck[]=req.getCookies();
String prodName=req.getParameter("prodName").trim();
for(int i=0; i<ck.length; i++) {
if(ck[i].getName().equals(prodName)) {
resp.getWriter().println(prodName+" named product requested for
"+ck[i].getValue()+" number of quantities");
}
}
} else
if(submit.equals("Delete cart")) {
Cookie ck=new Cookie(req.getParameter("prodName").trim(), null);
ck.setMaxAge(0);
resp.addCookie(ck);
resp.getWriter().println("Item deleted from cart");
} else {
Cookie ck[]=req.getCookies();
for(int i=0; i<ck.length; i++) {
resp.getWriter().println(ck[i].getName()+" : "+ck[i].getValue()+"<br>");
}// for()
}// else
}// doGet()
}// class
start tomcat
deploy web application
http://localhost:8081/ cookies_4/ShoppingCart.html
Fifth Java Web Application
Servlet-Servlet communication/Inter-servlet communication with the web application, across web
application using RequestDispatcher class forward() and include() methods, across web servers
using Socket programming and other one is using response.sendRedirect():
Communication between
• Servlet-> HTML,
• Servlet-> JSP,
• Servlet-> Servlet within the web application,
• across web applications in the same web server
• and across web servers.
• using response.sendRedirect() and RequestDispatcher.forward() & include()
Communication between Servlet-> HTML:
Usually client submits HTML form data to server, in response to form submission servlet will send
another HTML file to client's browser. But in the last applications we generated HTML form from
servlet to client using out.println() statements. Generating HTML form content in out.println()
statements is complex and error prone also. Hence we can write response HTML as a separate .html
extension files such files can be redirected from servlet to client's browser using
response.sendRedirect(String urlOfTheFile).
+ open Eclipse
+ Create a DynamicWebProject
Name: redirect_5
+ Create a HTML
Name: Login.html
<PRE>
<FORM method="POST" action="./loginServlet">
User <input type="text" name="user">
Pass <input type="password" name="pass">
<input type="submit" name="submit" value="Login">
</FORM>
</PRE>
+ Create a servlet
Name: LoginServlet
servlet-name: loginServlet
url-pattern: /loginServlet
public class LoginServlet extends HttpServlet {
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String user=request.getParameter("user").trim();
String pass=request.getParameter("pass").trim();
if(user.equals("abc") && pass.equals("xyz")) {
response.sendRedirect("./LoginSuccess.html");
} else {
response.setStatus(307);
response.addHeader("Location",
"http://localhost:8081/fifth_redirect/LoginFailed.html");
// dispatch HTTP response to client
response.flushBuffer(); // PrintWriter out=response.getWriter(); // out.flush();
}
}
}
+ Create a HTML
Name: LoginSuccess.html
Login Success
Name: LoginFailed.html
Login Failed
Place this URL on browser:
http://localhost:8081/redirect_5/Login.html
Servlet-> JSP communication using RequestDispatcher.forward() and include()
ServletContext:
ServletContainer creates one ServletContext object per web application. ServletContext contains
web DD file data (web.xml) which includes url-pattern mapped to servlet-name, servlet-name
mapped to servlet-class, context parameters, servlet context attributes, objects of singleton servlets.
In Servlets old API from Servlets 1.0 - 2.0 ServletContext object contains 3 methods called
• Servlet getServlet(String servletName)
• Enumeration getServletNames()
• Enumeration getServlets()
If one servlet1 requests sctxt.getServlet("s2"), the context will return s2 object. With the s2 object
we can access s2 completely means we can access its class instance variables, its instance methods,
its lifecycle methods including init(), service() and destroy(). But ServletContext object is giving
privilage to Servlet1 only to communicate with Servlet2 service() method to share their business
logic execution but not to communicate with other methods of Servlet2 which will be treated as
misusing servlet privilage. Due to security concern these 3 methods are deprecated in Servlets 2.1.
Until Servlet 2.3 no alternative API is given to communicate between servlets. In Servlets 2.3
RequestDispatcher interface is introduced as an alternative.
To create RequestDispatcher object two methods given in ServletContext called:
• RequestDispatcher getRequestDispatcher(String urlPattern)
• RequestDispatcher getNamedDispatcher(String servletName)
To communicate with other servlets we can use any one of the method because every servlet is
having both servlet-name and url-pattern configured in web.xml but if servlet wants to communicate
with JSP because JSPs are not configured in web.xml file we must use only getRequestDispatcher()
method but not getNamedDispatcher().
**********************************************************************************
Suppose if we are having Login.jsp that can be configured in web.xml file as follows:
<servlet>
<servlet-name>login</servlet-name>
<jsp-file>Login.jsp</jsp-file>
</servlet>
If JSP is configured in web.xml file then we can obtain its RequestDispatcher object using
getNamedDispatcher() also.
**********************************************************************************
What is RequestDispatcher?
RequestDispatcher is an interface, its implementation is provided by web server vendor. During
sctxt.getRequestDispatcher()/getNamedDispatcher() the context object obtains servlet object,
passes into RequestDispatcher object and that object reference is returned to client/servlet1.
When client communicates with the methods of RequestDispatcher, RD communicates with the
service() method of other servlet.
RequestDispatcher contains two methods called forward()) and include(). The difference is in case if
servlets are communicated using include () then all the servlet out.println() statements are included
in HTTP response body. If any servlet communicates with other servlet using forward(), then the
preceding servlet output written into HTTP response body will be cleared and the next servlet
out.println() statement output will be included in resp body. As soon as second servlet service()
method execution is completed control will come to forward() method of RD, that will flush() the
response, the resultant is HTTP response is flushed/committed to client.
Sixth Java Web Application
Example on RequestDispatcher
+ open Eclipse
+ Create a DynamicWebProject
Name: disp_6
+ Create 3 Servlet Named Servlet1, Servlet2, Servlet3, their names and url-patterns are s1, s2, s3,
/s1, /s2, /s3
http://localhost:8081/ disp_6/s1
Place s1,s2,s3 using disp.forward() / include()
Seventh Java Web Application
The following example covers how to implement MVC architecture in which communication exist
between servlet using RequestDispatcher.forward()/include() methods:
ShoppingCart application using RequestDispatcher.forward() and include() methods:
Create tables in database
create table users (username varchar2(20) primary key,
password varchar2(20));
create table categories (cid number primary key,
cname varchar2(30));
create table products (pid number primary key,
pname varchar2(30),
price number,
pdescr varchar2(50),
cid number references categories(cid));
insert into users values ('abc', 'xyz');
insert into users values ('xyz', 'abc');
insert into users values ('lmn', 'pqr');
insert into users values ('pqr', 'lmn');
insert into categories values (1, 'Books');
insert into categories values (2, 'Toys');
insert into categories values (3, 'Sports ware');
insert into categories values (4, 'Foodie');
insert into products values (1, 'Saga of Melusha', 500.00, 'Amish Tripati', 1);
insert into products values (2, 'Two States', 450.00, 'Chetan Bhagat', 1);
insert into products values (3, 'The promise', 450.00, 'Nikita Singh', 1);
insert into products values (4, 'Barbie Doll', 1050.00, 'Barbie', 2);
insert into products values (5, 'Hot wheels', 150.00, 'Hot wheels', 2);
insert into products values (6, 'Logo Bricks', 550.00, 'Logo Bricks', 2);
insert into products values (7, 'Nike Shoes', 2500.00, 'Nike', 3);
insert into products values (8, 'MRF Cricket Bat', 1500.00, 'Bat', 3);
insert into products values (9, 'Nike Tennis Rocket', 2550.00, 'Rocket', 3);
insert into products values (10, 'Schezwan Noodles', 120.00, 'Schezwan', 4);
insert into products values (11, 'Rasagulla', 350.00, 'Resagulla', 4);
insert into products values (12, 'Hyderabad Biryani', 250.00, 'Biryani', 4);
commit;
Create a DynamicWeb Project
Name: cart_7
src
controller
LoginController
CategoryController
ProductController
CartController
model
LoginModel
CategoryModel
ProductModel
view
CategoriesView
ProductsView
CartView
beans
Category
Product
WebRoot
WEB-INF
web.xml
Login.html
LoginFailed.html
Login.html
<PRE>
<FORM method="post" action="./lc">
User <input type="text" name="user">
Pass <input type="password" name="pass">
<input type="submit" name="submit" value="Login">
</FORM>
</PRE>
Create a Servlet
Package: controller
Name: LoginController
lc, /lc
Press CTRL+SHIFT+O to automatically import packages
public class LoginController extends HttpServlet {
public void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String user=request.getParameter("user").trim();
String pass=request.getParameter("pass").trim();
if(user.isEmpty() && pass.isEmpty()) {
response.sendRedirect("./LoginFailed.html");
} else {
getServletContext().getNamedDispatcher("lm").include(request,response);
String loginStatus=request.getAttribute("loginStatus").toString();
if(loginStatus.equalsIgnoreCase("Success")) {
getServletContext().getRequestDispatcher("/cc").forward(request,response);
} else {
response.sendRedirect("./LoginFailed.html");
} // else
}// else
}// service()
}// class
Create a Servlet
Package: model
Name: LoginModel
lm, /lm
Press CTRL+SHIFT+O to automatically import packages
public class LoginModel extends HttpServlet {
public void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String user=request.getParameter("user").trim();
String pass=request.getParameter("pass").trim();
try {
Connection con=factory.DBConn.getConn();
Statement stmt=con.createStatement();
ResultSet rs=stmt.executeQuery("SELECT * FROM users WHERE
username='"+user+"' AND password='"+pass+"' " );
if(rs.next()) {
// username is stored in session scope
request.getSession().setAttribute("user", user);
// user loginstatus in request scope
request.setAttribute("loginStatus", "Success");
} else {
request.setAttribute("loginStatus", "Failed");
}
}
catch(Exception e) {}
}
}
Create a Class
Package: beans
Name: Category
Press CTRL+SHIFT+O to automatically import packages
public class Category {
private int cid;
private String cname;
List productList;
}
Create a Class
Package: beans
Name: Product
Press CTRL+SHIFT+O to automatically import packages
public class Product {
private int pid;
private String pname;
private double price;
private String pdescr;
private Category category;
}
Create a Servlet
Package: controller
Name: CategoryController
cc, /cc
Press CTRL+SHIFT+O to automatically import packages
public class CategoryController extends HttpServlet {
public void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
/*
verify categoriesList exist in the sctxt or not; if not request CategoryModel; if
exist forward CategoriesView to client
*/
ServletContext sctxt=getServletContext();
if(sctxt.getAttribute("categoriesList")==null) {
sctxt.getRequestDispatcher("/cm").include(request, response);
sctxt.getRequestDispatcher("/cv").forward(request, response);
} else {
sctxt.getRequestDispatcher("/cv").forward(request, response);
}
}
}
Create a Servlet
Package: model
Name: CategoryModel
cm, /cm
Press CTRL+SHIFT+O to automatically import packages
public class CategoryModel extends HttpServlet {
public void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
/*
retrieve categories, populate each record into one Category bean, store all
the bean objects into categoriesList and then store the list into sctxt
*/
ServletContext sctxt=getServletContext();
try {
List<Category> list=new ArrayList();
Connection con=factory.DBConn.getConn();
Statement stmt=con.createStatement();
ResultSet rs=stmt.executeQuery("SELECT * FROM categories");
while(rs.next()) {
Category c=new Category(rs.getInt(1), rs.getString(2), null);
list.add(c);
}// while
sctxt.setAttribute("categoriesList", list);
}// try
catch(Exception e) {
e.printStackTrace();
}// catch
}
}
Create a Servlet
Package: view
Name: CategoriesView
cv, /cv
Press CTRL+SHIFT+O to automatically import packages
public class CategoriesView extends HttpServlet {
public void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
ServletContext sctxt=getServletContext();
Object o=sctxt.getAttribute("categoriesList");
List<Category> list=(List)o;
PrintWriter out=response.getWriter();
out.println("<UL>");
for(Category c:list) {
out.println("<LI><A
href='./pc?catid="+c.getCid()+"'>"+c.getCname()+"</A></LI>");
}
out.println("</UL>");
}
}
http://localhost:8081/cart_6/Login.html
Create a Servlet
Package: controller
Name: ProductController
pc, /pc
Press CTRL+SHIFT+O to automatically import packages
public class ProductController extends HttpServlet {
public void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
/*
retrieve catid from req
verify with the catid attribute exist in sctxt or not
if exist forward ProductsView to client
if not request ProductModel using disp.incude() and then forward
ProductsView to client
*/
ServletContext sctxt=getServletContext();
String catid=request.getParameter("catid");
if(sctxt.getAttribute(catid)==null) {
sctxt.getRequestDispatcher("/pm").include(request, response);
sctxt.getRequestDispatcher("/pv").forward(request, response);
} else {
sctxt.getRequestDispatcher("/pv").forward(request, response);
}
}
}
Create a Servlet
Package: model
Name: ProductModel
pm, /pm
Press CTRL+SHIFT+O to automatically import packages
public class ProductModel extends HttpServlet {
public void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
/*
retrieve catid from req
with catid retrieve products from product table, store records into Product
object, store all such objects into List, store List into sctxt object with catid
*/
ServletContext sctxt=getServletContext();
String catid=request.getParameter("catid");
try {
Connection con=factory.DBConn.getConn();
Statement stmt=con.createStatement();
ResultSet rs=stmt.executeQuery("SELECT * FROM products WHERE
cid="+catid);
List<Product> list=new ArrayList<Product>();
while(rs.next()) {
Product p=new Product(rs.getInt(1), rs.getString(2), rs.getDouble(3),
rs.getString(4), null);
list.add(p);
}// while()
sctxt.setAttribute(catid, list);
}// try
catch(Exception e) {
e.printStackTrace();
}// catch()
}// service()
}// class
Create a Servlet
Package: view
Name: ProductsView
pv, /pv
Press CTRL+SHIFT+O to automatically import packages
public class ProductsView extends HttpServlet {
public void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
PrintWriter out=response.getWriter();
ServletContext sctxt=getServletContext();
String catid=request.getParameter("catid");
List<Product> list=(List)sctxt.getAttribute(catid);
out.println("<TABLE>");
out.println("<TR>");
out.println("<TH>PID</TH>");
out.println("<TH>PName</TH>");
out.println("<TH>Price</TH>");
out.println("<TH>Descr</TH>");
out.println("<TH>Qty</TH>");
out.println("</TR>");
for(Product p:list) {
out.println("<TR>");
out.println("<TD>"+p.getPid()+"</TD>");
out.println("<TD>"+p.getPname()+"</TD>");
out.println("<TD>"+p.getPrice()+"</TD>");
out.println("<TD>"+p.getPdescr()+"</TD>");
out.println("<TD><input type='text' name='"+p.getPid()+"'
value=''></TD>");
out.println("</TR>");
}
out.println("<TR>");
out.println("<TD colspan='2'>");
out.println("<input type='submit' name='submit' value='Add To Cart'>");
out.println("</TD>");
out.println("<TD colspan='2'>");
out.println("<A href='./cv'>View Categories</A>");
out.println("</TD>");
out.println("</TABLE>");
}
}
Create a Servlet
Package: model
Name: CartController
cartc, /cartc
Press CTRL+SHIFT+O to automatically import packages
public class CartController extends HttpServlet {
public void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
PrintWriter out=response.getWriter();
ServletContext sctxt=getServletContext();
HttpSession hs=request.getSession();
Map map;
if(hs.getAttribute("shoppingCartMap")==null) {
map=new HashMap();
hs.setAttribute("shoppingCartMap", map);
} else {
map=(Map)hs.getAttribute("shoppingCartMap");
}
Enumeration en=request.getParameterNames();
while(en.hasMoreElements()) {
String name=en.nextElement().toString();
if(name.equals("submit")) {
} else {
String qty=request.getParameter(name).trim();
// client state persistence; store pid and qty as key & value pairs
if(!qty.isEmpty()) {
// hs.setAttribute(name, qty);
map.put(name, qty);
}// if()
}// else
}// while()
sctxt.getRequestDispatcher("/cartView").forward(request, response);
}
}
Create a Servlet
Package: model
Name: CartView
cartv, /cartv
Press CTRL+SHIFT+O to automatically import packages
public class CartView extends HttpServlet {
public void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
PrintWriter out=response.getWriter();
ServletContext sctxt=getServletContext();
HttpSession hs=request.getSession();
Enumeration en=sctxt.getAttributeNames();
while(en.hasMoreElements()) {
String name=en.nextElement().toString();
String value=sctxt.getAttribute(name);
out.println(name+" "+value+"<br>");
}
Enumeration en=hs.getAttributeNames();
while(en.hasMoreElements()) {
String name=en.nextElement().toString();
String value=sctxt.getAttribute(name);
out.println(name+" "+value+"<br>");
}
}
}
Eight Java Web Application
Filters
Filters are "Chain of Reposibility" design pattern implemented classes.
Filters are also a web components as same as Servlets.
Servlets are written per HTML form basis. The logic written in servlet is to process HTML form data.
Whereas the logic written in Filter is not to process HTML form data instead the logic which is
common to execute in more than one servlet is written in filter.
The logic which is commonly required in more than one servlet are:
i) Logging
ii) Field Validations
iii) Authentication & Authorization
iv) File-upload processing
v) Image processing
vi) Encryption & Decryption of data
vii) Compression
viii) Detection harmful data submitted by hackers
ix) Page Decoration Filter
To implement Filter developer must implement one class that implements from javax.servlet.Filter
interface. Filter interface is having 3 methods called
public void init(FilterConfig fc)
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain fc)
public void destroy()
Filters are intended to execute both before and after servlet execution.
To execute Filter before servlet execution, servlet url-pattern must be applied to filter url-pattern.
To dispatch control from filter to next filter or servlet, in doFilter() method of Filter we need to call
fc.doFilter(req, resp)
Code which is written in Filter before fc.doFilter(req, resp) will execute before servlet execution (acts
like a pre-filter), code written after fc.doFilter(req, resp) will execute after servlet execution (acts like
post-filter).
Open Eclipse
Create a DynamicWeb Project
Name: filters_8
src
LoginServlet
RegServlet
filters
LoggingFilter
PageDecorationFilter
ValidationFilter
WebRoot
WEB-INF
web.xml
Login.html
Reg.html
<!-- Login.html -- >
<pre>
<form method="post" action="./ls">
User <input type="text" name="user">
Pass <input type="password" name="pass">
<input type="submit" name="submit" value="Login">
</form>
</pre>
<!-- Reg.html -->
<pre>
<form method="post" action="./rs">
SName <input type="text" name="sname">
Email <input type="text" name="email">
Mobile <input type="text" name="mobile">
Course <input type="text" name="course">
Address <input type="text" name="address">
<input type="submit" name="submit" value="Register">
</form>
</pre>
// LoginServlet.java
public class LoginServlet extends HttpServlet {
public void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException,
IOException {
resp.getWriter().println("Login Successful");
}
}
// RegServlet.java
public class RegServlet extends HttpServlet {
public void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException,
IOException {
resp.getWriter().println("Registration Successful");
}
}
// LoggingFilter.java
public class LoggingFilter implements Filter {
@Override
public void init(FilterConfig arg0) throws ServletException {
// TODO Auto-generated method stub
}
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain fc) throws
ServletException, IOException {
System.out.println("LoggingFilter executed before
"+((HttpServletRequest)req).getServletPath());
fc.doFilter(req, resp);
System.out.println("LoggingFilter executed after
"+((HttpServletRequest)req).getServletPath());
}
public void destroy() { }
}
// PageDecorationFilter.java
public class PageDecorationFilter implements Filter {
public void init(FilterConfig fc) throws ServletException { }
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain fc) throws
ServletException, IOException {
PrintWriter out=resp.getWriter();
out.println("<H1><CENTER>ActiveNET Inc IN, US, UK, UAE, Africa, Oceana</CENTER></H1>");
out.println("<CENTER>Home || Training || Development || Projects || Contact Us</CENTER>");
out.println("<UL><LI>Home</LI><LI>Training</LI><LI>Development</LI><LI>Projects</LI><LI>Contac
t Us</LI>");
fc.doFilter(req, resp);
out.println("New Batch Staring<br/>Openings on java<br/>Immediate Openings<br/>");
out.println("<H5><CENTER>Copyrights reserved to ActiveNET Inc 2014-3014</CENTER></H5>");
}
public void destroy() { }
}
// ValidationFilter.java
public class ValidationFilter implements Filter {
public void init(FilterConfig fc) throws ServletException { }
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain fc) throws
ServletException, IOException {
resp.setContentType("text/html");
PrintWriter out=resp.getWriter();
String err="";
Enumeration en=req.getParameterNames();
while(en.hasMoreElements()) {
String name=en.nextElement().toString();
String value=req.getParameter(name);
if(value.isEmpty()){
err=err+"<br/> "+name+" is empty<br>";
}// if()
}// while()
if(err.length()>0) {
out.println("<font color='red'>"+err+"</font>");
} else {
fc.doFilter(req, resp);
}
}
public void destroy() { }
}
web.xml
<web-app>
<filter>
<filter-name>lf</filter-name>
<filter-class>filters.LoggingFilter</filter-class>
</filter>
<filter>
<filter-name>pdf</filter-name>
<filter-class>filters.PageDecorationFilter</filter-class>
</filter>
<filter>
<filter-name>vf</filter-name>
<filter-class>filters.ValidationFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>lf</filter-name>
<url-pattern>/ls</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>lf</filter-name>
<url-pattern>/rs</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>pdf</filter-name>
<url-pattern>/ls</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>pdf</filter-name>
<url-pattern>/rs</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>vf</filter-name>
<url-pattern>/ls</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>vf</filter-name>
<url-pattern>/rs</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>ls</servlet-name>
<servlet-class>LoginServlet</servlet-class>
</servlet>
<servlet>
<servlet-name>rs</servlet-name>
<servlet-class>RegServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ls</servlet-name>
<url-pattern>/ls</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>rs</servlet-name>
<url-pattern>/rs</url-pattern>
</servlet-mapping>
</web-app>
http://localhost:8081/filters_8/Login.html
Ninth Java Web Application
Listeners:
Listeners are event handlers. Class which handles some logic during events is a
EventHandler/Listener. onClick, onChange, onSelect etc are UI events. But Listeners in servlets
handles server side events.
What are server side events?
ServletContainer creating & destroying ServletContext, Servlet, ServletRequest and HttpSession
objects are all events.
Have you received any event notification for the above said objects before?
If you say No! I says Yes, because when servlet container create and destroy servlet object it is
invoking init() and destroy() methods on servlet instance, we feel invoking init() and destroy()
methods is called as calling servlet lifecycle methods but they are servlet event listener methods.
But no events are listened yet on ServletRequest, HttpSession and ServletContext objects.
In javax.servlet package
i) public interface ServletContextListener {
public void contextInitialized(ServletContextEvent sce);
public void contextDestroyed(ServletContextEvent sce);
}
ii) public interface ServletRequestListener {
public void requestInitialized(ServletRequestEvent sre);
public void requestDestroyed(ServletRequestEvent sre);
}
In javax.servlet.http package
iii)public interface HttpSessionListener {
public void sessionCreated(HttpSessionEvent hse);
public void sessionDestroyed(HttpSessionEvent hse);
}
To receive these events developer must write a sub class of these interfaces, implement all the 6
methods and the class must be configured in web.xml file under
<listener>
<listener-class>listeners.MyListener</listener-class>
</listener>
The purpose of ServletContextListener, contextInitialized() method is if we want to initialize anything
at the time of web application deployment such as Connection object/DataSource object
creation,loading hibernate.cfg.xml file and and store SessionFactory object into ServletContext such
things will be performed in ServletContextListener.
Example on Listeners
----------------------------
+ Open Eclipse
+ Create a DynamicWebProject
Name: listeners_9
+ Create a Class
Package: listeners
Name: MyListener
super interfaces:ServletRequestListener,HttpSessionListener, ServletContextListener
public class MyListener implements ServletRequestListener, HttpSessionListener,
ServletContextListener {
public void requestInitialized(ServletRequestEvent sre) {
System.out.println("request initialized");
}
public void requestDestroyed(ServletRequestEvent sre) {
System.out.println("request destroyed");
}
public void sessionCreated(HttpSessionEvent hse) {
System.out.println("session created");
}
public void sessionDestroyed(HttpSessionEvent hse) {
System.out.println("session destroyed");
}
public void contextInitialized(ServletContextEvent sce) {
System.out.println("context initialized");
}
public void contextDestroyed(ServletContextEvent sce) {
System.out.println("context destroyed");
}
}
+ Create one servlet
Name: ListenerServlet
ls, /ls
public class ListenerServlet extends HttpServlet {
public void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException,
IOException {
HttpSession hs=req.getSession();
PrintWriter out=resp.getWriter();
out.println("msg from ListenerServlet");
}
}
web.xml
<web-app>
<listener>
<listener-class>listeners.MyListener</listener-class>
</listener>
<servlet>
<servlet-name>ls</servlet-name>
<servlet-class>ListenerServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ls</servlet-name>
<url-pattern>/ls</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>1</session-timeout>
</session-config>
</web-app>
http://localhost:8081/listeners_9/ls
JSP
(Java Server Pages)
also called as Template Engine Technology
9+9+4+3+(9-4)+4
LCP+io+se+de+sae+sv
By SuryanarayanaBy SuryanarayanaBy SuryanarayanaBy Suryanarayana
ActiveNET
� 9 Lifecycle phase
� 9 Implicit objects
� 4 Scripting Elements
� 3 Directive Elements
� 9 Standard Action Elements
� 4 Scope Variables
i. Compare Markup Language with Scripting Language
ii. Compare Client side scripting with Server side Scripting
iii. Compare JSP with Servlets
iv. How JSP transforms PIC (Page Implementation Class) / Servlet class
a. 9 transition phases
b. JSP PIC class hierarchy
c. JSP life cycle
d. 9 Implicit objects
e. 4 scope variables
v. 4 Scripting elements
vi. 3 Directive elements
vii. 9 Standard action elements
viii. Custom / User-defined tags. TIC (Tag Implementation Class/Tag Handler Class) and its
lifecycle
ix. Empty tag with attribute
x. Nested tag with attributes
Compare Markup with Scripting Languages
� We will write as document/page, it will run as component/class.
� JSP is a dynamic web document (It contains HTM tags, in between tags java code executes
on server that will retrieve some data from database and places in between HTML tags –
such a output is called as dynamic web document).
Markup languages starts with < (left angular bracket) tag name followed > (right angular bracket).
Whenever the markup language document is downloaded on to browser, browser is having HTML
rendering kit that renders HTML document as rich text document on browser.
Browser is a HTML rendering (reading+conversion) engine.
HTML is meant for developing web pages and rich formatting the text.
CSS is an add-on to HTML which improves the look and feel of the HTML output/styling the HTML
elements / tags.
JavaScript, VBScript and JScript are used to validate client data at front end on the browser. These
scripts are client side scripts.
Whereas JSP, ASP, PHP, CFM (ColdFusion Markup Language), XSQL (Oracle XML SQL), Groovy Grails,
Ruby Rails etc are all server side scripting languages. The intention of these server-side scripting
languages is to generate HTML code while executing java or some other programming languages.
While executing java code we can fetch data dynamically from database or file system, the output
can be embedded in HTML code and can be generated on to client system. So that HTML output
looks like a dynamic output.
That means to generate HTML documents dynamically we will use JSP or ASP or PHP. We can also
use JSP as an alternative to Servlets.
Because JSP is having following:
i) 4 scripting element
ii) 3 directive elements
iii) 9 standard action elements
iv) 9 implicit objects
v) 4 scope variables
vi) having an option to write user defined tags/elements
One of the scripting element is <% %> (Scriptlet), the code written in Scriptlet is placed in try block of
_jspService() method in JSP PIC (Page Implementation Class).
Code placed in <%= %> (Expression tag) is placed as it is in out.println() statement.
Code placed in <%! %> (Declaration) goes to class body.
With JSP we can generate both dynamic web documents and components.
Writing JSP as a Servlet is to achieve rapid web component development.
JSP is initially a web document, later it converts and runs as web component.
JSP is template document.
JSP tags are templates. JSP document is template document, JSP engine is template engine which
understands templates/tags and converts them into concern language code.
Compare Client side scripting with Server side Scripting
Scripting/Programming/Algorithm writing these are all more or less like same. Coming to compare
difference between Client Side Scripting Vs Server Side Scripting
� Server side scripting is used to create dynamic pages based of number of conditions when
the user browser makes a request to the server.
� Client side scripting is used when the user browser already has all the code and the page is
altered on the basis of the user input.
� Web Server executes server side scripting that produces the page to be sent the browser. It
performs some logic execution such as user field retrieval, the data validation, interaction
with the database inserting/updating/deleting/selecting to and from the database and
produces the resultant output to the browser.
� The browser executes the sent HTML, CSS, JavaScript on browser.
� Server side script executes server side script and sends output to browser, it doesn’t execute
client side scripts
� Browser executes script and data sent onto to browser.
� Server side script can access data from the file system / database on server side system.
� Client side script cannot access file system or database on client system also.
� Server side script cannot be blocked by the user.
� Client side script can be blocked by the user.
� Server side script is slower than client side script because server side script execution
depends on server speed, database speed, client-server network speed etc.
� Client side script doesn’t have all these limitations.
� Examples of server side scripting languages are JSP, ASP, PHP, Cold Fusion, Ruby, Python,
Groovy etc.
� Examples of client side scripting languages are JavaScript, VBScript, Jscript.
Compare JSP with Servlets
� Servlet is HTML in Java whereas JSP is java in HTML.
� Servlets runs faster than JSP.
� Coding in JSP is easier than Servlet. Servlet coding is easier than JSP.
o Tell me what do you say?
� From Java Web Developer perspective Servlet is easy because it is java class.
� From the web designer perspective embedding Java code in HTML with
minimum number of scripting tags is easy.
� Servlet already compile and runs on browser, at runtime it won’t check for the syntactical
and input errors. Input errors are handled with exception handler. Hence server side
programs are safe from that perspective.
� Whereas client side scripting interprets on client browser at runtime. Hence syntactical,
logic, input errors are all found at runtime while executing HTML document on browser.
How JSP transforms PIC (Page Implementation Class) / Servlet class
4 JSP Scripting Elements
� <!-- --> HTML comments are placed in out.println() during page translation.
� <%-- --%> Content written in JSP comment will be ignore during page translation.
� <%! %> declaration code goes to class body as it is. Variable declarations, jspInit(),
jspDestroy() methods, user defined methods, single and multi line comments.
� <%= %> expression tag content goes to out.println()
� <% %> Scriptlet tag content goes to try block of _jspService()
JSP engine is a template engine which converts JSP into PIC / Servlet.
How JSP transforms PIC (Page Implementation Class)/Servlet
Whenever the first request is made to JSP from the browser, the JSP container and Servlet container
will execute 9 transition phases on JSP:
JSP Container processes:
i) Verification Phase (well-formedness of JSP document is verified, tags are case sensitive, every
start tag must have end tag, tag attributes must be quoted, tags must be properly nested)
ii) Validation Phase (Tag syntaxes are verified that means tag attributes are correctly written or not)
- if fails translation errors are displayed on the browser
iii) Translation Phase (The JSP document is converted into a PIC/Servlet that extends from
org.apache.jasper.runtime.HttpJspBase class which is a adapter class to
javax.servlet.jsp.HttpJspPage, javax.servlet.jsp.JspPage and javax.servlet.Servlet interfaces. All the 8
methods are implemented in HttpJspBase class and _jspService() is overridden in our PIC. In
_jspService() method 9 implicit objects are declared:
a) HttpServletRequest request
b) HttpServletResponse response
c) ServletContext application
d) ServletConfig config
e) HttpSession session
f) Object page=this
g) JspWriter out
h) Throwable exception
i) PageContext pageContext - wrapper class that contains all 8 implicit objects
JSP PIC Class Hierarchy Diagram
iv) Compilation Phase (JSP container uses javac to compile java program)
- if java statement syntaxes are wrong compilation errors will be displayed on the browser
v) Configuration Phase (JSP container configures PIC in servlet container, for that Jasper will place
PIC .java & .class files in C:\Program Files\apache-tomcat-6.0.37-windows-x86\apache-tomcat-
6.0.37\work\Catalina\localhost\_\org\apache\jsp\am36 folder)
Servlet Container processes:
vi) Instantiation Phase (Catalina instantiates PIC using public no argument constructor) - Singleton-
multithread model
vii) Initialization Phase (Catalina will invoke init() method, the init() method is derived into PIC from
HttpJspBase class that init() method will invoke jsp lifecycle method jspInit())
viii) Execution Phase (Catalina invokes service() method on PIC again the HttpJspBase class
implemented service() method will invoke _jspService() method on PIC. Since PIC is also a servlet it
will run as singleton-multi thread model object)
Note:All the 8 phases will execute during first client request to JSP, once PIC is generated and
service() is executed from thereafter only _jspService() method executes for multiple client from
multiple threads. Once each client request processing is completed, the corresponding thread object
destroys but instance remains alive. Next to first client only Execution phase only executes.
ix) Destruction Phase (Will execute only if already deployed JSP is modified outside and redeployed
again. In this phase Catalina will invoke destroy() method on PIC, HttpJspBase class destroy() method
will invoke jspDestroy() method. In the jspDestroy() we will deinitialize JSP class instance variables.
This phase executes when JSP is deployed again and after this phase all the 8 phases are executed
again upto Execution phase).
Examples on JSP Scripting Elements
First example on JSP
Place Hello.jsp file in the following folder
C:\Program Files\apache-tomcat-6.0.37-windows-x86\apache-tomcat-6.0.37\webapps\ROOT\
am36\Hello.jsp
Hello.jsp
<%="Hello"%>
Open browser and type the following URL
http://localhost:65535/am36/Hello.jsp
Page implementation can be found in C:\Program Files\apache-tomcat-6.0.37-windows-x86\apache-
tomcat-6.0.37\work\Catalina\localhost\_\org\apache\jsp\am36\Hello_jsp.java
That looks like this
Second example on JSP
Another example on JSP Scripting elements:
create table course (cid number primary key, cname varchar2(30));
insert into course values (1, 'Core Java');
insert into course values (2, 'Adv Java');
insert into course values (3, 'Oracle');
insert into course values (4, 'Hibernate');
insert into course values (5, 'Spring');
commit;
create table reg (regid number primary key,
sname varchar2(30),
email varchar2(30),
mobile varchar2(30),
course varchar2(100),
address varchar2(150)
);
<%-- DBConn.jsp --%>
<%@ page import="java.sql.*"%>
<%!
// class instance variable declaration
Connection con;
Statement stmt;
ResultSet rs;
// overriding lifecycle method
public void jspInit() {
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
con=DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:XE", "active", "activenet");
stmt=con.createStatement();
}
catch(Exception e) {
e.printStackTrace();
}// catch()
}// jspInit()
%>
<%-- NewReg.jsp --%>
<%@ include file="DBConn.jsp"%> <%-- includes above file here --%>
<%
rs=stmt.executeQuery("SELECT cname FROM course");
session.setAttribute("token", new Integer(1));
%>
<PRE>
<FORM method="post" action="./NewRegProcessing.jsp">
SName <INPUT type="text" name="sname">
Email <INPUT type="text" name="email">
Mobile <INPUT type="text" name="mobile">
Course <SELECT name="course" size="5" MULTIPLE>
<%
while(rs.next()) {
String cname=rs.getString(1);
%>
<OPTION value='<%=cname%>'><%=cname%></OPTION>
<%
} // closing while loop
%>
</SELECT>
Address <TEXTAREA name="address"></TEXTAREA>
<INPUT type="submit" name="submit" value="Register">
</FORM>
</PRE>
/* out.println("<OPTION value=');
out.println(rs.getString(1));
out.println("'>");
out.println(rs.getString(1));
out.println("</OPTION>"); */
<%-- NewRegProcessing.jsp --%>
<%@ include file="DBConn.jsp"%>
<%
if(session.getAttribute("token")!=null) {
PreparedStatement pstmt=con.prepareStatement("INSERT INTO reg VALUES (?,?,?,?,?,?)");
String sname=request.getParameter("sname").trim();
String email=request.getParameter("email").trim();
String mobile=request.getParameter("mobile").trim();
String course[]=request.getParameterValues("course");
String courses="";
System.out.println(course.length);
int len=course.length;
for(int i=0;i<len;i++) {
courses+=course[i]+", ";
System.out.println(courses);
}
courses=courses.substring(0, courses.length()-2);
System.out.println(courses);
String address=request.getParameter("address").trim();
rs=stmt.executeQuery("SELECT max(regid) FROM reg");
int regid=0;
if(rs.next()) {
regid=rs.getInt(1);
}
regid++;
pstmt.setInt(1, regid);
pstmt.setString(2, sname);
pstmt.setString(3, email);
pstmt.setString(4, mobile);
pstmt.setString(5, courses);
pstmt.setString(6, address);
pstmt.executeUpdate();
session.removeAttribute("token");
%>
Regid is <%=regid%>
<%
} else {
%>
<FONT color='red'><I>Duplicate form submitted</I></FONT>
<%
}
%>
Request following RL on browser
http://localhost:65535/am36/NewReg.jsp
column sname format a20;
column email format a25;
column mobile format 9999999999;
column course format a20;
column address format a20;
select * from reg;
4 scripting elements:
<!-- --> HTML comment - out.println()
<%-- --%> JSP comment - ignored during page translation
<%! %> Declaration tag, class body
<%= %> Expression tag - out.println()
<% %> Scriptlet - to write java code in JSP PIC _jspService() try{ } block
3 directive elements:
<%@ include %> include directive
<%@ page %> page directive
<%@ taglib %> tag directive
9 standard action elements:
<jsp:include/> or <jsp:include></jsp:include>
<jsp:forward/> or <jsp:forward></jsp:forward>
<jsp:useBean>
<jsp:setProperty>
<jsp:getProperty>
</jsp:useBean>
<jsp:plugin>
<jsp:params>
<jsp:param>
<jsp:fallback>
</jsp:plugin>
Examples on Directive Elements
<%@ include %> and <jsp:include>:
These tags are used in JSP to compose other web pages into our web page. To implement composite
view we will use these includes.
Generally the web designers will generate and give us HTML pages with nice header, menu and body
which we want to repeatedly use in our web documents.
Hence generate header, menu, footer separately and include them in our document using <%@
include %> (include directive) and <jsp:include> tags.
The main difference is <%@ include %> tag included web pages are static includes, the <jsp:include>
tag included web pages are dynamically added to our JSP.
In case of <%@ include %> tag the included document source code will be included in our JSP at the
time of page translation into PIC, the class compile and runs.
Whereas in <jsp:include> the included document is included using RequestDispatcher.include so that
our JSP always communicates other web page every time @ runtime.
<%@ include %> execution is faster than <jsp:include>
But whenever the included page modifies our JSP PIC regenerates again. Transition phases executes
more in <%@ include %>.
With the help of <%@ include %> we can include other HTML and JSP documents in our JSP
document but cannot include Servlets.
Servlets also can be included in our JSP using <jsp:include>
Third example on JSP include directive element
This example covers both <%@include file=””%> aka include directive and <jsp:include page=””>
Header.html
<H1><CENTER>ActiveNET Inc US, UK, IN</CENTER></H1>
Footer.html
<H6><CENTER style='color:gray;'>Home || Training || Development || Projects || Contact
us</CENTER></H6>
HMenu.html
<A href="index.jsp">Home</A> || <A href="training.jsp">Training</A> || <A
href="development.jsp">Development</A> || <A href="projects.jsp">Projects</A> || <A
href="contactus.jsp">Contact us</A>
index.jsp
<TABLE align="center" border="1">
<TR>
<TD><%@ include file="Header.html"%></TD>
</TR>
<TR>
<TD><%@ include file="HMenu.html"%></TD>
</TR>
<TR>
<TD>Welcome to ActiveNET web site</TD>
</TR>
<TR>
<TD><jsp:include page="Footer.html"/></TD>
</TR>
</TABLE>
training.jsp
<TABLE align="center" border="1">
<TR>
<TD><%@ include file="Header.html"%></TD>
</TR>
<TR>
<TD><%@ include file="HMenu.html"%></TD>
</TR>
<TR>
<TD>
<TABLE>
<TR>
<TH>Course</TH>
<TH>Date & Time</TH>
<TH>Faculty</TH>
<TH>Duration</TH>
</TR>
<TR>
<TD>Core Java</TD>
<TD>1-12-2013</TD>
<TD>Core Java</TD>
<TD>60</TD>
</TR>
<TR>
<TD>Adv Java</TD>
<TD>15-12-2013</TD>
<TD>Suryanarayana</TD>
<TD>60</TD>
</TR>
</TABLE>
</TD>
</TR>
<TR>
<TD><jsp:include page="Footer.html"/></TD>
</TR>
</TABLE>
Conclusion:
If included web pages are frequently modified then <jsp:include> is preferable.
While including static HTML pages in JSP <%@ include %> is preferable, while including Servlets and
JSP <jsp:include> is preferable.
Example on Page directive tag/element
<%@ page %> (Page directive tag)
<%@ page
import=""
language=""
extends=""
isThreadSafe=""
session=""
buffer=""
autoFlush=""
errorPage=""
isErrorPage=""
contentType=""
info=""
%>
Page directive tag is used by the web developer to control the PIC generated by JSP container.
i) import=”” we can list of package statements with comma separator, don't put semi-column
at the end.
a. Ex: import="java.sql.*,java.util.*"
ii) language="Java" by default the language is Java. In future we can embed other
programming languages code also in JSP document.
iii) extends="HttpJspPage sub class" In Tomcat web server the JSP PIC extends from
HttpJspBase class. Then PIC becomes webserver dependent. If JSP PIC want to be web &
application server independent then developer need to write one HttpJspPage interface sub
class, implement all the lifecycle methods and that classname can be mentioned here.
iv) isThreadSafe="true|false" JSPContainer is asking us is JSP class instance variables are safe
from singleton-multi thread model or not. By default it is true. false must be given if we
declare class instance variables.
a. If false is declares JSP container generates PIC that implements from
SingleThreadModel interface. Then servlet container creates separates servlet
object for each client and a separate thread.
b. true can be given even if we declare class instance variables provided if they are
declared CONSTANT or common variables to all the users.
v) session="true|false" by default is true. But for each HttpSession object 85 bytes of memory
is required. If session is true and not used in the JSP for each new client 85 bytes memory
will be unneccessarily allocated that is server unneccessary heap consumption.
vi) buffer="32Kb|8kb|none"
a. the buffer size is the size of JspWriter class object out. Once after every 8kb fill the
response will be automatically flushed and cleared.
vii) autoFlush="true|false"
viii) errorPage="Error.jsp"
ix) isErrorPage="false"
Standard action elements:
<jsp:forward page=""/>
<jsp:include page=""/>
<jsp:useBean id="" class="" scope="">
<jsp:setProperty name="" property="" value=""/>
<jsp:getProperty name="" property=""/>
</jsp:useBean>
<jsp:plugin type="" code="" codebase="">
<jsp:params>
<jsp:param name="" value=""/>
</jsp:params>
<jsp:fallback>
</jsp:plugin>
Example on <jsp:forward> and <jsp:include> standard
action element:
� <jsp:forward> element/tag is used to forward other HTML/JSP documents onto browser.
� <jsp:include> element/tag is used to include other HTML/JSP documents into JSP PIC.
� <jsp:forward> uses
getServletContext()/application.getRequestDispatcher(“/jsp_file_path”).forward(request,
response) method.
� <jsp:include> uses
getServletContext()/application.getRequestDispatcher(“/jsp_file_path”).include(request,
response) method.
� <jsp:forward> element/tag forwards last page output to browser, pages which are included
in the previous communication are cleared-off.
� <jsp:include> element/tag includes every page included in the JSP till last page and finally all
the included pages output goes to browser.
<jsp:forward> and <jsp:include> tags are used to include and forward other JSP and HTML pages in a
JSP Page. Both tags take page attribute.
Login.html
<PRE>
<FORM method="post" action="./Login.jsp">
User <INPUT type="text" name="user">
Pass <INPUT type="password" name="pass">
<INPUT type="submit" name="submit" value="Login">
</FORM>
</PRE>
Login.jsp
<%
String user=request.getParameter("user").trim();
String pass=request.getParameter("pass").trim();
if(user.equals("abc") && pass.equals("xyz")) {
%>
<jsp:forward page="LoginSuccess.jsp"/>
<%
} else {
%>
<jsp:include page="LoginFailed.jsp"/>
<%
}
%>
LoginSuccess.jsp
Login Success <%=request.getParameter("user")%>
LoginFailed.jsp
Login Failed <%=request.getParameter("user")%>
Example on MVC Architecture implementation using
<jsp:useBean> and its sub tags <jsp:setProperty> and
<jsp:getProperty>:
jsp:useBean and its sub tags
<jsp:useBean> is used to create objects of the bean and its sub tags <jsp:setProperty> and
<jsp:getProperty> are used to call setter and getter methods on the bean properties.
The intent of this tag is to avoid writing java code in JSPs.
With this tag we can implement MVC architectures in java web applications.
<jsp:setProperty> tag reads request parameters, converts them into appropriate types like int, long,
double etc and then populates the values into Bean. Hence we need not have to explicitly call
request.getParameter() statements.
i) Open Eclipse IDE
ii) Create a web project
Name: activenet_reg
iii) Create a HTML
Name: NewReg.html
<html>
<head>
<style type="text/css" lang="stylesheet">
INPUT {
border:solid 1px green
}
#bluebg {
background-color: teal;
}
#sname{
background-color: red;
}
.yellowbg {
background-color: yellow;
}
fieldset {
background-image: url("paper_1024.jpg");
background-repeat:no-repeat;
border: 1px solid green;
}
</style>
</head>
<body>
<PRE><center><fieldset style="width:300px;">
<legend>New Reg Form</legend>
<FORM method="post" action="./NewReg.jsp">
SName <INPUT type="text" name="sname" id="sname">
Email <INPUT type="text" name="email" id="bluebg">
Mobile <INPUT type="text" name="mobile" class="yellowbg">
Course <INPUT type="text" name="course" id="bluebg">
Address <INPUT type="text" name="address" class="yellowbg">
<INPUT type="submit" name="submit" value="Reg">
</FORM>
</fieldset></center>
</PRE>
</body></html>
iv) Create one more HTML
Name: FindReg.html
<PRE>
<FORM method="get" action="./FindReg.jsp">
Reg ID <INPUT type="text" name="regid">
<INPUT type="submit" name="submit" value="Find">
</FORM>
</PRE>
v) Create a Java class
Package: beans
Name: Reg
package beans;
public class Reg {
private int regid;
private String sname;
private String email;
private String mobile;
private String course;
private String address;
Connection con;
Statement stmt;
PreparedStatement pstmt;
ResultSet rs;
public Reg() {
super();
initDB();
}
public Reg(int regid, String sname, String email, String mobile,
String course, String address) {
super();
this.regid = regid;
this.sname = sname;
this.email = email;
this.mobile = mobile;
this.course = course;
this.address = address;
initDB();
}
public void initDB() {
try {
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
con=DriverManager.getConnection("jdbc:odbc:oracledsn", "active",
"activenet");
stmt=con.createStatement();
pstmt=con.prepareStatement("INSERT INTO reg VALUES (?,?,?,?,?,?)");
}
catch(Exception e) {}
}
public int getRegid() {
return regid;
}
public void setRegid(int regid) {
this.regid = regid;
}
public String getSname() {
return sname;
}
public void setSname(String sname) {
this.sname = sname;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getMobile() {
return mobile;
}
public void setMobile(String mobile) {
this.mobile = mobile;
}
public String getCourse() {
return course;
}
public void setCourse(String course) {
this.course = course;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public void save() {
try {
rs=stmt.executeQuery("SELECT max(regid) FROM reg");
if(rs.next()) {
regid=rs.getInt(1);
}
regid++;
pstmt.setInt(1, regid);
pstmt.setString(2, sname);
pstmt.setString(3, email);
pstmt.setString(4, mobile);
pstmt.setString(5, course);
pstmt.setString(6, address);
pstmt.executeUpdate();
}
catch(Exception e) {}
}
public void find() {
// List list=new ArrayList();
try {
rs=stmt.executeQuery("SELECT * FROM reg WHERE regid="+regid);
if(rs.next()) {
regid=rs.getInt(1);
sname=rs.getString(2);
email=rs.getString(3);
mobile=rs.getString(4);
course=rs.getString(5);
address=rs.getString(6);
}
}
catch(Exception e) {}
}
public List findAll() {
List list=new ArrayList();
try {
rs=stmt.executeQuery("SELECT * FROM reg");
while(rs.next()) {
Reg r=new Reg(rs.getInt(1), rs.getString(2), rs.getString(3),
rs.getString(4), rs.getString(5), rs.getString(6));
list.add(r);
}
}
catch(Exception e) {}
return list;
}
}
+ Create a JSP
Name: NewReg.jsp
<jsp:useBean id="rb" class="beans.Reg">
<%-- beans.Reg rb=new beans.Reg(); --%>
<jsp:setProperty name="rb" property="*"/>
<%-- rb.setSname(request.getParameter("sname")); --%>
<%-- rb.setEmail(request.getParameter("email")); --%>
<% rb.save(); %>
Reg ID is : <jsp:getProperty name="rb" property="regid"/>
<%-- out.println(rb.getRegid()); --%>
</jsp:useBean>
+ Create a JSP
+ FindReg.jsp
<jsp:useBean id="rb" class="beans.Reg">
<jsp:setProperty name="rb" property="*"/>
<% rb.find(); %>
Reg ID : <jsp:getProperty name="rb" property="regid"/><br/>
SName : <jsp:getProperty name="rb" property="sname"/><br/>
<%-- <%=rb.getSname()%> --%>
Email : <jsp:getProperty name="rb" property="email"/><br/>
Mobile : <jsp:getProperty name="rb" property="mobile"/><br/>
Course : <jsp:getProperty name="rb" property="course"/><br/>
Address: <jsp:getProperty name="rb" property="address"/><br/>
</jsp:useBean>
+ Create a JSP
+ FindAllRegs.jsp
<html>
<head>
<style type="text/css" lang="stylesheet">
#colhead {
background-color: brown;
color: orange;
}
.even {
background-color: orange;
color: brown;
}
.odd {
background-color: white;
color: brown;
}
</style>
</head>
<body>
<jsp:useBean id="rb" class="beans.Reg">
<%
java.util.List list=rb.findAll();
java.util.Iterator i=list.iterator();
%>
<TABLE>
<TR id="colhead">
<TH>Reg ID</TH>
<TH>SName</TH>
<TH>Email</TH>
<TH>Mobile</TH>
<TH>Course</TH>
<TH>Address</TH>
</TR>
<%
int counter=1;
while(i.hasNext()) {
Object o=i.next();
beans.Reg r=(beans.Reg)o;
if(counter%2==0) {
%>
<TR class="even">
<TD><%=r.getRegid()%></TD>
<TD><%=r.getSname()%></TD>
<TD><%=r.getEmail()%></TD>
<TD><%=r.getMobile()%></TD>
<TD><%=r.getCourse()%></TD>
<TD><%=r.getAddress()%></TD>
</TR>
<%
} else {
%>
<TR class="odd">
<TD><%=r.getRegid()%></TD>
<TD><%=r.getSname()%></TD>
<TD><%=r.getEmail()%></TD>
<TD><%=r.getMobile()%></TD>
<TD><%=r.getCourse()%></TD>
<TD><%=r.getAddress()%></TD>
</TR>
<%
}
counter++;
}
%>
</TABLE>
</jsp:useBean>
</body>
</html>
http://localhost:8081/activenet_reg/NewReg.html
http://localhost:8081/activenet_reg/FindReg.html
http://localhost:8081/activenet_reg/FindAllRegs.jsp
Custom / User defined tags:
In XML, XML tags are defined in DTD / Schema and used in XML document. In XML document we will
store the data structuredly. But the purpose of tags defined in JSP is to used them in JSP document
to execute java code without writing java code directly in JSP.
Custom tags are written and used in JSP is to avoid java code completely from JSP document.
To write user defined tag we need to write a class that extends TagSupport class, override 3 lifecycle
methods:
public int doStartTag()
public int doAfterBody()
public int doEndTag()
Configure the tag name and Tag implementation Class/Tag Handler Class in a.tld extension file.
tld (Tag Library Descriptor)
.tld file must be placed in WEB-INF folder
In the .tld file we need to mention one common namespace to all the tags in <uri> tag of a .tld file.
In the JSP document
<%@ taglib uri="thenamespacementionedintld" prefix="a"%>
<a:tagname/>
Tag Handler Class hierarchy:
JspTag
|
Tag
|
IterationTag
|
TagSupport
No methods are derived from JspTag interface but functions like a Marker interface.
******************************************************************
What is Marker interface?
******************************************************************
Marker interfaces may or many not contain methods, but interface which is not having methods is
called as Marker interface. But some marker interfaces are also having methods.
Thread API recognizes the class which is having run() method as Thread provided if the class is
directly or indirectly implemented from Runnable interface. But it is having run() method.
In object serialization only the class which is implemented from Serializable can only be serialized.
This verification is performed by ObjectOutputStream.writeObject(Object o) method.
In servlets servlet container creates object of Servlet class. But not the class which contains init(),
service() and destroy() is treated as Servlet, it is treated only if and if it is directly or indiectly derived
from javax.servlet.Servlet interface.
In RMI rmic generates stubs and skeletons only to the class which is inherited from Remote
interface. Since there are no methods exist in Remote interface.
******************************************************************
From Tag interface following methods:
doStartTag(), doEndTag(), release(), setParent(), getParent(), setPageContext(PageContext pc)
following vars:
SKIP_BODY
EVAL_BODY_INCLUDE
SKIP_PAGE
EVAL_PAGE
From IterationTag interface
method:
doAfterBody()
var:
EVAL_BODY_AGAIN
Finally TagSupport (Adapter) class implements from IterationTag interface implemented all the
super interface methods. Hence when we want to implement custom tag we need to extend from
TagSupport class and can override required methods.
In empty tag only doStartTag() method implementation is sufficient.
In nested tags all 3 doStartTag(), doAfterBody() and doEndTag() method implementation are
required.
Valid return values in
public int doStartTag() {
return SKIP_BODY;
return EVAL_BODY_INCLUDE;
}
public int doAfterBody() {
return EVAL_BODY_AGAIN;
return SKIP_BODY;
}
public int doEndTag() {
return EVAL_PAGE;
return SKIP_PAGE;
}
Example on Empty tag with attribute
Example: <a:courses size="1|5"/>
+ open Eclipse
+ Create a Web Project
Name: hello_tag
+ Create a class
+ Name: HelloTag
package tags;
import java.io.IOException;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.TagSupport;
public class HelloTag extends TagSupport {
/*
* setId(String id)
* setParent(Tag tag)
* setPageContext(PageContext pageContext)
* setValue(String key, Object o)
*
* String getId()
* Tag getParent()
* PageContext getPageContext()
* Object getValue(String key)
* Enumeration getValues()
*
* int doStartTag()
* int doAfterBody()
* int doEndTag()
*
* release()
* wait(), wait(long ms), wait(long ms, int ns), notify(), notifyAll()
* equals(). toString(), hashCode()
*
*/
private String name;
private int age;
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public int doStartTag() throws JspException {
try {
pageContext.getOut().println("Hello "+name+" your age is "+age);
} catch (IOException e) {
e.printStackTrace();
}
return SKIP_BODY;
}
}
mytags.tld
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE taglib
PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN"
"http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">
<taglib>
<tlib-version>1.0</tlib-version>
<jsp-version>1.2</jsp-version>
<short-name>a</short-name>
<uri>http://www.activenetinformatics.com/adv/am36/jsp/customtags</uri>
<display-name>AM36 batch</display-name>
<description>Custom Tags Example</description>
<tag>
<name>hello</name>
<tag-class>tags.HelloTag</tag-class>
<body-content>empty</body-content>
<attribute>
<name>name</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>age</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
</taglib>
Hello.jsp
<%@ taglib uri="http://www.activenetinformatics.com/adv/am36/jsp/customtags" prefix="a1"%>
<%-- <a1:hello age="16" name="ActiveNET"/> --%>
<a1:hello age='<%=Integer.parseInt(request.getParameter("age"))%>'
name='<%=request.getParameter("name")%>'/>
http://localhost:65535/hello_tag/Hello.jsp?age=20&name=ActiveNET
Example on Empty tag with attribute
Example: <a:courses size="1|5"/>
+ open Eclipse
+ Create a Web Project
Name: emptytag
src
tags
CoursesTag.java
WebRoot
WEB-INF
web.xml
tags.tld
NewRegForm.jsp
+ Create a class
Package: tags
Name: CoursesTag
super class: TagSupport
package tags;
public class CoursesTag extends TagSupport {
// if tag is passed with an attribute then such variable
// must be declared as class private instance variable in
// TIC/THC and provide one pair of public setter method.
private int size;
public void setSize(int size) {
this.size=size;
}
public int doStartTag() {
try {
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
Connection con=DriverManager.getConnection("jdbc:odbc:oracledsn",
"active", "activenet");
Statement stmt=con.createStatement();
ResultSet rs=stmt.executeQuery("SELECT cname FROM course");
JspWriter out=pageContext.getOut();
out.println("<SELECT name='course' size='"+size+"'>");
while(rs.next()) {
String cname=rs.getString(1);
out.println("<OPTION value='"+cname+"'>");
out.println(cname);
out.println("</OPTION>");
}
out.println("<SELECT>");
}
catch(Exception e) {}
return SKIP_BODY;
}
}
Copy one .tld file from Tomcat installation directory, place the file into our WEB-INF folder.
tags.tld
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE taglib
PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN"
"http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">
<taglib>
<tlib-version>1.0</tlib-version>
<jsp-version>1.2</jsp-version>
<short-name>a</short-name>
<uri>http://www.activenetinformatics.com/am35/jsp/customtags</uri>
<display-name>JSTL core RT</display-name>
<description>our own library</description>
<tag>
<name>courses</name>
<tag-class>tags.CoursesTag</tag-class>
<body-content>empty</body-content>
<description>
To dynamically populate course names in a drop down list box this tag library is developed.
</description>
<attribute>
<name>size</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
</taglib>
NewRegForm.jsp
<%@ taglib uri="http://www.activenetinformatics.com/am35/jsp/customtags" prefix="a"%>
<PRE>
<FORM>
SName <INPUT type="text" name="sname">
Email <INPUT type="text" name="email">
Mobile <INPUT type="text" name="mobile">
Course <a:courses size="5"/>
Address <INPUT type="text" name="address">
<INPUT type="submit" name="submit" value="Register">
</FORM>
</PRE>
deploy web app, start tomcat
http://localhost:65535/emptytag/NewRegForm.jsp
Example on Nested Tag
Example:
<a:transaction>
<a:admission/>
<a:displayAllAdmissions/>
</a:transaction>
+ Create one more class
Package: tags
Name: TransactionTag
super class: TagSupport
package tags;
public class TransactionTag extends TagSupport {
private String driver;
private String url;
private String user;
private String pass;
Connection con;
Statement stmt;
public void setDriver(String driver) {
this.driver = driver;
}
public void setUrl(String url) {
this.url = url;
}
public void setUser(String user) {
this.user = user;
}
public void setPass(String pass) {
this.pass = pass;
}
public int doStartTag() {
try {
Class.forName(driver);
con=DriverManager.getConnection(url, user, pass);
stmt=con.createStatement();
}
catch(Exception e) {}
return EVAL_BODY_INCLUDE;
}
public int doAfterBody() {
return SKIP_BODY;
}
public int doEndTag() {
return EVAL_PAGE;
}
}
Create a New Class
Name: AdmissionTag
package tags;
public class AdmissionTag extends TagSupport {
public int doStartTag() {
try {
HttpServletRequest req=(HttpServletRequest)pageContext.getRequest();
Tag t=getParent();
TransactionTag tt=(TransactionTag)t;
ResultSet rs=tt.stmt.executeQuery("SELECT max(regid) FROM reg");
int regid=0;
if(rs.next()) {
regid=rs.getInt(1);
}
regid++;
PreparedStatement pstmt=tt.con.prepareStatement("INSERT INTO reg
VALUES (?,?,?,?,?,?)");
pstmt.setInt(1, regid);
pstmt.setString(2, req.getParameter("sname").trim());
pstmt.setString(3, req.getParameter("email").trim());
pstmt.setString(4, req.getParameter("mobile").trim());
pstmt.setString(5, req.getParameter("course").trim());
pstmt.setString(6, req.getParameter("address").trim());
pstmt.executeUpdate();
pageContext.getOut().println("Reg ID is "+regid);
}
catch(Exception e) {}
return SKIP_BODY;
}
}
Name: DisplayAllAdmissionsTag
package tags;
import java.sql.ResultSet;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.Tag;
import javax.servlet.jsp.tagext.TagSupport;
public class DisplayAllAdmissionsTag extends TagSupport {
public int doStartTag() {
try {
Tag t=getParent();
TransactionTag tt=(TransactionTag)t;
ResultSet rs=tt.stmt.executeQuery("SELECT * FROM reg");
JspWriter out=pageContext.getOut();
out.println("<TABLE>");
out.println("<TR>");
out.println("<TH>Reg ID</TH>");
out.println("<TH>SName</TH>");
out.println("<TH>Email</TH>");
out.println("<TH>Mobile</TH>");
out.println("<TH>Course</TH>");
out.println("<TH>Address</TH>");
out.println("</TR>");
while(rs.next()) {
out.println("<TR>");
out.println("<TD>"+rs.getInt(1)+"</TD>");
out.println("<TD>"+rs.getString(2)+"</TD>");
out.println("<TD>"+rs.getString(3)+"</TD>");
out.println("<TD>"+rs.getString(4)+"</TD>");
out.println("<TD>"+rs.getString(5)+"</TD>");
out.println("<TD>"+rs.getString(6)+"</TD>");
out.println("</TR>");
}
out.println("</TABLE>");
}
catch(Exception e) {}
return SKIP_BODY;
}
}
NewReg.jsp
<%@ taglib uri="http://www.activenetinformatics.com/am35/jsp/customtags" prefix="a"%>
<a:transaction driver="sun.jdbc.odbc.JdbcOdbcDriver" url="jdbc:odbc:oracledsn" user="active"
pass="activenet">
<a:admission/>
<a:displayAllAdmissions/>
</a:transaction>
NewRegForm.jsp same as previous application.
tags.tld
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE taglib
PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN"
"http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">
<taglib>
<tlib-version>1.0</tlib-version>
<jsp-version>1.2</jsp-version>
<short-name>a</short-name>
<uri>http://www.activenetinformatics.com/am35/jsp/customtags</uri>
<display-name>JSTL core RT</display-name>
<description>our own library</description>
<tag>
<name>courses</name>
<tag-class>tags.CoursesTag</tag-class>
<body-content>empty</body-content>
<description>
To dynamically populate course names in a drop down list box this tag library is developed.
</description>
<attribute>
<name>size</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
<tag>
<name>transaction</name>
<tag-class>tags.TransactionTag</tag-class>
<body-content>JSP</body-content>
<description>
This tag accepts driver props as attributes, initialize con & stmt object tp provide to their
sub tags.
</description>
<attribute>
<name>driver</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>url</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>user</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>pass</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
<tag>
<name>admission</name>
<tag-class>tags.AdmissionTag</tag-class>
<body-content>empty</body-content>
<description>
Tis tag accepts reg details from req parameters and inserts into DB.
</description>
</tag>
<tag>
<name>displayAllAdmissions</name>
<tag-class>tags.DisplayAllAdmissionsTag</tag-class>
<body-content>empty</body-content>
<description>
Tis tag populates all reg details on browser in a tabular format .
</description>
</tag>
</taglib>
AJAX with Servlet/JSP
AJAX (Asynchronous JavaScript and XML)
AJAX is a web 2.0 technology, it is only a technique used to keep HTML page as it is on browser and
only sends data as request to server and brings data response back to browser but not the entire
HTML page.
AJAX reduces the n/w bandwidth consumption between client and server.
HTML+CSS+JS+XHR=> AJAX
To use AJAX in HTML documents we must use one JavaScript in-built object one among 9 is
XMLHttpRequest.
(Window, String, Date, Number, Math, Array, RegExpr, Boolean, XMLHttpRequest)
With AJAX we can reduce request-response time.
XMLHttpRequest object is not a cross browser compatible class. Hence we cannot request it using
var xhr=new XMLHttpRequest();
In old IE 6.0 web browser, the browser support ActiveXObject() objects. In IE 6 Microsoft developed
one ActiveXObject called Microsoft.XMLHTTP and Msxml2.XMLHTTP. These objects must be created
new ActiveXObject("Microsoft.XMLHTTP");
In other than IE browser and from IE7 onwards browsers are having directly XMLHttpRequest object
support.
var xhr;
function createXHR() {
if (ActiveXObject) {
window.alert("IE browser");
xhr=new ActiveXObject("Microsoft.XMLHTTP");
window.alert(xhr);
if(xhr==null) {
xhr=new ActiveXObject("Msxml2.XMLHTTP");
window.alert(xhr);
}// if()
}// if()
else if (XMLHttpRequest) {
xhr=new XMLHttpRequest(); // non IE and IE7 onwards
window.alert("your browser is non IE "+xhr);
} else {
window.alert("No XHR support");
}
}
XMLHttpRequest is having following methods:
i) open(HTTPMethod, URL, Asnych)
ii) send(data)
iii) setRequestHeader(headerName, headerValue)
XMLHttpRequest is having following properties:
i) onreadystatechange
ii) readyState
iii) status
iv) statusText
v) responseText
vi) responseXML
open() method takes GET or POST as first argument, if GET is used the form data/ HTTP encode
string is appended at the end of URL (is the second argument), in case of POST the form data must
be passed through send() method, so that the data will go through HTTP request body as a payload.
onreadystatechange - this xhr property stores the function name which is to be called each time
when xhr readyState changes from 0-4.
readyState - from the begining to till end xhr readyState changes from 0-4
0 - Uninitialized/xhr object is created but server connection is not established
1 - Initialized / connection established to server, open() method is called
2 - Sent/request sent to server
3 - Receiving / processing request
4 - Received / request finished-response ready
status - is a HTTP status coming from server
200 - OK
404 - Page not found
500 - Internal server error
307 - Temporary Redirect
responseXML, responseText - based on whether server is sending response in a XML form or plain
text form we need to use this method
Create a web project
Name: ajax_call
Create a HTML
Name: Reg.html
<HTML>
<HEAD>
<SCRIPT>
var xhr;
function createXHR() {
if (ActiveXObject) {
// window.alert("IE browser");
xhr=new ActiveXObject("Microsoft.XMLHTTP");
// window.alert(xhr);
if(xhr==null) {
xhr=new ActiveXObject("Msxml2.XMLHTTP");
// window.alert(xhr);
}// if()
}// if()
else if (XMLHttpRequest) {
xhr=new XMLHttpRequest(); // non IE and IE7 onwards
// window.alert("your browser is non IE "+xhr);
} else {
// window.alert("No XHR support");
}
}
function getReg() {
createXHR();
var regId=window.document.getElementById("regid");
var regIdValue=regId.value;
// window.alert(regIdValue);
xhr.onreadystatechange=callback;
// window.alert("after onreadystatechange");
xhr.open("GET", "./RetrieveReg.jsp?regid="+regIdValue, false);
// window.alert("after open");
xhr.send("");
// window.alert("after send()");
}
function callback() {
// window.alert(xhr.readyState+" "+xhr.status);
if(xhr.readyState==4 && xhr.status==200) {
var respXML=xhr.responseXML;
// window.alert(respXML);
var regid=window.document.getElementById("regid");
var sname=window.document.getElementById("sname");
var email=window.document.getElementById("email");
var mobile=window.document.getElementById("mobile");
var course=window.document.getElementById("course");
var address=window.document.getElementById("address");
var regids=respXML.getElementsByTagName("regid");
// window.alert(regids[0].firstChild.data);
regid.value=regids[0].firstChild.data;
var snames=respXML.getElementsByTagName("sname");
// window.alert(snames[0].firstChild.data);
sname.value=snames[0].firstChild.data;
email.value=respXML.getElementsByTagName("email")[0].firstChild.data;
mobile.value=respXML.getElementsByTagName("mobile")[0].firstChild.data;
course.value=respXML.getElementsByTagName("course")[0].firstChild.data;
address.value=respXML.getElementsByTagName("address")[0].firstChild.data;
}
}
</SCRIPT>
</HEAD>
<BODY>
<PRE>
<FORM>
RegID <INPUT type="text" name="regid" id="regid" onblur="getReg()">
SName <INPUT type="text" name="sname" id="sname" value="">
Email <INPUT type="text" name="email" id="email">
Mobile <INPUT type="text" name="mobile" id="mobile">
Course <INPUT type="text" name="course" id="course">
Address <INPUT type="text" name="address" id="address">
<INPUT type="button" name="button" id="button" value="Update">
</FORM>
</PRE>
</BODY>
</HTML>
RetrieveReg.jsp
<%
response.setContentType("text/xml");
int regid=Integer.parseInt(request.getParameter("regid").trim());
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
java.sql.Connection con=java.sql.DriverManager.getConnection("jdbc:odbc:oracledsn", "active",
"activenet");
java.sql.Statement stmt=con.createStatement();
java.sql.ResultSet rs=stmt.executeQuery("SELECT * FROM reg WHERE regid="+regid);
String xml="<reg>";
if(rs.next()) {
xml+="<regid>"+rs.getInt(1)+"</regid>";
xml+="<sname>"+rs.getString(2)+"</sname>";
xml+="<email>"+rs.getString(3)+"</email>";
xml+="<mobile>"+rs.getString(4)+"</mobile>";
xml+="<course>"+rs.getString(5)+"</course>";
xml+="<address>"+rs.getString(6)+"</address>";
}
xml+="</reg>";
System.out.println(xml);
out.println(xml);
%>
UpdateReg.jsp
<%
response.setContentType("text/plain");
java.io.InputStream is=request.getInputStream();
java.io.DataInputStream dis=new java.io.DataInputStream(is);
// System.out.println(dis.readLine());
String line=dis.readLine();
int regid=0;
String sname="";
String email="";
String mobile="";
String course="";
String address="";
java.util.StringTokenizer st=new java.util.StringTokenizer(line,"&");
java.util.StringTokenizer st1=new java.util.StringTokenizer(st.nextToken(),"=");
st1.nextToken();
regid=Integer.parseInt(st1.nextToken());
st1=new java.util.StringTokenizer(st.nextToken(),"=");
st1.nextToken();
sname=st1.nextToken();
st1=new java.util.StringTokenizer(st.nextToken(),"=");
st1.nextToken();
email=st1.nextToken();
st1=new java.util.StringTokenizer(st.nextToken(),"=");
st1.nextToken();
mobile=st1.nextToken();
st1=new java.util.StringTokenizer(st.nextToken(),"=");
st1.nextToken();
course=st1.nextToken();
st1=new java.util.StringTokenizer(st.nextToken(),"=");
st1.nextToken();
address=st1.nextToken();
Class.forName("oracle.jdbc.driver.OracleDriver");
java.sql.Connection
con=java.sql.DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:XE", "active",
"activenet");
java.sql.PreparedStatement pstmt=con.prepareStatement("UPDATE reg SET
sname=?,email=?,mobile=?,course=?,address=? WHERE regid=?");
pstmt.setString(1,sname);
pstmt.setString(2,email);
pstmt.setString(3,mobile);
pstmt.setString(4,course);
pstmt.setString(5,address);
pstmt.setInt(6, regid);
int i=pstmt.executeUpdate();
System.out.println(i+" row updated");
out.println(i+" row updated");
%>
JSTL
JSP Standard Tag Library
Core, SQL, FMT, XML Tag Libraries
By SuryanarayanaBy SuryanarayanaBy SuryanarayanaBy Suryanarayana
ActiveNET
Custom tags are used to avoid writing java code in jsp documents. Hence we can substitute them
with custom tags.
Whereas JSTL allows us to write java logic in JSP document using JSTL tags but not by directly writing
Java code.
Java logic generally consists of variable declaration, initialization, accessing, storing-retrieving and
removing attributes from various scopes (request, session, application), object creation, method
calls on object, conditions, loops, exception handling statements, JDBC operations, reading request
parameters etc.
Additionally we may use I18N support, XML generation, parsing, transformation etc.
To perform these operations in JSTL Sun provided 4 tag libraries called:
i) Core Tag Library
ii) SQL Tag Library
iii) XML Tag Library
iv) Formatting Tag Library
Each tag library consists of many pre-defined tags whose classes are bundled and given in jstl.jar and
standard.jar. These tag library classes and their tag names are configured in 4 .tld extension files
(c.tld, sql.tld, x.tld, fmt.tld-I18N)
Hence to use JSTL in java web project, while creating web project we must include jstl.jar and
standard.jar files in project lib directory.
Tag Libraries, their files, their namespaces and their prefixes
Tag Library Name tld file name Namespace Prefix
Core Library c.tld http://java.sun.com/jstl/core
http://java.sun.com/jsp/jstl/core
c
SQL Library sql.tld http://java.sun.com/jstl/sql
http://java.sun.com/jsp/jstl/sql
sql
XML Library x.tld http://java.sun.com/jstl/xml
http://java.sun.com/jsp/jstl/xml
x
Formatting Library fmt.tld http://java.sun.com/jstl/fmt
http://java.sun.com/jsp/jstl/fmt
fmt
Functions fn.tld http://java.sun.com/jstl/fn
http://java.sun.com/jsp/jstl/fn
fn
How many tags each tag library consists of:
Tag Name with attributes Explanation
The tags in c.tld are: (14)
Variable management tags:
<c:set var="" value="" scope=""> Store variable with the given name in the given
scope.
<c:out value=""> Retrieves variable from the request scope with
requested variable name.
<c:remove var="" scope=""> Removes variable from the request scope and
name
Conditions tags:
<c:if test=”” var=””> Meant for writing simple/single condition
<c:choose>
<c:when>
<c:otherwise>
</c:choose>
Meant for writing multiple conditions. The whole
complex condition must be place <c:choose> tag,
each condition must be placed in <c:when>, the
last else condition must be placed in
<c:otherwise> tag.
Loops:
<c:forEach >
<c:forTokens >
Exception handling:
<c:catch>
Miscellaneous:
<c:import>
<c:param>
<c:redirect>
<c:param>
<c:url>
<c:param>
The tags in sql.tld are: (6)
<sql:setDataSource>
<sql:transaction>
<sql:update>
<sql:query>
<sql:param>
<sql:dateParam>
The tags in x.tld are: (10)
set
out
choose
when
otherwise
if
forEach
param
parse
transform
The tags in fmt.tld are: (12)
requestEncoding
setLocale
timeZone
setTimeZone
Bundle
setBundle
Message
Param
formatNumber
parseNumber
formatDate
parseDate
The functions in fn.tld are: (15)
fn:contains()
fn:containsIgnoreCase()
fn:endsWith()
fn:escapeXml()
fn:indexOf()
fn:trim()
fn:startsWith()
fn:split()
fn:toLowerCase()
fn:toUpperCase()
fn:substring()
fn:substringAfter()
fn:substringBefore()
fn:length()
fn:replace()
Example on JSTL Core Tag Library Tags
The JSTL Core Tag Library provides tags for variable support, URL management, flow control etc.
+ Open Eclipse
+ Create a DynamicWebProject
Name: jstl_1
Select Add JSTL libraries to WEB-INF/lib folder check box
Click on Finish
+ Create a JSP
Name: Core.jsp
<%@ taglib uri="http://java.sun.com/jstl/core" prefix="c"%>
<%-- var management tags --%>
<%-- storing var 'i' into various scope with diff values --%>
<c:set var="i" value="10" />
<!-- by default page scope -->
<c:set var="i" value="100" scope="page" />
<c:set var="i" value="1000" scope="request" />
<c:set var="i" value="10000" scope="session" />
<c:set var="i" value="100000" scope="application" />
<c:set var="str" value="ActiveNET" scope="request" />
<%
Object o = request.getAttribute("i");
out.println(o.getClass().getName() + "<br>");
%>
<%=request.getAttribute("i").getClass().getName()%><br />
<%=request.getAttribute("str").getClass().getName()%><br />
<%-- retrive and display variables from the above scopes --%>
<c:out value="${pageScope.i}" /><br />
<c:out value="${requestScope.i}" /><br />
<c:out value="${sessionScope.i}" /><br />
<c:out value="${applicationScope.i}" /><br />
<%-- removing attribute from a scope --%>
<c:remove var="i" scope="page" />
<c:out value="${pageScope.i}" /><br />
<c:out value="${requestScope.i}" /><br />
<c:out value="${sessionScope.i}" /><br />
<c:out value="${applicationScope.i}" /><br />
<!-- Conditional tags -->
<%-- Simple condition --%>
<c:if test="${5==5}" var="result">
5==5 is <c:out value="${result}" />
<br />
</c:if>
<%-- Compound condition / multiple conditions --%>
<c:choose>
<c:when test="${5==5}">
Yes you know maths<br />
</c:when>
<c:when test="${5!=5}">
you don't know maths<br />
</c:when>
<c:otherwise>
I don't comment on you. <br />
</c:otherwise>
</c:choose>
<%-- Simple Loop / Definite Loop --%>
<c:forEach var="j" begin="1" end="10" step="1">
<c:out value="${j}" /> X 38 = <c:out value="${j*38}" />
<br />
</c:forEach>
<%-- indefinite loop --%>
<%
java.util.List list = new java.util.ArrayList();
list.add("Apple");
list.add("Mango");
list.add("Guava");
list.add("Papaya");
list.add("Grapes");
list.add("Banana");
list.add("Strawberry");
request.setAttribute("fruits", list);
%>
<%-- <c:forEach> tag items attribute takes only array or collection object as its value --%>
<%-- List list=(List)request.getAttribute("fruits"); --%>
<c:forEach items="${requestScope.fruits}" var="fruit">
<c:out value="${fruit}" />
<br />
</c:forEach>
<%-- c:forTokens tag acts like StringTokenizer --%>
<c:forTokens items="I am Mad, i am mad. Are you Mad, We are all mad."
delims=" " var="token">
<c:out value="${token}" />
<br />
</c:forTokens>
<%--
<c:catch var="e">
<%
throw new NullPointerException();
%>
<c:out value="${e}" />
</c:catch>
<c:import url="http://www.activenetinformatics.com"/>
<c:redirect url="http://www.activenetinformatics.com"/>
--%>
<c:url value="http://www.google.com">
<c:param name="hl" value="fr"/>
<c:param name="q" value="JSTL XML Examples"/>
</c:url>
Example on JSTL SQL Tag Library Tags
The SQL tag Library tags are meant to interact with RDBMSs such as Oracle, MySQL, MSSQLServer,
IBM DB2 etc.
+ Create a JSP
Name: SQL.jsp
<%@ taglib uri="http://java.sun.com/jstl/core" prefix="c"%>
<%@ taglib uri="http://java.sun.com/jstl/sql" prefix="sql"%>
<PRE>
<FORM method="post" action="./SQLReg.jsp">
Reg ID <input type="text" name="regid"/>
SName <input type="text" name="sname"/>
Email <input type="text" name="email"/>
Mobile <input type="text" name="mobile"/>
Course <input type="text" name="course"/>
Address<input type="text" name="address"/>
<input type="submit" name="submit" value="Reg"/>
</FORM>
</PRE>
<sql:setDataSource driver="sun.jdbc.odbc.JdbcOdbcDriver" url="jdbc:odbc:oracledsn" user="active"
password="activenet" var="con" scope="session"/>
<sql:query dataSource="${sessionScope.con}" sql="select * from reg" var="rs"/>
<TABLE border="1" align="center">
<TR>
<TH>RegID</TH>
<TH>SName</TH>
<TH>Email</TH>
<TH>Mobile</TH>
<TH>Course</TH>
<TH>Address</TH>
</TR>
<c:forEach items="${rs.rows}" var="row">
<TR>
<TD><c:out value="${row.regid}"/></TD>
<TD><c:out value="${row.sname}"/></TD>
<TD><c:out value="${row.email}"/></TD>
<TD><c:out value="${row.mobile}"/></TD>
<TD><c:out value="${row.course}"/></TD>
<TD><c:out value="${row.address}"/></TD>
</TR>
</c:forEach>
</TABLE>
+ Create a JSP
SQLReg.jsp
<%@ taglib uri="http://java.sun.com/jstl/sql" prefix="sql"%>
<%@ taglib uri="http://java.sun.com/jstl/core" prefix="c"%>
<sql:transaction dataSource="${sessionScope.con}">
<sql:update sql="INSERT INTO reg VALUES (?,?,?,?,?,?)">
<sql:param value="${param.regid}"/>
<sql:param value="${param.sname}"/>
<sql:param value="${param.email}"/>
<sql:param value="${param.mobile}"/>
<sql:param value="${param.course}"/>
<sql:param value="${param.address}"/>
</sql:update>
</sql:transaction>
<c:redirect url="./SQL.jsp"/>
Type following URL on browser:
http://localhost:8081/jstl_1/SQL.jsp
If we don’t want user to enter/give regid and want to generate regid automatically on server on
our own, write the following JSP.
or Write the following code in SQLReg.jsp
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/sql" prefix="sql"%>
<%-- i want to store NewReg.jsp form data into reg table. Next want to display all the records in
tabular format --%>
<sql:transaction dataSource="${orads}">
<%-- PK generation --%>
<c:set var="regid" value="0"/>
<sql:query var="rs" sql="SELECT max(regid) FROM reg"></sql:query>
<c:forEach items="${rs.rows}" var="row">
<c:set var="regid" value="${row.regid}"/>
<c:out value="${regid}"/>
</c:forEach>
<c:out value="${regid}"/>
<%-- record insertion --%>
<sql:update sql="INSERT INTO reg VALUES (?,?,?,?,?,?)" var="i">
<%-- reading request parameters --%>
<sql:param value="${regid+1}"/>
<sql:param value="${param.sname}"/>
<%-- equal to request.getParameter("sname") --%>
<sql:param value="${param.email}"/>
<sql:param value="${param.mobile}"/>
<sql:param value="${param.course}"/>
<sql:param value="${param.address}"/>
</sql:update>
<center>Reg ID is <c:out value="${regid}"/></center><br/>
<%-- displaying all records in HTML tabular format --%>
<TABLE>
<TR>
<TH>RegID</TH>
<TH>SName</TH>
<TH>Email</TH>
<TH>Mobile</TH>
<TH>Course</TH>
<TH>Address</TH>
</TR>
<sql:query sql="SELECT * FROM reg" var="rs1"></sql:query>
<c:forEach items="${rs1.rows}" var="row1">
<TR>
<TD><c:out value="${row1.regid}"/></TD>
<TD><c:out value="${row1.sname}"/></TD>
<TD><c:out value="${row1.email}"/></TD>
<TD><c:out value="${row1.mobile}"/></TD>
<TD><c:out value="${row1.course}"/></TD>
<TD><c:out value="${row1.address}"/></TD>
</TR>
</c:forEach>
</TABLE>
</sql:transaction>
Example on JSTL XML Tag Library:
JSTL XML Tag Library is meant for manipulating and creating XML documents. Before going further
we need to copy the two XML and XPath related libraries into <TOMCAT_HOME>\lib directory.
Download Xalan.jar file from the link http://xml.apache.org/xalan-j/index.html
Download XercesImpl.jar file from http://www.apache.org/dist/xerces/j/
Example on <x:out> tag
The <x:out> tag is used for displaying the result of an xml Path expression and writes the result to
JSP writer object. It is similar to the scriptlet tag <%= %> used in JSP.
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="x" uri="http://java.sun.com/jsp/jstl/xml" %>
<html>
<head>
<title>XML Tags</title>
</head>
<body>
<h2>Vegetable Information:</h2>
<c:set var="vegetable">
<vegetables>
<vegetable>
<name>onion</name>
<price>40/kg</price>
</vegetable>
<vegetable>
<name>Potato</name>
<price>30/kg</price>
</vegetable>
<vegetable>
<name>Tomato</name>
<price>90/kg</price>
</vegetable>
</vegetables>
</c:set>
<x:parse xml="${vegetable}" var="output"/>
<b>Name of the vegetable is</b>:
<x:out select="$output/vegetables/vegetable[1]/name"/><br>
<b>Price of the Potato is</b>:
<x:out select="$output/vegetables/vegetable[2]/price"/>
</body>
</html>
Example on <x:parse> tag
The <x:parse> tag is used for parse the XML data specified either in the tag body or an attribute. It is
used for parse the xml content and the result will stored inside specified variable.
novels.xml
<books>
<book>
<name>Three mistakes of my life</name>
<author>Chetan Bhagat</author>
<price>200</price>
</book>
<book>
<name>Tomorrow land</name>
<author>NUHA</author>
<price>2000</price>
</book>
</books>
Parse.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="x" uri="http://java.sun.com/jsp/jstl/xml" %>
<html>
<head>
<title>x:parse Tag</title>
</head>
<body>
<h2>Books Info:</h2>
<c:import var="bookInfo" url="novels.xml"/>
<x:parse xml="${bookInfo}" var="output"/>
<p>First Book title: <x:out select="$output/books/book[1]/name"/></p>
<p>First Book price: <x:out select="$output/books/book[1]/price"/></p>
<p>Second Book title: <x:out select="$output/books/book[2]/name"/></p>
<p>Second Book price: <x:out select="$output/books/book[2]/price"/></p>
</body>
</html>
Example on <x:set> tag
The <x:set> tag is used to set a variable with the value of an XPath expression. It is used to store the
result of xml path expression in a scoped variable.
Set.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="x" uri="http://java.sun.com/jsp/jstl/xml" %>
<html>
<head>
<title>x:set Tag</title>
</head>
<body>
<h3>Books Information:</h3>
<c:set var="book">
<books>
<book>
<name>Three mistakes of my life</name>
<author>Chetan Bhagat</author>
<price>200</price>
</book>
<book>
<name>Tomorrow land</name>
<author>Brad Bird</author>
<price>2000</price>
</book>
</books>
</c:set>
<x:parse xml="${book}" var="output"/>
<x:set var="fragment" select="$output/books/book[2]/price"/>
<b>The price of the Tomorrow land book</b>:
<x:out select="$fragment" />
</body>
</html>
Example on <xml:choose>, <xml:when>, <xml:otherwise>
The <x:choose> tag is a conditional tag that establish a context for mutually exclusive conditional
operations. It works like a Java switch statement in which we choose between a numbers of
alternatives.
The <x:when> is subtag of <x:choose> that will include its body if the condition evaluated be 'true'.
The <x:otherwise> is also subtag of <x:choose> it follows <x:when> tags and runs only if all the prior
condition evaluated is 'false'.
The <x:when> and <x:otherwise> works like if-else statement. But it must be placed inside
<x:choose> tag.
Choose_When_Otherwise.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="x" uri="http://java.sun.com/jsp/jstl/xml" %>
<html>
<head>
<title>x:choose Tag</title>
</head>
<body>
<h3>Books Information:</h3>
<c:set var="xmltext">
<books>
<book>
<name>Three mistakes of my life</name>
<author>Chetan Bhagat</author>
<price>200</price>
</book>
<book>
<name>Tomorrow land</name>
<author>Brad Bird</author>
<price>2000</price>
</book>
</books>
</c:set>
<x:parse xml="${xmltext}" var="output"/>
<x:choose>
<x:when select="$output//book/author = 'Chetan bhagat'">
Book is written by Chetan bhagat
</x:when>
<x:when select="$output//book/author = 'Brad Bird'">
Book is written by Brad Bird
</x:when>
<x:otherwise>
The author is unknown...
</x:otherwise>
</x:choose>
</body>
</html>
Example on <x:if> tag
The <x:if> tag is used for evaluating the test XPath expression. It is a simple conditional tag which is
used for evaluating its body if the supplied condition is true.
IfTag.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="x" uri="http://java.sun.com/jsp/jstl/xml" %>
<html>
<head>
<title>x:if Tags</title>
</head>
<body>
<h2>Vegetable Information:</h2>
<c:set var="vegetables">
<vegetables>
<vegetable>
<name>onion</name>
<price>40</price>
</vegetable>
<vegetable>
<name>Potato</name>
<price>30</price>
</vegetable>
<vegetable>
<name>Tomato</name>
<price>90</price>
</vegetable>
</vegetables>
</c:set>
<x:parse xml="${vegetables}" var="output"/>
<x:if select="$output/vegetables/vegetable/price < 100">
Vegetables prices are very low.
</x:if>
</body>
</html>
Example on <x:transform> tag
The <x:transform> tag is used in a XML document for providing the XSL (Extensible Stylesheet
Language) transformation. It is used for transforming xml data based on XSLT script.
Transfer.xsl
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:param name="doc"/>
<xsl:template match="/">
<html>
<body>
<h2>Company's Employee detail</h2>
<table border="2">
<tr>
<th align="left">Name
</th>
<th align="left">Designation
</th>
<th align="left">Age
</th>
</tr>
<xsl:for-each select="organisation/company/emp">
<tr>
<td>
<xsl:value-of select="name"/>
</td>
<td>
<xsl:value-of select="designation"/>
</td>
<td>
<xsl:value-of select="age"/>
</td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
Transfer.xml
<?xml version="1.0" encoding="UTF-8"?>
<organisation>
<company>
<emp>
<name>Rajan Singh</name>
<designation>Bussiness Developer</designation>
<age>40</age>
</emp>
<emp>
<name>Supriya Gaur</name>
<designation>HR Executive</designation>
<age>22</age>
</emp>
</company>
<company>
<emp>
<name>Shashnak Singhal</name>
<designation>Sr. Java Programmer</designation>
<age>26</age>
</emp>
<emp>
<name>Hemant Kishor</name>
<designation>Sr. PHP Programmer</designation>
<age>23</age>
</emp>
</company>
</organisation>
Transform.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="x" uri="http://java.sun.com/jsp/jstl/xml" %>
<html>
<head>
<title>x:transform Tag</title>
</head>
</html>
<c:import var="xml" url="transfer.xml" />
<c:import var="xsl" url="transfer.xsl" />
<x:transform xml="${xml}" xslt="${xsl}" />
Example on <x:param> tag
The <x:param> tag is used to set the parameter in the XSLT style sheet. It use along with the
transform tag for sending parameter along with the value.
Transfer.xsl
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="html" indent="yes"/>
<xsl:param name="bgColor"/>
<xsl:template match="/">
<html>
<body>
<xsl:apply-templates/>
</body>
</html>
</xsl:template>
<xsl:template match="books">
<table border="1" width="60%" bgColor="{$bgColor}">
<xsl:for-each select="book">
<tr>
<td>
<b><xsl:value-of select="name"/></b>
</td>
<td>
<xsl:value-of select="author"/>
</td>
<td>
<xsl:value-of select="price"/>
</td>
</tr>
</xsl:for-each>
</table>
</xsl:template>
</xsl:stylesheet>
Param.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="x" uri="http://java.sun.com/jsp/jstl/xml" %>
<html>
<head>
<title>x:transform Tag</title>
</head>
<body>
<h3>Novels Information:</h3>
<c:set var="xmltext">
<books>
<book>
<name>Three mistakes of my life</name>
<author>Chetan Bhagat</author>
<price>200</price>
</book>
<book>
<name>Tomorrow land</name>
<author>Brad Bird</author>
<price>1000</price>
</book>
<book>
<name>Wings of fire</name>
<author>Dr. APJ Abdul Kalam</author>
<price>500</price>
</book>
</books>
</c:set>
<c:import url="transfer.xsl" var="xslt"/>
<x:transform xml="${xmltext}" xslt="${xslt}">
<x:param name="bgColor" value="yellow"/>
</x:transform>
</body>
</html>
Formatting (I18N) Tag Library in JSTL:
The formatting tags provide support for message formatting, number and date formatting etc. The
url for the formatting tags is http://java.sun.com/jsp/jstl/fmt and prefix is fmt.
Example on <fmt:parseNumber>
<fmt:parseNumber> tag is used to parses the String representation of a currency, percentage or
number. It is based on the customized formatting pattern.
ParseNumber.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<html>
<head>
<title>fmt:parseNumber tag</title>
</head>
<body>
<h3>The fmt:parseNumber tag Example is:</h3>
<c:set var="Amount" value="786.970" />
<fmt:parseNumber var="j" type="number" value="${Amount}" />
<p><i>Amount is:</i> <c:out value="${j}" /></p>
<fmt:parseNumber var="j" integerOnly="true" type="number" value="${Amount}"
/>
<p><i>Amount is:</i> <c:out value="${j}" /></p>
</body>
</html>
Example on <fmt:timeZone>
The <fmt:timeZone> tag specifies the parsing action nested in its body or the time zone for any time
formatting. It is used for specify the time zone information used for time formatting operations.
TimeZone.jsp
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<html>
<head>
<title>fmt:timeZone Tag</title>
</head>
<body>
<c:set var="str" value="<%=new java.util.Date()%>" />
<table border="2" width="100%">
<tr>
<td width="100%" colspan="2" bgcolor="#FF7F50">
<p align="center">
<b>
<font color="#000000" size="6">Formatting:
<fmt:formatDate value="${str}" type="both"
timeStyle="long" dateStyle="long" />
</font>
</b>
</p>
</td>
</tr>
<c:forEach var="zone"
items="<%=java.util.TimeZone.getAvailableIDs()%>">
<tr>
<td width="50%" bgcolor="#C0C0C0">
<c:out value="${zone}" />
</td>
<td width="50%" bgcolor="#FFEBCD">
<fmt:timeZone value="${zone}">
<fmt:formatDate value="${str}" timeZone="${zn}"
type="both"/>
</fmt:timeZone>
</td>
</tr>
</c:forEach>
</table>
</body>
</html>
Example on <fmt:formatNumber>
The <fmt:formatNumber> tag is used to format the numerical value using the specific format or
precision. It is used to format percentages, currencies, and numbers according to the customized
formatting pattern.
FormatNumber.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
<html>
<head>
<title>fmt:formatNumber Tag</title>
</head>
<body>
<h3>Formatting of Number:</h3>
<c:set var="Amount" value="9850.14115" />
<p> Formatted Number-1:
<fmt:formatNumber value="${Amount}" type="currency" /></p>
<p>Formatted Number-2:
<fmt:formatNumber type="number" groupingUsed="true" value="${Amount}" /></
p>
<p>Formatted Number-3:
<fmt:formatNumber type="number" maxIntegerDigits="3" value="${Amount}" /><
/p>
<p>Formatted Number-4:
<fmt:formatNumber type="number" maxFractionDigits="6" value="${Amount}" /><
/p>
<p>Formatted Number-5:
<fmt:formatNumber type="percent" maxIntegerDigits="4" value="${Amount}" /></
p>
<p>Formatted Number-6:
<fmt:formatNumber type="number" pattern="###.###$" value="${Amount}" /><
/p>
</body>
</html>
Example on <fmt:parseDate>
The <fmt:parseDate> tag parses the string representation of a time and date. It is used to format the
time and date according to a customized formatting pattern.
ParseDate.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<html>
<head>
<title>fmt:parseDate Tag</title>
</head>
<body>
<h3>Parsed Date:</h3>
<c:set var="date" value="12-08-2016" />
<fmt:parseDate value="${date}" var="parsedDate" pattern="dd-MM-yyyy" />
<p><c:out value="${parsedDate}" /></p>
</body>
</html>
Example on <fmt:bundle>
The <fmt:bundle> tag loads the resource bundle which is used by its tag body. This tag will make the
specified bundle available for all <fmt:message> tags that occurs between the boundary of
<fmt:bundle> and </fmt:bundle> tags.
Simple.java
package com.package;
import java.util.ListResourceBundle;
public class Simple extends ListResourceBundle {
public Object[][] getContents() {
return contents;
}
static final Object[][] contents = { { "colour.Violet", "Violet" },
{ "colour.Indigo", "Indigo" }, { "colour.Blue", "Blue" }, };
}
Bundle.jsp
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<html>
<head>
<title>fmt:bundle Tag</title>
</head>
<body>
<fmt:bundle basename="com.ActiveNET.Simple" prefix="colour.">
<fmt:message key="Violet"/><br/>
<fmt:message key="Indigo"/><br/>
<fmt:message key="Blue"/><br/>
</fmt:bundle>
</body>
</html>
Example on <fmt:setTimeZone>
The <fmt:setBundle> tag is used to load the resource bundle and store their value in the bundle
configuration variable or the name scope variable.
Example on <fmt:setBundle>
The <fmt:setBundle> tag is used to load the resource bundle and store their value in the bundle
configuration variable or the name scope variable.
Main.java
package com.example;
import java.util.ListResourceBundle;
public class Main extends ListResourceBundle {
public Object[][] getContents() {
return contents;
}
static final Object[][] contents = { { "vegetable.Potato", "Potato" },
{ "vegetable.Tomato", "Tomato" }, { "vegetable.Carrot", "Carrot" }, };
}
SetBundle.jsp
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<html>
<head>
<title>fmt:setBundle Tag</title>
</head>
<body>
<fmt:setBundle basename="com.ActiveNET.Main" var="lang"/>
<fmt:message key="vegetable.Potato" bundle="${lang}"/><br/>
<fmt:message key="vegetable.Tomato" bundle="${lang}"/><br/>
<fmt:message key="vegetable.Carrot" bundle="${lang}"/><br/>
</body>
</html>
Example on <fmt:message>
The <fmt:message> tag is used for displaying an internationalized message. It maps the key of
localized message to return the value using a resource bundle specified in the bundle attribute.
Message.java
package com.example;
import java.util.ListResourceBundle;
public class Message extends ListResourceBundle {
public Object[][] getContents() {
return contents;
}
static final Object[][] contents = { { "vegetable.Potato", "Potato" },
{ "vegetable.Tomato", "Tomato" }, { "vegetable.Carrot", "Carrot" }, };
}
Message.jsp
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<html>
<head>
<title>fmt:message Tag</title>
</head>
<body>
<fmt:setBundle basename="com.ActiveNET.Message" var="lang"/>
<fmt:message key="vegetable.Potato" bundle="${lang}"/><br/>
<fmt:message key="vegetable.Tomato" bundle="${lang}"/><br/>
<fmt:message key="vegetable.Carrot" bundle="${lang}"/><br/>
</body>
</html>
Example on <fmt:formatDate>
The <fmt:formatDate> tag is used for different formats of date and time using the supplied pattern
and styles. It is used to format the time and date according to the customized formatting pattern.
FormatDate.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
<html>
<head>
<title>fmt:formatDate</title>
</head>
<body>
<h2>Different Formats of the Date</h2>
<c:set var="Date" value="<%=new java.util.Date()%>" />
<p>
Formatted Time :
<fmt:formatDate type="time" value="${Date}" />
</p>
<p>
Formatted Date :
<fmt:formatDate type="date" value="${Date}" />
</p>
<p>
Formatted Date and Time :
<fmt:formatDate type="both" value="${Date}" />
</p>
<p>
Formatted Date and Time in short style :
<fmt:formatDate type="both" dateStyle="short" timeStyle="short"
value="${Date}" />
</p>
<p>
Formatted Date and Time in medium style :
<fmt:formatDate type="both" dateStyle="medium" timeStyle="medium"
value="${Date}" />
</p>
<p>
Formatted Date and Time in long style :
<fmt:formatDate type="both" dateStyle="long" timeStyle="long"
value="${Date}" />
</p>
</body>
</html>
Functions Library
JSTL fn:contains() function
The fn:contains() is used for testing if the string containing the specified substring. If the specified
substring is found in the string, it returns true otherwise false.
Contains.jsp
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
<html>
<head>
<title>Using JSTL Functions</title>
</head>
<body>
<c:set var="String" value="Welcome to ActiveNET"/>
<c:if test="${fn:contains(String, 'ActiveNET')}">
<p>Found ActiveNET string<p>
</c:if>
<c:if test="${fn:contains(String, 'ACTIVENET')}">
<p>Found ACTIVENET string<p>
</c:if>
</body>
</html>
JSTL fn:containsIgnoreCase() function
The fn:containsIgnoreCase() function is used to test if an input string contains the specified substring
as a case insensitive way. During searching the specified substring it ignores the case.
ContainsIgnoreCase.jsp
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
<html>
<head>
<title>Using JSTL Functions</title>
</head>
<body>
<c:set var="String" value="Welcome to javatpoint"/>
<c:if test="${fn:containsIgnoreCase(String, 'javatpoint')}">
<p>Found javatpoint string<p>
</c:if>
<c:if test="${fn:containsIgnoreCase(String, 'JAVATPOINT')}">
<p>Found JAVATPOINT string<p>
</c:if>
</body>
</html>
JSTL fn:endsWith() function
The fn:endsWith() function is used for testing if an input string ends with the specified suffix. If the
string ends with a specified suffix, it returns true otherwise false.
EndsWith.jsp
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
<html>
<head>
<title>Using JSTL Functions</title>
</head>
<body>
<c:set var="String" value="Welcome to JSP programming"/>
<c:if test="${fn:endsWith(String, 'programming')}">
<p>String ends with programming<p>
</c:if>
<c:if test="${fn:endsWith(String, 'JSP')}">
<p>String ends with JSP<p>
</c:if>
</body>
</html>
JSTL fn:escapeXml() function
EscapeXml.jsp
The fn:escapeXml() function escapes the characters that would be interpreted as XML markup. It is
used for escaping the character in XML markup language.
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
<html>
<head>
<title>Using JSTL Functions</title>
</head>
<body>
<c:set var="string1" value="It is first String."/>
<c:set var="string2" value="It is <xyz>second String.</xyz>"/>
<p>With escapeXml() Function:</p>
<p>string-1 : ${fn:escapeXml(string1)}</p>
<p>string-2 : ${fn:escapeXml(string2)}</p>
<p>Without escapeXml() Function:</p>
<p>string-1 : ${string1}</p>
<p>string-2 : ${string2}</p>
</body>
</html>
JSTL fn:indexOf() function
The fn:indexOf() function return an index of string. It is used for determining the index of string
specified in substring.
IndexOfjsp
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
<html>
<head>
<title>Using JSTL Functions</title>
</head>
<body>
<c:set var="string1" value="It is first String."/>
<c:set var="string2" value="It is <xyz>second String.</xyz>"/>
<p>Index-1 : ${fn:indexOf(string1, "first")}</p>
<p>Index-2 : ${fn:indexOf(string2, "second")}</p>
</body>
</html>
JSTL fn:trim() function
The fn:trim() function removes the blank spaces from both the ends of a string. It mainly used for
ignoring the blank spaces from both the ends of string.
Trim.jsp
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
<html>
<head>
<title>Using JSTL Functions</title>
</head>
<body>
<c:set var="str1" value="Welcome to JSP programming "/>
<p>String-1 Length is : ${fn:length(str1)}</p>
<c:set var="str2" value="${fn:trim(str1)}" />
<p>String-2 Length is : ${fn:length(str2)}</p>
<p>Final value of string is : ${str2}</p>
</body>
</html>
JSTL fn:startsWith() function
The fn:startsWith() function test if an input string is started with the specified substring.
StartsWith.jsp
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
<html>
<head>
<title>Using JSTL Function</title>
</head>
<body>
<c:set var="msg" value="The Example of JSTL fn:startsWith() Function"/>
The string starts with "The": ${fn:startsWith(msg, 'The')}
<br>The string starts with "Example": ${fn:startsWith(msg, 'Example')}
</body>
</html>
JSTL fn:split() function The fn:split() function splits the string into an array of substrings. It is used for splitting the string into
an array based on a delimiter string.
Split.jsp
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
<html>
<head>
<title>Using JSTL Functions</title>
</head>
<body>
<c:set var="str1" value="Welcome-to-JSP-Programming."/>
<c:set var="str2" value="${fn:split(str1, '-')}" />
<c:set var="str3" value="${fn:join(str2, ' ')}" />
<p>String-3 : ${str3}</p>
<c:set var="str4" value="${fn:split(str3, ' ')}" />
<c:set var="str5" value="${fn:join(str4, '-')}" />
<p>String-5 : ${str5}</p>
</body>
</html>
JSTL fn:toLowerCase() function
The fn:toLowerCase() function converts all the characters of a string to lower case. It is used for
replacing any upper case character in the input string with the corresponding lowercase character.
ToLowerCase.jsp
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
<html>
<head>
<title> Using JSTL Function </title>
</head>
<body>
<c:set var="string" value="Welcome to JSP Programming"/>
${fn:toLowerCase("HELLO,")}
${fn:toLowerCase(string)}
</body>
</html>
JSTL fn:toUpperCase() function
The fn:toUpperCase() function converts all the characters of a string to upper case. It is used for
replacing any lower case character in the input string with the corresponding upper case character.
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
<html>
<head>
<title>Using JSTL Function </title>
</head>
<body>
<c:set var="site" value="javatpoint.com"/>
<c:set var="author" value="Sonoo Jaiswal"/>
Hi, This is ${fn:toUpperCase(site)} developed by ${fn:toUpperCase(author)}.
</body>
</html>
JSTL fn:substring() function The fn:substring() function returns the subset of a string. It is used to return the substring of given
input string according to specified start and end position.
SubString.jsp
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
<html>
<head>
<title>Using JSTL Function </title>
</head>
<body>
<c:set var="string" value="This is the first string."/>
${fn:substring(string, 5, 17)}
</body>
</html>
JSTL fn:substringAfter() function
The fn:substringAfter() function returns the subset of string followed by a specific substring. It
returns the part of string which lies after the provided string value.
SubStringAfter.jsp
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
<html>
<head>
<title>Using JSTL Function </title>
</head>
<body>
<c:set var="string" value="Nakul Jain"/>
${fn:substringAfter(string, "Nakul")}
</body>
</html>
JSTL fn:substringBefore() function The fn:substringBefore() function returns the subset of string before a specific substring. It is used
for returning a part of original string which lies before the specified string value.
SubStringBefore.jsp
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
<html>
<head>
<title>Using JSTL Function </title>
</head>
<body>
<c:set var="string" value="Hi, This is JAVATPOINT.COM developed by SONOO JAISWAL.
"/>
${fn:substringBefore(string, "developed")}
</body>
</html>
JSTL fn:length() function The fn:length() function returns the number of characters inside a string, or the number of items in a
collection. It is used for calculating the length of string and to find out the number of elements in a
collection.
Length.jsp
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
<html>
<head>
<title>JSTL fn:length() example</title>
</head>
<body>
<c:set var="str1" value="This is first string"/>
<c:set var="str2" value="Hello"/>
Length of the String-1 is: ${fn:length(str1)}<br>
Length of the String-2 is: ${fn:length(str2)}
</body>
</html>
JSTL fn:replace() function The fn:replace() function replaces all the occurrence of a string with another string sequence. It
search in an input string and replace it with the provided string.
Replace.jsp
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
<html>
<head>
<title>Using JSTL Function </title>
</head>
<body>
<c:set var="author" value="Ramesh Kumar"/>
<c:set var="string" value="pqr xyz abc PQR"/>
${fn:replace(author, "Ramesh", "Suresh")}
${fn:replace(string, "pqr", "hello")}
</body>
</html>