Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
Advanced Java Server Pages Written by Dr. Yaron Kanza, Edited by permission from author by Liron Blecher © Yaron Kanza Agenda • 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 variables Attributes forwarded in requests Session attributes, such as user information Application attributes, such as access counters 3 See tutorial at http://docs.oracle.com/javase/tutorial/javabeans/ 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 Counter Bean - CounterBean.java package myUtils; A Bean is a concept and therefore there’s no need to extend any class or implement any interface! Bean must reside in a package public class CounterBean { (though it would’ve been very Java-ish to create an empty interface “Bean”) private int counter; public CounterBean() { counter = 0; } public int getCounter() { return counter; } public void setCounter(int i) { counter = i; } A Bean is created by an empty constructor public void increment() { ++counter; } } Other methods can be implemented as well 7 Counter setter and getter <html> An instance named according to the given id is <jsp:useBean id="accessCounter" either found in the relevant class=“myUtils.CounterBean" scope="application"/> scope or is created <head><title>Bean Example</title></head><body> 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 The default scope is page <% accessCounter.increment(); %> <h1> Welcome to Page A</h1> Invokes getCounter() <h2>Accesses to this application: <jsp:getProperty name="accessCounter" property="counter"/> </h2> <a href="pageB.jsp">Page B</a></body> </html> pageA.jsp 8 Counter Bean – cont. <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: Since an instance named according to the given id can be found in the application scope, no instantiation takes place <jsp:getProperty name="accessCounter" property="counter"/> </h2> <a href="pageA.jsp">Page A</a></body> </html> pageB.jsp A very similar JSP 9 Part of the Generated Servlet myUtils.CounterBean accessCounter = null; synchronized (application) { 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 accessCounter = (myUtils.CounterBean) _jspx_page_context.getAttribute("accessCounter", PageContext.APPLICATION_SCOPE); Similar effect to getServletContext().getAttribute() accessCounter = new myUtils.CounterBean(); if (accessCounter == null) { _jspx_page_context.setAttribute("accessCounter", accessCounter, PageContext.APPLICATION_SCOPE); } } 10 Similar effect to getServletContext().setAttribute() counter DEMO 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 Example 2: Session Data – cont. 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 13 Example 2: Session Data – cont. <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.html 14 Example 2: Session Data – cont. <jsp:useBean id="userInfo" class=“myUtils.UserInfoBean" scope="session"/> <jsp:setProperty name="userInfo" property="*"/> The String values are converted to the right bean’s property types.. <html> <head><title>Page A</title></head><body> <h1>Hello <jsp:getProperty name="userInfo" property="firstName"/> Match all the request parameters to corresponding properties. You could match parameters to properties explicitly using property=… param=… <jsp:getProperty name="userInfo" property="lastName"/>, You can also set properties with </h1> explicit values using property=… value=… <h1>Have a nice session!</h1> <h2> <a href="infoB.jsp">User Info B</a></h2> </body></html> 15 infoA.jsp Example 2: Session Data – cont. <jsp:useBean id="userInfo" class=“myUtils.UserInfoBean" scope="session"/> <jsp:setProperty name="userInfo" property="*"/> <html> This time the request has no parameters <head><title>Page B</title></head><body> so no bean properties are set <h1>Hello <jsp:getProperty name="userInfo" property="firstName"/> <jsp:getProperty name="userInfo" property="lastName"/>, </h1> A very similar JSP <h1>Have a nice session!</h1> <h2> <a href="infoA.jsp">User Info A</a></h2> </body></html> 16 infoB.jsp 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) 17 session DEMO 18 Agenda • 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 • Goal: <mytag:date/> The java file is placed in webapps/myapp/WEB-INF/src/my/ 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 The class file is placed in package my; webapps/myapp/WEB-INF/classes/my/ import javax.servlet.jsp.JspException; import javax.servlet.jsp.tagext.SimpleTagSupport; import java.io.IOException; Base class of public class DateTag extends SimpleTagSupport { tags which public void doTag() throws JspException, IOException { don’t handle getJspContext().getOut().print(new java.util.Date()); the body or the attributes } } Using the JSP-context, You can also acquire other implicit objects by calling getSession(), getRequest() etc… 22 DateTag.java Date Tag Example – cont. Set this value that indicates your <taglib> tag library version <tlib-version>1.0</tlib-version><jsp-version>2.0</jsp-version> <tag> <name>date</name> Name of the tag <tagclass>my.DateTag</tagclass> Tag’s class file in /myapp/WEB-INF/classes/my/ <body-content>empty</body-content> </tag> This defined tag contains no body </taglib> my-taglib.tld 23 Date Tag Example – cont. You can add here more tags… The prefix for this tag must appear before the tag itself (looks like a namespace). The Prefix can’t be empty <%@ taglib prefix=“mytag" uri="/WEB-INF/tags/my-taglib.tld" %> <html><body> <h1>Hello. The time is: <mytag:date/></h1> </body></html> The path could be a URL. If you choose to use a local path, it must begin with /WEB-INF/tags/ taglibuse.jsp 24 Taglib with Attributes package my; Base class of tags which do handle attributes import javax.servlet.jsp.JspException; import javax.servlet.jsp.tagext.TagSupport; import java.io.IOException; public class DateTag2 extends TagSupport { private boolean isLongFormat = false; The setter/getter methods should be named after the attribute (i.e. “get” + capital (<attribute>)) public void setIsLongFormat(boolean b) { the attribute is defined as not required so it must have a default value This member’s name should be identical to the attribute’s. isLongFormat = b; } public boolean getIsLongFormat() { return isLongFormat; { 25 Attribute’s setter method Attribute’s getter method DateTag2.java public int doStartTag() throws JspException { try { if (isLongFormat) { Invoked when the generated Servlet starts processing the “start tag” pageContext.getOut().print(new java.util.Date().getTime()); } else { pageContext.getOut().print(new java.util.Date()); } } catch (Exception e) { Prints the date according to the isLongFormat attribute throw new JspException("DateTag: " + e.getMessage()); } return SKIP_BODY; } Signals the generated Servlet there’s no body within the tag to process public int doEndTag() { return EVAL_PAGE; }} Signals the generated Servlet to continue executing the generated Servlet code 26 Invoked when the generated Servlet starts processing the “end tag” <tag> <name>date2</name> Same as before, only with different names for the tagclass <tagclass>my.DateTag2</tagclass> <body-content>empty</body-content> You can put several blocks one after another <attribute> <name>isLongFormat</name> <required>false</required> The attribute is “not required” so you have to define a default value in DateTag2.java </attribute> my-taglib2.tld </tag> <%@ taglib prefix=“mytag" uri="/WEB-INF/tags/my-taglib2.tld" %> <html><body> Uses default attribute value <h1>Hello.</h1> <h2>The time is: <mytag:date2/></h2> <h2>Milliseconds since the epoch : <mytag:date2 isLongFormat="true" /></h2> </body></html> Uses a given attribute value 27 taglibuse2.jsp How does it work? taglibuse2_jsp.java Create the JspContext taglibuse2.jsp JSP to Java Servlet translation 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… 28 When 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 JspContext DateTag2 setIsLongFormat() “Start tag” is reached doStartTag() “End tag” is reached doEndTag() 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 The Simplified Example <%= new java.util.Date() %> date.tag <%@ taglib prefix=“mytag" tagdir="/WEB-INF/tags/" %> <html> <body> In this new mechanism we use tagdir instead of uri we used in the old taglib implementation <h1>Hello. The time is: <mytag:date/></h1> </body> </html> 30 taguse.jsp A new directive The Attributes Example <%@ attribute name="isLongFormat" required="false" %> date3.tag <%!private String createDate(String isLong) { if ((isLong == null) || (isLong.equals("false"))) { Private method declaration return new java.util.Date().toString();} Default and else { return new Long(new java.util.Date().getTime()).toString();} isLongFormat=“false” case } %> <%=createDate(isLongFormat)%> isLongFormat=“true” case Calls the private method The isLongFormat parameter is identified as the isLongFormat attribute because we used the attribute directive <%@ taglib prefix=“mytag" tagdir="/WEB-INF/tags/" %> <html><body> <h1>Hello.</h1> <h2>The time is: <mytag:date3/></h2> Default case <h2>Milliseconds since the epoch : <mytag:date3 isLongFormat="true" /></h2> </body></html> isLongFormat=“true” 31 taguse3.jsp 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 taglib DEMO 33 Agenda • 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 Map a parameter name to a single • param, paramValues, value or to multiple values • header ,headerValues, Map a header name to a single value or to multiple values • cookie, • initParam, • pageScope, requestScope, • sessionScope, applicationScope Maps a cookie name to a single value Maps a context initialization parameter name to a single value For example, use the param[“x”] or param.x to get the value of the parameter x 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.jsp 39 An Example <%@ page isELIgnored="false" %> The default value is TRUE <html> <head><title>EL Examples</title></head> ${…} means evaluate the expression inside the {} <h1>Expression-Language Examples</h1> <h2>Parameter <code>x</code>: ${param["x"]} </h2> cookie[“nameof”].getValue() <h2>Cookie <code>name</code>: header [“Connection”] ${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 40 sessionScope[“homepage”]. getPath(). You can omit the sessionScope Only the ${param.x} is evaluated sessionScope [“arr”][param[“x”]