You are on page 1of 60

Initialization and

Communication
Contents

1 Problem?
2 Variable declarations and initializations
3 Initialization
4 ServletConfig
5 init param for a particular servlet
6 ServletContext
7 Methods of ServletContext
8 Setting values for context variable : variable global to all the web components

9 Servlet-Browser Communication
10 Status 2xx
Contents

11 Status 4xx
12 Status 5xx
13 Status 3xx
14 Redirect through Servlet to Servlet Communication
15 Ways
16 forward
17 include
18 javax.servlet.RequestDispatcher
19 Request Attributes
20 web.xml
Contents

21 Register Servlet
22 Success Servlet
23 Error Servlet
24 Connecting to a database
25 JDBC 2.0 optional package
26 DataSource
27 JNDI and DataSources
28 Steps to get Connection object from DataSource
29 Advantages
30 J2EE Application Server’s support for DataSource
contents

31 Connection Pooling
32 J2EE Application Servers support for Connection Pooling
33 Distributed Transactions
Know
• How initialization is done
• How servlet-browser and servlet-servlet
communciation work
• How to connect to databases
Be Able To
• Write servlets that interact with databases
Problem?
//assume imports
public class Getdate extends HttpServlet{
java.util.Date d=new java.util.Date();
public void doGet(HttpServletRequest req,
HttpServletResponse res) throws IOException,
ServletException{
java.io.PrintWriter out=res.getWriter();
out.println("<html><body>Right now the date
and time of the server is "+ d);
out.println("</body></html>");}}

What is it that this code is


trying to achieve? Do
think it will achieve it?
Same date gets printed for all
users!
I will initialize ‘d’ in the doGet()
method to solve this problem.

Alright. Since you are printing


the date immediately and not
using it any more, it seems to
work ok. However, consider
the case when you want to
insert the date into the
database and then use it for
some calculation. While the
insertion operation for user1
takes place what happens if
another user invokes the
same servlet?
Variable declarations and
initializations
• The variables that are declared as part of a servlet will
be shared by all the users since there is only one
servlet instance created by the server.
• Therefore we must be careful about the variable
declaration. If shared variables are changed then it
should be done in thread-safe manner.

Where would you


declare username
and password
variables?
Static or non static variable
does not make any
difference to the servlet
since there is only one
instance of a servlet.

But why should there be


only one instance of a
servlet? I am not sure…
have we seen this
before?
We are learning servlet 2.4. Older
versions of the servlet API had a
interface called SingleThreadModel
that made sure a single instance
of servlet is created for every user.
This interface is deprecated in 2.4
version!
Initialization
• In a java class, initialization is normally done in
the constructor. But that is not the case with a
servlet class.
• Why?

We have talked
about this
before… for sure!!
Initialization
• Servlet instance variables are initialized in
init().
• The ServetConfig object is a configuration
object used by a servlet container to pass
information to a servlet during initialization. Most of
the time this information will be required to
initialize variables.
• There are two ways to initialize:
Override init(ServletConfig config)
Override init()and get config object
using getServletConfig() method(of
Servlet interface)
ServletConfig
• This object is used to fetch the initialization
parameters for individual servlets.
• This object is passed on by the application server
to the servlet during initialization when
init(ServletConfig) method is called.
ServletConfig
• Getting ServletConfig object:
ServletConfig getServletConfig() method in
Servlet interface

• Methods to get init parameters:


public String getInitParameter(String name)
of ServletConfig

• GenericServlet class also provides the same method as the


above. It indirectly calls the method above.
init param for a particular servlet
<servlet>
<servlet-name>servlet-name</servlet-name>
<init-param>
<param-name>param-name</param-name>
<param-value>param-value</param-value>
</init-param>

</servlet>
In servlet servlet-name :
String var-name=getInitParameter(“param-name”);
Question?

If one could initialize


variables in web.xml
then one could have
done the same in the
servlet class itself!
So what difference
does it make if this is
done in the DD?
ServletContext
• This object is global to all servlets and jsps in an
application context.
• It is used to set and get variables that are global
application variables.
• It is also used by the servlet to get info about the
servlet engine this servlet is running and info about
other servlets.
ServletContext
• Getting ServletContext
• ServletContext getServletContext()
method of HttpServlet
or
• Initialize an instance of cxt by overriding
init(ServletContext) method.
Methods of ServletContext
• String getInitParameter(String name)
• void setAttribute(String name,Object
obj)
• Object getAttribute(String name)
• void removeAttribute(String name)
Setting values for context variable :
variable global to all the web
components
<web-app>

<context-param>
<param-name>param-name
</param-name>
<param-value>param-value
</param-value>
</context-param>
</web-app>
In any servlet in of the current application:
ServletContext ctx=getServletContext();
String value=ctx.getInitParameter(“param-
name”);
Example
<web-app>
<display-name>Init Params</display-name>
<servlet>
<servlet-name>Colors</servlet-name>
<servlet-class>Colors</servlet-class>
<init-param>
<param-name>title</param-name>
<param-value>Add Employee</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>Colors</servlet-name>
<url-pattern>/display.do</url-pattern>
</servlet-mapping>

<context-param>
<param-name>color</param-name>
<param-value>red</param-value>
</context-param>
</web-app>
init
public class Colors extends
javax.servlet.http.HttpServlet{
public void
doGet(javax.servlet.http.HttpServletRequest req,
javax.servlet.http.HttpServletResponse res)
throws java.io.IOException,
javax.servlet.ServletException{
java.io.PrintWriter out=res.getWriter();
out.println("<html>");
String title=getInitParameter("title");
String
color=getServletContext().getInitParameter("color")
;
out.println("<body bgcolor='"+color+"'>");
out.println("<h1>"+title+"</h1>");
out.println("</body></html>");
}}
Servlet-Browser Communication
Status 2xx

GET Request for servlet s1


s1
Response packet
HTTP/1.1 200 OK
header

Client Server
<html>
…</html body HTTP status code
2xx indicating
the requested
resource is
available.
Status 4xx

GET Request for servlet s2


s1
Response packet
HTTP/1.1 404 NOT FOUND
header

Client Server
body
HTTP status code
4xx indicating
the requested
resource is not
available.
doPost(
Status 5xx ) not
defined!

POST Request for servlet s1


s1
Response packet
HTTP/1.1 500 Internal Server Error

Client Server

HTTP status code


5xx server error.
In this case the
request is made
for the method
not defined in
the servlet.
Status 3xx
• HttpServletResponse has method called
sendRedirect(String url)
• This method sends a temporary redirect
response to client with status code 3xx.
Location specifies the URL page to which the
redirection is going to be.
• Usage:
response.sendRedirect(“http://local
host:8080/direct/s?name=‘Harry
Potter’”)
public class S1{

HTTP status code response.sendRedirect
3xx indicating (“http://pondser/app2);
the redirect …
}

Request for servlet S1


S1
Response packet
HTTP/1.1 307 Temporary Redirect

Client Server

Request for http://pondser/app2

PondServer
Redirect through Servlet to
Servlet Communication
Ways
• Two servlets (or JSPs) can communicate with
each other.
• There are two ways in which the communicate
can happen based on where the control is finally
going to be:
– forward
– include
forward request
response
GET Request for servlet S1
S1
forward

S2

Calls doGet() method of S2.


If the request was for POST,
then
doPost() of S2 gets called.
Control finally is in S2. Response is generated by S2
include request
response
GET Request for servlet S1
S1
include

S2
Calls doGet() method of S2.
If the request was for POST, then
doPost() of S2 gets called.

Control finally is in S1. Response is generated by S1


javax.servlet.RequestDispatcher
• RequestDispatcher is an interface that has methods to
forward or include.
• void forward(ServletRequest request,
ServletResponse response)
• void include(ServletRequest request,
ServletResponse response.
• RequestDispatcher instance is obtained through
– ServletContext or ServletRequest method-
RequestDispatcher
getRequestDispatcher(String path)
or
– ServletContext methodw.r.t. to <url-pattern>
RequestDispatcher
getNamedDispatcher(String name)
w.r.t. to <servlet-name>
Question?
You could create an instance
of servlet S2 from servlet S1
and call doGet() or doPost()
directly. Why do you then
require a
RequestDispatcher ?
Request Attributes
• Request and Response objects are shared
between the servlets when they communicate.
Needless to say that form parameters etc. will be
accessible by both the servlets.
• In addition to this, request object can be used to
send additional data to the a servlet or a JSP while
forwarding (or including).
• HttpSessionRequest methods that allow this:
– Object getAttribute(String name)
– void setAttribute(String name ,
Object obj)
– void removeAttribute(String name)
Example
<html><head><title>Register</title></head>
<body>
<h2>Register</h2>
<table border=1><tr><td>
<form method=post action="register">
Name:<input type=text name=name>
Email:<input type=text name=email>
<input type=submit></form>
</body>
</html> On submitting this form, a servlet is
invoked that checks for the validity of
data. If the data is invalid, the same form
is displayed with an error message,
otherwise another servlet is invoked that
displays a friendly message.
web.xml
<web-app>
<display-name>Register</display-name>
<servlet>
<servlet-name>Register</servlet-name>
<servlet-class>Register</servlet-class>
</servlet>

<servlet>
<servlet-name>Success</servlet-name>
<servlet-class>Success</servlet-class>
</servlet>

<servlet>
<servlet-name>Failure</servlet-name>
<servlet-class>Error</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Register</servlet-name>
<url-pattern>/register.do</url-pattern>
</servlet-mapping>

<servlet-mapping>
<servlet-name>Success</servlet-name>
<url-pattern>/success.do</url-pattern>
</servlet-mapping>

<servlet-mapping>
<servlet-name>Failure</servlet-name>
<url-pattern>/error.do</url-pattern>
</servlet-mapping>

</web-app>
Register Servlet
// assume imports
public class Register extends HttpServlet {
public void doPost(HttpServletRequest
request,HttpServletResponse response)
throws IOException, ServletException {
PrintWriter out = response.getWriter();

String name=request.getParameter("name");
String email=request.getParameter("email");

if( (name!=null && name.trim().length()!=0) &&


(email!=null && email.trim().length()!=0))
request.getRequestDispatcher("success.do").for
ward(request,response);
else{
request.setAttribute("error","Name or
email not entered");

request.getRequestDispatcher("error.do").inc
lude(request,response);

request.getRequestDispatcher("index.html").i
nclude(request,response);
}

}}
Success Servlet
//assume imports
public class Success extends HttpServlet {
public void doPost(HttpServletRequest request,
HttpServletResponse response) throws
IOException, ServletException {
PrintWriter out = response.getWriter();
try{
response.setContentType("text/html");
out.println("<html><head><title>Success
</title>");
out.println("<head><body>");
out.println("Thanks <I>
"+request.getParameter("name")+"</I>" );

out.println("<BR>For further details we will


contact in the email-id
<B>"+request.getParameter("email")+"</B>");

out.println("</body></html>");
}catch(Exception e){
out.println(e.toString()); }}
}
Error Servlet
public class Error extends HttpServlet {
public void doPost(HttpServletRequest
request,HttpServletResponse response)
throws IOException, ServletException{
PrintWriter out = response.getWriter();
try{
response.setContentType("text/html");
out.println("<html><head><title>login
</title>");
out.println("<head><body><font
color=red><b>");
String
err=(String)request.getAttribute("error");
String
login=request.getParameter("login");
if(err!=null)
out.println(err);

out.println("</font><b><br></body></html>");
}catch(Exception
e){out.println(e.toString());
}
}
}
Connecting to a database
• We can connect to database from our servlet in
two ways:
JDBC 2.0 core package
(same as JDBC 1.0)
a. using traditional methods
b. using DataSources
Better way!

Having seen this in detail in JDBC, we wil


just look at an example here.
JDBC 2.0 Optional package
Example using traditional
methods
public void doGet(...){
try{
String url
="jdbc:oracle:thin:@deepa.:1521:sample";
Class.forName("oracle.jdbc.OracleDriver");

Connection con =
DriverManager.getConnection(url,"SYSTEM","
admin");
Statement stmt=con.createStatement();
ResultSet rs = stmt.executeQuery("SELECT
name, id FROM student");
JDBC 2.0 optional package
• javax.sql package
• Includes the following:
DataSource interface
Connection Pooling
Distributed Transactions
RowSet

They have the same functionality as ResultSet.


In addition, RowSet is implemented as a JavaBean
Details of RowSet is beyond the scope of our
discussions! So with this bit on RowSet we stop.
DataSource
• DataSource interface is used as an alternative
to DriverManager of JDBC 2.0 core package.
• It makes the application more portable and makes
the code easier to maintain.
• A DataSource object refers to the real world
data source (relational database or spreadsheet
etc.)
• DataSource object is created (typically by an
application server) when the details like the URL
of the data source and the Driver name is
provided.
JNDI and DataSources
• DataSource object thus created is then
registered with a JNDI naming service (which
maps the DataSource object with a name).
• Once this is done, any application can retrieve
the DataSource object from the JNDI naming
service by providing the name.
• Once the DataSource is obtained, the
Connection object can be created and from
then on the code can work with JDBC 2.0 core
package as usual.
Steps to get Connection object
from DataSource
Step 1: Get the DataSource object
Context ctx=new InitialContext();
DataSource ds= (DataSource )
ctx.lookup(“jdbc/MyDSName”);
Step 2: Get the connection object
Connection con=
ds.getConnection(“usernam”,”password
”);
Advantages
• Portability: Since the information such as the
URL of the data source location, Driver class
name is not hard-coded in the application, it
makes the application independent of
database (or data source) vendor.
• Easy Maintenance: If the url of data source
changes then it just involves making one
change in data source configuration.
Application need not be touched at all!
• Connection Pooling

Coming up !
J2EE Application Server’s support
for DataSource
• J2EE Application Server comes with some JNDI
naming and directory services (LDAP Server
etc.).
• Most Application Servers provide a tool that
allows application developers or administrators
to configure DataSources to this JNDI service.
• Advantage with this is that the application
developer can defer the decision of which
database to use until the deployment time!
Connection Pooling
• Connection Pooling is a mechanism whereby a
collection of connection objects is maintained
by the application
• Each time application requires a Connection
object, it gets it from the pool.
• In other words, when an application closes a
connection, that connection is recycled rather
than being destroyed
– improves performance
J2EE Application Servers support
for Connection Pooling
• Most application servers implement
DataSource interface that supports connection
pooling.
• Therefore when you get connection form Data
Source instance, you get it from the pool and
when you close it, the connection goes back to
the pool.
J2EE Application Servers support
for Connection Pooling
• The size of the connection pool depends on the
application server.
• Application servers also provide a tool where
this size can be configured.
How does Connection pooling
improve performance?

Establishing connection is an
expensive operation. If connection
to a data source is required
throughout the application, it is
wise to retain and reuse the same
connection object. In a web
application (where many clients
request at the same time) it makes
sense to create a pool of
connection objects and reuse
these!
Distributed Transactions
• From an application developer’s point of view
there is no difference between Connection
obtained by the DataSource object and the
DriverManager except in case of transactions.
• With Connection object obtained from
DataSource, distributed transaction is
automatically supported.
• Therefore the application using Connection
object obtained from DataSource cannot call
commit or rollback methods directly.
Example using DataSource to
connect to Oracle

You might also like