[jdbc, servlets, jsp, jstl]activenet ® adv java [jdbc, servlets, jsp, jstl] by suryanarayana #202,...

157
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] [email protected]

Upload: others

Post on 11-Mar-2020

72 views

Category:

Documents


8 download

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]

[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 &amp; 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>