© Yaron Kanza Advanced Java Server Pages Written by Dr. Yaron Kanza, Edited by permission from author by Liron Blecher
© Yaron Kanza
Advanced Java Server PagesWritten by Dr. Yaron Kanza, Edited by permission from author by Liron Blecher
Age
nda
• Java Beans in JSP
• Custom JSP tags - TagLib
• JSP Expression Language
Motivation
Software components (e.g. objects, data structures, primitives) are extensively used in Web applications
For example:Service local variablesAttributes forwarded in requestsSession attributes, such as user informationApplication attributes, such as access counters
See tutorial at http://docs.oracle.com/javase/tutorial/javabeans/
3
Motivation
Standard actions are used to manipulate components: declaration, reading from the suitable context, setting of new values (according to input parameters), storing inside the suitable context, etc.
Java Beans provide a specification for automatic handling and manipulation of software components in JSP (and other technologies...)
4
Java Beans: The Idea
Java Beans are simply objects of classes that follow some (natural) coding convention:
• An empty constructor• A readable property has a matching getter• A writable property has a matching setter
Use JSP actions to access and manipulate the bean, and special action attributes to specify the properties of the bean, e.g., its scope
JSP programmers do not wish to write cumbersome code or class files
5
Example 1: Access Counter
In the following example, we use a Bean to maintain an
access counter for requests to the pages
6
7
Counter Bean - CounterBean.java
package myUtils;
public class CounterBean {
private int counter;
public CounterBean() { counter = 0; }
public int getCounter() { return counter; }
public void setCounter(int i) { counter = i; }
public void increment() { ++counter; }
}
Bean must reside in a package
A Bean is created by an empty constructor
Counter setter and getter
Other methods can be implemented as well
A Bean is a concept and therefore there’s no need to extend any class or implement any interface!(though it would’ve been very Java-ish to create an empty interface “Bean”)
8
<html> <head><title>Bean Example</title></head><body>
<jsp:useBean id="accessCounter"
class=“myUtils.CounterBean" scope="application"/>
<% accessCounter.increment(); %>
<h1> Welcome to Page A</h1>
<h2>Accesses to this application:
<jsp:getProperty name="accessCounter" property="counter"/>
</h2>
<a href="pageB.jsp">Page B</a></body>
</html>
pageA.jsp
Invokes getCounter()
An instance named according to the given id is either found in the relevant scope or is created
The default scope is page
You could also use the type attribute in order to instantiate a data type which is either superclass of class or an interface that class implements
9
<html> <head><title>Bean Example</title></head><body>
<jsp:useBean id="accessCounter"
class=“myUtils.CounterBean" scope="application"/>
<% accessCounter.increment(); %>
<h1> Welcome to Page B</h1>
<h2>Accesses to this application:
<jsp:getProperty name="accessCounter" property="counter"/>
</h2>
<a href="pageA.jsp">Page A</a></body>
</html>pageB.jsp
A very similar JSP
Since an instance named according to the given id can be found in the application scope, no instantiation takes place
Counter Bean – cont.
10
Part of the Generated Servlet
myUtils.CounterBean accessCounter = null;
synchronized (application) {
accessCounter = (myUtils.CounterBean) _jspx_page_context.getAttribute("accessCounter",
PageContext.APPLICATION_SCOPE);
if (accessCounter == null) {
accessCounter = new myUtils.CounterBean();
_jspx_page_context.setAttribute("accessCounter",
accessCounter, PageContext.APPLICATION_SCOPE);
}
}Similar effect to getServletContext().setAttribute()
Similar effect to getServletContext().getAttribute()
The instance is created and kept in the application’s scope as required. Note however that accessing this instance is out of the synchronized scope
DEMO
counter
11
Example 2: Session Data
In the following example, we use a Bean in order to keep a user's details throughout the session
12
package myUtils;
public class UserInfoBean {
private String firstName;
private String lastName;
public UserInfoBean() { firstName = lastName = null;}
public String getFirstName() {return firstName;}
public String getLastName() {return lastName;}
public void setFirstName(String string) {firstName = string;}
public void setLastName(String string) {lastName = string;}
}
UserInfoBean.java
Example 2: Session Data – cont.
13
<html>
<head><title>Information Form</title></head>
<body>
<h1>Fill in your details:</h1>
<form action="infoA.jsp" method="get"><p>
Your First Name:
<input type="text" name="firstName" /> <br/>
Your Last Name:
<input type="text" name="lastName" /><br/>
<input type="submit" /></p>
</form>
</body></html>
infoForm.html14
Example 2: Session Data – cont.
<jsp:useBean id="userInfo" class=“myUtils.UserInfoBean" scope="session"/>
<jsp:setProperty name="userInfo" property="*"/>
<html>
<head><title>Page A</title></head><body>
<h1>Hello
<jsp:getProperty name="userInfo" property="firstName"/>
<jsp:getProperty name="userInfo" property="lastName"/>,
</h1>
<h1>Have a nice session!</h1>
<h2> <a href="infoB.jsp">User Info B</a></h2>
</body></html> infoA.jsp
Match all the request parameters to corresponding properties. You could match parameters to properties explicitly using property=… param=…
You can also set properties with explicit values using property=… value=…
The String values are converted to the right bean’s property types..
15
Example 2: Session Data – cont.
<jsp:useBean id="userInfo" class=“myUtils.UserInfoBean" scope="session"/>
<jsp:setProperty name="userInfo" property="*"/>
<html>
<head><title>Page B</title></head><body>
<h1>Hello
<jsp:getProperty name="userInfo" property="firstName"/>
<jsp:getProperty name="userInfo" property="lastName"/>,
</h1>
<h1>Have a nice session!</h1>
<h2> <a href="infoA.jsp">User Info A</a></h2>
</body></html> infoB.jsp
A very similar JSP
This time the request has no parameters so no bean properties are set
16
Example 2: Session Data – cont.
17
Advantages of Java Beans
Easy and standard management of data• Automatic management of bean sharing and lots more
Good programming style• Allow standard but not direct access to members• You can add code to the setters and getters (e.g. constraint
checks) without changing the client code• You can change the internal representation of the data without
changing the client code
Increase of separation between business logic (written by programmers) and HTML (written by GUI artists)
DEMO
session
18
Age
nda
• Java Beans in JSP
• Custom JSP tags - TagLib
• JSP Expression Language
Custom JSP Tags
JSP code may use custom tags – tags that are defined and implemented by the programmer
The programmer defines how each of the custom tags is translated into Java code
There are two methods to define custom tags:• Tag libraries - used in old versions of JSP• Tag files - much simpler, introduced in JSP 2.0
20
Tag Libraries
A tag library consists of:• Tag handlers - Java classes that define how each of the new
tags is translated into Java code • A TLD (Tag Library Descriptor) file, which is an XML file that
defines the structure and the implementing class of each tag• (see a tutorial at
http://java.sun.com/products/jsp/tutorial/TagLibrariesTOC.html)
21
Date Tag Example
package my;import javax.servlet.jsp.JspException;import javax.servlet.jsp.tagext.SimpleTagSupport;import java.io.IOException;public class DateTag extends SimpleTagSupport { public void doTag() throws JspException, IOException { getJspContext().getOut().print(new java.util.Date()); }}
DateTag.java
Using the JSP-context, You can also acquire other implicit objects by calling getSession(), getRequest() etc…
The class file is placed in webapps/myapp/WEB-INF/classes/my/
The java file is placed in webapps/myapp/WEB-INF/src/my/
Base class of tags which don’t handle the body or the attributes
We must use a package (not necessarily named like your application) since this is a helper class which is imported form the JSP’s generated Servlet that is placed within a named package
• Goal: <mytag:date/>
22
<taglib> <tlib-version>1.0</tlib-version><jsp-version>2.0</jsp-version> <tag> <name>date</name> <tagclass>my.DateTag</tagclass> <body-content>empty</body-content> </tag></taglib>
my-taglib.tld
Set this value that indicates your tag library version
Name of the tagTag’s class file in/myapp/WEB-INF/classes/my/This defined tag contains no body
23
Date Tag Example – cont.
<%@ taglib prefix=“mytag" uri="/WEB-INF/tags/my-taglib.tld" %><html><body> <h1>Hello. The time is: <mytag:date/></h1></body></html>
taglibuse.jsp
The prefix for this tag must appear before the tag itself (looks like a namespace).The Prefix can’t be empty
The path could be a URL.If you choose to use a local path, it must begin with /WEB-INF/tags/
You can add here more tags…
24
Date Tag Example – cont.
25
Taglib with Attributes
package my;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.TagSupport;
import java.io.IOException;
public class DateTag2 extends TagSupport {
private boolean isLongFormat = false;
public void setIsLongFormat(boolean b) {
isLongFormat = b; }
public boolean getIsLongFormat() {
return isLongFormat; {
DateTag2.java
Base class of tags which do handle attributes
the attribute is defined as not required so it must have a default value
Attribute’s setter methodAttribute’s getter method
This member’s name should be identical to the attribute’s.
The setter/getter methods should be named after the attribute (i.e. “get” + capital (<attribute>))
public int doStartTag() throws JspException { try {
if (isLongFormat) { pageContext.getOut().print(new java.util.Date().getTime()); } else { pageContext.getOut().print(new java.util.Date()); }
} catch (Exception e) { throw new JspException("DateTag: " + e.getMessage()); } return SKIP_BODY; } public int doEndTag() { return EVAL_PAGE; } }
Invoked when the generated Servlet starts processing the “start tag”
Prints the date according to the isLongFormat attribute
Signals the generated Servlet there’s no body within the tag to process
Invoked when the generated Servlet starts processing the “end tag”
Signals the generated Servlet to continue executing the generated Servlet code
26
<tag><name>date2</name><tagclass>my.DateTag2</tagclass><body-content>empty</body-content>
<attribute><name>isLongFormat</name><required>false</required>
</attribute></tag> my-taglib2.tld
<%@ taglib prefix=“mytag" uri="/WEB-INF/tags/my-taglib2.tld" %><html><body> <h1>Hello.</h1> <h2>The time is: <mytag:date2/></h2> <h2>Milliseconds since the epoch : <mytag:date2
isLongFormat="true" /></h2></body></html>
taglibuse2.jsp
Same as before, only with different names for the tagclass
You can put several blocks one after another
The attribute is “not required” so you have to define a default value in DateTag2.java
Uses default attribute value
Uses a given attribute value
27
28
How does it work?
taglibuse2.jsp
taglibuse2_jsp.java
JspContext
DateTag2
setIsLongFormat()
doStartTag()
doEndTag()
JSP to Java Servlet translation
Create the JspContextWhen the translation engine first encounters <mytag:date2> it creates a new instance of DateTag2 (so we needn’t worry about concurrency issues) and passes it the JspContext reference
The attribute value is set using the setter method.The translator actually translated the attribute string value as it appears in the JSP source, to a boolean value as the Java tag class expects it…
“Start tag” is reached
“End tag” is reached
Tag Files
JSP 2.0 provides an extremely simplified way of defining tags
The motivation: JSP programmers prefer not to write cumbersome code or class files
The idea: for each custom tag, write a tag file tagName.tag that implements the tag translation using JSP code
This way, the programmer can avoid creating tag handlers and TLD files
29
<%= new java.util.Date() %>
The Simplified Example
<%@ taglib prefix=“mytag" tagdir="/WEB-INF/tags/" %><html> <body> <h1>Hello. The time is: <mytag:date/></h1> </body></html>
date.tag
taguse.jsp
In this new mechanism we use tagdir instead of uri we used in the old taglib implementation
30
31
The Attributes Example<%@ attribute name="isLongFormat" required="false" %><%!private String createDate(String isLong) {
if ((isLong == null) || (isLong.equals("false"))) {return new java.util.Date().toString();}
else { return new Long(new java.util.Date().getTime()).toString();}} %><%=createDate(isLongFormat)%>
<%@ taglib prefix=“mytag" tagdir="/WEB-INF/tags/" %><html><body> <h1>Hello.</h1> <h2>The time is: <mytag:date3/></h2> <h2>Milliseconds since the epoch : <mytag:date3 isLongFormat="true" /></h2></body></html>
date3.tag
taguse3.jsp
Private method declaration
Default and isLongFormat=“false” case
Calls the private method
isLongFormat=“true” case
Default case
isLongFormat=“true”
A new directive
The isLongFormat parameter is identified as the isLongFormat attribute because we used the attribute directive
Other Capabilities of Custom Tags
Attributes• You can add validation mechanism for the attributes values
Tag Body• Tag translation may choose to ignore, include or change the tag
body
32
DEMO
taglib
33
Age
nda
• Java Beans in JSP
• Custom JSP tags - TagLib
• JSP Expression Language
JSP Expression Language
JSP expression language is a comfortable tool to access useful objects in JSP
This language provides shortcuts in a somewhat JavaScript-like syntax
An expression in EL is written as ${expr}
For example:
Hi, ${user}. <em style="${style}">Welcome</em>
Note that the EL expression does not violate the XML syntax as opposed to <%= expression %>
35
EL Variables
JSP EL does not recognize JSP's implicit objects, but rather has its own set
Each of these objects maps names to values• param, paramValues,• header ,headerValues,• cookie,• initParam, • pageScope, requestScope,• sessionScope, applicationScope
For example, use the param[“x”] or param.x to get the value of the parameter x
Map a parameter name to a single value or to multiple valuesMap a header name to a single value or to multiple valuesMaps a cookie name to a single valueMaps a context initialization parameter name to a single value
36
EL Variables (cont)
A variable that is not an EL implicit object is looked up at the page, request, session (if valid) and application scopes
That is, x is evaluated as the first non-null element obtained by executing pageContext.getAttribute("x"), request.getAttribute("x"), etc.
Might be confusing. Make sure you know what you’re accessing!
37
Object Properties
In JSP EL, Property prop of Object o is referred to as o[prop]
Property prop of Object o is evaluated as follows:• If o is a Map object, then o.get(prop) is returned • If o is a List or an array, then prop is converted into an integer
and o.get(prop) or o[prop] is returned• Otherwise, treat o “as a bean”, that is: convert p to a string, and
return the corresponding getter of o, that is o.getProp()
The term o.p is equivalent to o["p"]
38
An Example
<% response.addCookie(new Cookie(“nameof",“homer")); session.setAttribute(“homepage", new java.net.URL("http://www.simpsons.com")); String[] strs = {"str1","str2"}; session.setAttribute("arr", strs); %><html><head><title>JSP Expressions</title></head><body> <form method="get" action="el.jsp"> <h2>Write the parameter x: <input name="x" type="text" /> <input type="submit" value="send" /></h2> </form></body></html>
elcall.jsp39
<%@ page isELIgnored="false" %><html> <head><title>EL Examples</title></head> <h1>Expression-Language Examples</h1><h2>Parameter <code>x</code>: ${param["x"]} </h2> <h2>Cookie <code>name</code>: ${cookie.nameof.value}</h2> <h2>Header <code>Connection</code>: ${header.Connection} </h2><h2>Path of session attr. <code>homepage</code>: ${sessionScope.homepage.path}</h2> <h2>Element <code>arr[${param.x}]</code>: ${arr[param.x]} </h2></body></html>
el.jsp
The default value is TRUE
cookie[“nameof”].getValue()
header [“Connection”]
sessionScope[“homepage”].getPath(). You can omit the sessionScope
${…} means evaluate the expression inside the {}
Only the ${param.x} is evaluated
sessionScope[“arr”][param[“x”]
40
An Example