8.
Java Beans and Java Server Pages
Introduction
The word Java Beans
conjures up images of Coffee Beans or even Beanbags, but the Java Beans that we
are talking about are related to Java.
Java beans play a
large role in JSP documents. A Java Bean is a Java component that works on any
Java Virtual Machine.
Packages
If you had a class
called Applet and if another user also called his class Applet, then whose
Applet gets called, yours or his? To prevent a name clash, sun invented the
concept of a package. They said that all classes created by Sun would start
with java. Unfortunately this does
nothing for a grouping. We would like all classes that deal with GUI issues to
be grouped together. Thus we have one more level i.e. all GUI classes are part
of java.awt and applet classes are a part of java.applet. Hence the full name
of the class Applet is java.applet.Applet and java.applet is the package name
which can be part of the import statement.
Beans
Before we get down to
telling you what beans are, we would like you to do the following:
We want you to change
to c:\jswdk-1.0.1\examples\web-inf\jsp and there you will find a subdirectory
called beans. Within this directory, create a subdirectory called yyy. Now
create a file called zzz.java and enter the code given below.
C:\jswdk-1.0.1\examples\web-inf\jsp\beans\yyy>edit zzz.java
zzz.java
package yyy;
public class zzz {
private String username = “mukhi”;
public zzz()
{
System.out.println(“Constructor”);
}
public void setusername(String name) {
username = name;
System.out.println(“setusername “ + username);
}
public String getusername() {
System.out.println(“getusername” + username);
return username;
}
}
C:\jswdk-1.0.1\examples\web-inf\jsp\beans\yyy>javac zzz.java
Since the first line
is package yyy, in the beans directory you must create a subdirectory named
yyy. The reason being, for the compiler to find packages, all the files that
hold the classes contained in a package must reside in a directory bearing the
package name.
A Java Bean is a normal
program. As we’ve seen in the previous chapter,it is a simple Java program; an
applet can also be called a Java Bean. The only difference is that in a Bean
some functions start with either a set
or get, which is why we have setusername and getusername. Whenever a function
begins with set or get, it relates to a property. That’s what a Java Bean is made up of.
The property here is
username and not setusername or getusername. A variable or a property can
either be used on the left or the right of the = sign. If it is on the left,
then it gets a value, hence it takes one string as a parameter. Once you
receive the value, what you do with it is up to you. In our program we store it
in a public variable. Get is used with functions. When it is on the right hand
side of the = sign, it returns a value and hence we are returning a string.
C:\jswdk-1.0.1\examples\jsp>edit b1.jsp
b1.jsp
<jsp:useBean id=”pp” scope=”page” class=”yyy.zzz” />
<html>
<body>
</body>
</html>
b1.jsp has an action
called useBean followed by id=pp. pp is the id, we will use it to refer to our
bean in the future. The actual name can be anything and there is nothing
special about pp and class=yyy.zzz is because our bean zzz is in a package yyy.
It is assumed that the bean will be in the sub-directory
C:\jswdk-1.0.1\examples\web-inf\jsp\beans\
and the package yyy starts from this beans subdirectory onwards.
Run the jsp file in
the browser as before.
You get no errors.
Check the dos screen of the Java Web Server where it will print ‘Constructor’
and then let’s look at the generated code.
-----------------
// begin [file=”C:\\jswdk-1.0.1\\examples\\jsp\\b1.jsp”;from=(0,0);to=(0,52)]
// end
// begin [file=”C:\\jswdk-1.0.1\\examples\\jsp\\b1.jsp”;from=(0,0);to=(0,52)]
yyy.zzz pp = null;
boolean _jspx_specialpp = false;
synchronized (pageContext) {
pp= (yyy.zzz)pageContext.getAttribute(“pp”,PageContext.PAGE_SCOPE);
if ( pp == null ) {
_jspx_specialpp = true;
try {
pp = (yyy.zzz) Beans.instantiate(getClassLoader(), “yyy.zzz”);
} catch (Exception exc) {
throw new ServletException (“ Cannot create bean of class “+”yyy.zzz”);
}
pageContext.setAttribute(“pp”, pp, PageContext.PAGE_SCOPE);
}
}
if(_jspx_specialpp == true) {
// end
// begin [file=”C:\\jswdk-1.0.1\\examples\\jsp\\b1.jsp”;from=(0,0);to=(0,52)]
}
// end
out.print(_jspx_html_data[1]);
----------------------
pp looks like yyy.zzz
where yyy is the name of the package and zzz the name of the class. This is
because in the JSP file the id was given as pp. pageContext has members like
getAttribute, setAttribute and so on. pp is initialized using the getAttribute
function. The second parameter is PageContext.PAGE_SCOPE, since that is what we
had given in the JSP file. The next thing that you do is check if pp has a value.
If it is Null, then Beans.instantiate will instantiate or create the bean. That means if the Bean is already
loaded then you get a handle to it, if not then it is created. Instantiate is a
static member in the Beans class. One of the parameters is the name of the
Bean. We have given a very short explanation here; let’s look at the next
example to understand a lot more on Beans with JSP.
zzz.java
package yyy;
public class zzz {
private String username = “mukhi”;
public zzz()
{
System.out.println(“Constructor”);
}
public void setusername(String name) {
username = name;
System.out.println(“setusername “ + username);
}
public String getusername() {
System.out.println(“getusername” + username);
return username;
}
}
b2.jsp
<jsp:useBean id=”pp” scope=”page” class=”yyy.zzz” />
<html>
<body>
hello , <jsp:getProperty name=”pp” property=”username” />
</body>
<html>
Output in browser
hello , mukhi
In the next example,
we have a new action named getProperty with a name and a property. In our JSP
file the property is username. This line will be replaced by the word mukhi.
Look in the dos window and you’ll see that the function getusername is called.
This function returns the value of the variable username which is initialized
to mukhi. Thus the tag <jsp:getProperty name=”pp” property=”username” />
is replaced by the string mukhi.
--------------
// begin [file=”C:\\jswdk-1.0.1\\examples\\jsp\\b2.jsp”;from=(3,8);to=(3,57)]
out.print(JspRuntimeLibrary.toString(pp.getusername()));
// end
----------------
getproperty in the
java generated code will become pp.getusername. setproperty is a function which
is related to getproperty and is used in the next example.
b3.jsp
<%@ page import=”yyy.zzz” %>
<jsp:useBean id=”pp” scope=”page” class=”yyy.zzz” />
<html>
<body>
hello, <jsp:getProperty name=”pp” property=”username” />
<jsp:setProperty name=”pp” property=”username” value=”no” />
<p> hi, <jsp:getProperty name=”pp” property=”username” />
</body>
</html>
Output in browser
hello, mukhi
hi, no
----------
// begin [file=”C:\\jswdk-1.0.1\\examples\\jsp\\b3.jsp”;from=(5,0);to=(5,60)]
pp.setusername(“no”);
// end
out.print(_jspx_html_data[4]);
// begin [file=”C:\\jswdk-1.0.1\\examples\\jsp\\b3.jsp”;from=(6,8);to=(6,57)]
out.print(JspRuntimeLibrary.toString(pp.getusername()));
// end
-----------
With setusername, you
give the name of the property and then the value. The value given here is ‘no’.
So you see mukhi and then no. The code is exactly the same. setusername is also
called with the parameter having a value no and we initialize username with it.
Scopes
Let’s talk about
scopes in greater detail.
There are four scopes,
request, page, session and application. Each time you give the scope as session
or request, the PageContext variable changes.
b4.jsp
<jsp:useBean id=”pp” scope=”session” class=”yyy.zzz” />
-------------
java file
synchronized (session) {
pp= (yyy.zzz)
pageContext.getAttribute(“pp”,PageContext.SESSION_SCOPE);
if ( pp == null ) {
_jspx_specialpp = true;
try {
pp = (yyy.zzz) Beans.instantiate(getClassLoader(), “yyy.zzz”);
} catch (Exception exc) {
throw new ServletException (“ Cannot create bean of class “+”yyy.zzz”);
}
pageContext.setAttribute(“pp”, pp, PageContext.SESSION_SCOPE);
}
------------------
With scope as session, pageContext.getAttribute
and setAttribute will have PageContext.SESSION_SCOPE.
b5.jsp
<jsp:useBean id=”pp” scope=”request” class=”yyy.zzz” />
-------------
java file
synchronized (request) {
pp= (yyy.zzz) pageContext.getAttribute(“pp”,PageContext.REQUEST_SCOPE);
if ( pp == null ) {
_jspx_specialpp = true;
try {
pp = (yyy.zzz) Beans.instantiate(getClassLoader(), “yyy.zzz”);
} catch (Exception exc) {
throw new ServletException (“ Cannot create bean of class “+”yyy.zzz”);
}
pageContext.setAttribute(“pp”, pp, PageContext.REQUEST_SCOPE);
}
-----------
With the scope as
request, pageContext.getAttribute and setAttribute will have
PageContext.REQUEST_SCOPE.
Now we will consider
two programs at a time b6.jsp and b7.jsp.
b6.jsp
<%@ page import=”yyy.zzz” %>
<jsp:useBean id=”pp” scope=”request” class=”yyy.zzz” />
<html>
<body>
b6 , ello, <jsp:getProperty name=”pp” property=”username” />
<jsp:setProperty name=”pp” property=”username” value=”no” />
<p> llo, <jsp:getProperty name=”pp” property=”username” />
<a href=”b7.jsp”> click here </a>
</body>
</html>
b7.jsp
<%@ page import=”yyy.zzz” %>
<jsp:useBean id=”pp” scope=”request” class=”yyy.zzz” />
<html>
<body>
b7 , ello, <jsp:getProperty name=”pp” property=”username” />
<jsp:setProperty name=”pp” property=”username” value=”no” />
<p> llo, <jsp:getProperty name=”pp” property=”username” />
</body>
</html>
Here, we have two JSP
files, b6 and b7. We are using the same Bean in both of them and the scope is
request. The first file contains <a href=”b7.jsp”> which will take us to
the second page i.e. b7.jsp.
When we click on the
first page, yyy.zzz gets created, and the constructor is called. When we click
on href, we move to b7. Since the scope in both is request, the constructor is
called once more. The values are reinitialized and the variables are created
from scratch.
In this case, the page
behaves like request. The bean is created each time, which means that it cannot
remember its earlier values.
Let’s see an example
where we give the scope as session.
b8.jsp
<%@ page import=”yyy.zzz” %>
<jsp:useBean id=”pp” scope=”session” class=”yyy.zzz” />
<html>
<body>
b8 , <jsp:getProperty name=”pp” property=”username” />
<jsp:setProperty name=”pp” property=”username” value=”no” />
<p> llo, <jsp:getProperty name=”pp” property=”username” />
<a href=”b9.jsp”> click here </a>
</body>
</html>
b9.jsp
<%@ page import=”yyy.zzz” %>
<jsp:useBean id=”pp” scope=”session” class=”yyy.zzz” />
<html>
<body>
b9 , ello, <jsp:getProperty name=”pp” property=”username” />
<jsp:setProperty name=”pp” property=”username” value=”no” />
<p> llo, <jsp:getProperty name=”pp” property=”username” />
</body>
</html>
Here, the constructor
is called only once and that happens when the Bean is loaded for the first
time. When you click on the link, the constructor is not called. The Bean is
not instantiated and the variables are not created again. They are persistent
for that entire session. If you start a new browser, then a new session is
created.
When you give the
scope as application, then the Bean and the variables retain their values till
the server is shut down. Any client coming from any other site will see the
values as they are on the server. It’s like a page counter that keeps
increasing on every visit to the page.
Try it out with
another copy of IE to understand it better.
pageContext.getAttribute
decides, depending upon the scope, whether the Bean should be instantiated or
not. You decide on the scope depending upon the functionality of the JSP code.
If the page scope is application, then everybody will be able to use it
forever, but in case of session, it depends upon how you want to share the
Bean.
Conclusion
In this chapter we
have shown you how Java Server Pages receive from and send data to Java Beans.
At the same time we also showed you how to create your own package. You are now
also aware that setting the scope to the four different options will generate
different results.