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.


Contents | Foreword | About the Authors | Introduction |
Appendix |Chapter 1 |Chapter 2 |Chapter 3 |Chapter 4 |Chapter 5 |Chapter 6 |
Chapter 7 |Chapter 8 |Chapter 9 |Chapter 10 |Chapter 11