Transcript JSP - CS

JSP – Java Server Pages
Part 2
Representation and Management of
Data on the Internet
Interacting with other
Resources
JSP Cooperation
• We will consider several ways in which JSP and
other resources cooperate
- Forwarding the request handling to other resources
- Including the content of other sources
- Including the code of other JSP files
- Forwarding exception handling to other JSPs
Actions
• JSP actions use constructs in XML syntax to
control the behavior of the Servlet engine
• Using actions, you can
- forward the request to another resource in the
application
- dynamically include a resource content in the
response
The forward Action
• jsp:forward - Forwards the requester to a new
resource
<jsp:forward page="{relativeURL|<%= expression %>}">
<jsp:param name="parameterName"
value="{parameterValue | <%= expression %>}" /> *
</jsp:forward>
• This action is translated to an invocation of the
RequestDispatcher
The include Action
• jsp:include - Include a resource content at run
time
<jsp:include page="{relativeURL|<%= expression %>}">
<jsp:param name="parameterName"
value="{parameterValue | <%= expression %>}" />*
</jsp:include>
• This action is also translated to an invocation of
the RequestDispatcher
The include Directive
• This directive lets you include files at the time
the JSP page is translated into a Servlet
• The directive looks like this:
<%@ include file="url" %>
• JSP content can affect main page
• In Tomcat 5.x, generated Servlet is updated when
included files change (unlike old versions...)
Include - Action
File1.jsp
HTML
content
Servlet1
HTML
content
File2.jsp
Servlet2
HTML
content
Include Directive
File1.jsp
File2.jsp
Servlet
HTML
content
include Action vs. Directive
• When a resource is included using the include action,
the generated Servlet uses the dispatcher to include its
content at runtime
• When a file is included using the include directive, the
file itself is included verbatim into the JSP code, prior to
the Servlet generation
• Question: in which of the above options can the included
element change the HTTP headers or status?
BlaBla.jsp
<html>
<head><title>Including JSP</title></head><body>
<h2>Here is an interesting page.</h2>
<p>Bla, Bla, Bla, Bla.</p>
<%@ include file="/AccessCount.jsp" %>
<jsp:include page="/dbimail.jsp"/>
</body></html>
AccessCount.jsp
<%! private int accessCount = 0; %>
<hr><p>Accesses to page since Servlet init:
<%= ++accessCount %></p>
dbimail.jsp
<hr><p>
Page Created for Dbi Course at <%= new java.util.Date() %>.
Email us <a href="mailto:[email protected]">here</a>. </p>
BlaBla_jsp.java
out.write("<html>\r\n");
out.write(" <head><title>Including JSP</title></head>\r\n");
out.write(" <body>\r\n");
out.write(" <h2>Here is an interesting page.</h2>\r\n");
out.write(" <p>Bla, Bla, Bla, Bla.</p>\r\n");
out.write("<hr>\r\n");
out.write("<p> \r\n");
out.write(" Accesses to page since Servlet init: \r\n");
out.print( ++accessCount );
out.write("</p>\r\n");
org.apache.jasper.runtime.JspRuntimeLibrary.
include(request, response, "/dbimail.jsp", out, false);
out.write(" </body>\r\n");
out.write("</html>\r\n");
Included Counter
• Suppose that the file BlaBla2.jsp is similar the
BlaBla.jsp
• How will the counter of BlaBla2.jsp act?
• What if we used a JSP action instead of a JSP
directive for the counter?
Error Pages
• We can set one JSP page to be the handler of uncaught
exceptions of another JSP page, using JSP directives
• <%@ page errorPage="url " %>
- Defines a JSP page that handles uncaught exceptions
- The page in url must have true in the page-directive:
• <%@ isErrorPage="true|false" %>
- The variable exception holds the exception thrown
by the calling JSP
connect.jsp
<html>
<head><title>Reading From Database </title></head>
<body>
<%@ page import="java.sql.*" %>
<%@ page errorPage="errorPage.jsp" %>
<%
Class.forName("oracle.jdbc.driver.OracleDriver");
Connection con = DriverManager.getConnection
("jdbc:oracle:thin:" + "snoopy/snoopy@sol4:1521:stud");
%>
<h2>Connection Established!!</h2>
</body>
</html>
errorPage.jsp
<html>
<head><title>Connection Error</title></head>
<body>
<%@ page import="java.io.*" %>
<%@ page isErrorPage="true" %>
<h1>Oops. There was an error when you accessed the
database.</h1>
<h2>Here is the stack trace:</h2>
<pre style="color:red">
<% exception.printStackTrace(new PrintWriter(out)); %>
</pre>
</body>
</html>
Custom JSP Tags
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
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
A Simple TagLib Example
DateTag.java
package dbi;
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());
}
}
<taglib>
<tlib-version>1.0</tlib-version><jsp-version>2.0</jsp-version>
<tag>
<name>date</name>
<tagclass>dbi.DateTag</tagclass>
<body-content>empty</body-content>
</tag>
</taglib>
dbi-taglib.tld
<%@ taglib prefix="dbitag" uri="/WEB-INF/tags/dbi-taglib.tld" %>
<html><body>
<h1>Hello. The time is: <dbitag:date/></h1>
</body></html>
taglibuse.jsp
Tag Files
• JSP 2.0 provides an extremely simplified way of
defining tags
• 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
The Simplified Example
<%= new java.util.Date() %>
date.tag
<%@ taglib prefix="dbitag" tagdir="/WEB-INF/tags/" %>
<html>
<body>
<h1>Hello. The time is: <dbitag:date/></h1>
</body>
</html>
taguse.jsp
Other Capabilities of Custom Tags
• Attributes
- You can define the possible attributes of the Tags
- These can be accessed during the Tag translation
• Tag Body
- Tag translation may choose to ignore, include or
change the tag body
Java Beans in JSP
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, like users information
- Application attributes, like access counters
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...)
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, like its scope
Example 1: Access Counter
In the following example, we use a Bean to
maintain an access counter for requests to the
pages
Counter Bean
package dbi;
Bean must reside in a package
public class CounterBean {
private int counter;
Bean is created by an empty
constructor
public CounterBean() { counter = 0; }
public int getCounter() { return counter; }
public void setCounter(int i) { counter = i; }
counter is readable and writable
public void increment() { ++counter; }
}
other methods can be used
CounterBean.java
<html>
<head><title>Bean Example</title></head><body>
<jsp:useBean id="accessCounter"
class="dbi.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>
invokes getCounter()
pageA.jsp
<html>
<head><title>Bean Example</title></head><body>
<jsp:useBean id="accessCounter"
class="dbi.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
From the Generated Servlet
dbi.CounterBean accessCounter = null;
synchronized (application) {
accessCounter = (dbi.CounterBean)
_jspx_page_context.getAttribute("accessCounter",
PageContext.APPLICATION_SCOPE);
if (accessCounter == null) {
accessCounter = new dbi.CounterBean();
_jspx_page_context.setAttribute("accessCounter",
accessCounter, PageContext.APPLICATION_SCOPE);
}
}
Example 2: Session Data
In the following example, we use a Bean in order
to keep a user's details throughout the session
package dbi;
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
<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
<jsp:useBean id="userInfo" class="dbi.UserInfoBean"
scope="session"/>
<jsp:setProperty name="userInfo" property="*"/>
<html>
Match parameters
to
<head><title>Page
A</title></head><body>
corresponding properties
<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
<jsp:useBean id="userInfo" class="dbi.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
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)
JSP Expression Language
JSP Expression Language
• JSP expression language is a comfortable tool to
access useful objects in JSP
• This language provides shortcuts in JavaScriptlike syntax
• An expression in EL is written as ${expr}
• For example:
Hi, ${user}. <em style="${style}">Welcome</em>
EL Variables
• JSP EL does not recognize JSP's implicit objects,
but rather has its own set:
param, paramValues, header ,headerValues,
cookie, initParam, pageScope, requestScope,
sessionScope, applicationScope
• Each of these objects maps names to values
• For example, use param["x"] or param.x to get the
value of the parameter x
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.
Object Properties
• In JSP EL, Property p of Object o is referred to as
o[p]
• Property p of Object o is evaluated as follows:
- If o is a Map object, then o.get(p) is returned
- If o is a List or an array, then p is converted into an
integer and o.get(p) or o[p] is returned
- Otherwise, treat o as a bean, convert p to a string, and
return apply the corresponding getter of o
• The term o.p is equivalent to o["p"]
An Example
<% response.addCookie(new Cookie("course","dbi"));
session.setAttribute("dbiurl",new
java.net.URL("http://www.cs.huji.ac.il/~dbi/index.html"));
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
<%@ 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>course</code>:
${cookie.course.value}</h2>
<h2>Header <code>Connection</code>:
${header.Connection} </h2>
<h2>Path of session attr. <code>dbiurl</code>:
${sessionScope.dbiurl.path}</h2>
<h2>Element <code>arr[${param.x}]</code>:
${arr[param.x]} </h2>
</body></html>
el.jsp