Download ppt

Document related concepts
no text concepts found
Transcript
JSP – Java Server Pages
Representation and Management of
Data on the Internet
Introduction
What is JSP Good For?
• Servlets allow us to write dynamic Web pages
- Easy access to request, session and context data
- Easy manipulation of the response (cookies, etc.)
- And lots more...
• It is not convenient to write and maintain long
static HTML using Servlets
out.println("<h1>Bla Bla</h1>" + "bla bla bla bla"
+ "lots more here...")
JSP Idea
• Use HTML for most of the page
• Write Servlet code directly in the HTML page,
marked with special tags
• The server automatically translates a JSP page to
a Servlet class and the latter is actually invoked
- In Tomcat 5.0 you can find the generated Servlet code
under $CATALINA_BASE/work/
Relationships
• Servlets: HTML code is printed from Java code
• JSP: Java code is embedded in HTML code
Java
HTML
HTML
Java
Example
<HTML>
<HEAD>
<TITLE>Hello World</TITLE>
</HEAD>
<BODY>
<H2><I><%= new java.util.Date() %></I></H2>
<H1>Hello World</H1>
</BODY>
</HTML>
Tomcat 5.0 Generated Servlet
JSP Limitations and Advantages
• JSP can only do what a Servlet can do
• Easier to write and maintain HTML
• Easier to separate HTML from code
• Can use a "reverse engineering technique": create
static HTML and then replace static data with
Java code
Basic JSP Elements
Elements in a JSP file
• HTML code: <html-tag>content</html-tag>
• HTML comment: <!-- comment -->
• JSP Comment: <%-- comment --%>
• Expressions: <%= expression %>
• Scriptlets: <% code %>
• Declarations: <%! code %>
• Directives: <%@ directive attribute="value" %>
• Actions: discussed later
JSP Expressions
• A JSP expression is used to insert Java values directly
into the output
• It has the form: <%= expression %> , where
expression can be a Java object, a numerical
expression, a method call that returns a value, etc...
• For example:
<%= new java.util.Date() %>
<%= "Hello"+" World" %>
<%= (int)(100*Math.random()) %>
JSP Expressions
• A JSP Expression is evaluated
• The result is converted to a string
• The string is inserted into the page
• This evaluation is performed at runtime (when
the page is requested), and thus has full access to
information about the request, the session, etc...
Expression Translation
<H1>A Random Number</H1>
<%= Math.random() %>
public void _jspService(HttpServletRequest request,
HttpServletResponse response)
throws java.io.IOException, ServletException {
...
response.setContentType("text/html");
...
out.write("<H1>A Random Number</H1>\r\n");
out.print( Math.random() );
out.write("\r\n");
...
}
Predefined Variables (Implicit Objects)
• The following predefined variables can be used:
- request: the HttpServletRequest
- response: the HttpServletResponse
- session: the HttpSession associated with the request
- out: the PrintWriter (a buffered version of type
JspWriter) used to fill the response content
- application: The ServletContext
• These variables and more will be discussed in details
<HTML>
<HEAD> <TITLE>JSP Expressions</TITLE></HEAD>
<BODY>
<H2>JSP Expressions</H2>
<UL>
<LI>Current time: <%= new java.util.Date() %>
<LI>Your hostname: <%= request.getRemoteHost() %>
<LI>Your session ID: <%= session.getId() %>
<LI>The <CODE>testParam</CODE> form parameter:
<%= request.getParameter("testParam") %>
</UL>
</BODY>
</HTML>
JSP Scriplets
• JSP scriptlets let you insert arbitrary code into the
Servlet service method ( _jspService )
• Scriptlets have the form: <% Java Code %>
• The code is inserted verbatim into the service method,
according to the location of the scriplet
• Scriptlets have access to the same automatically defined
variables as expressions
Scriptlet Translation
<%= foo() %>
<% bar(); %>
public void _jspService(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
...
response.setContentType("text/html");
...
out.print(foo());
bar();
...
}
An Interesting Example
Scriptlets don't have to be complete code blocks:
<% if (Math.random() < 0.5) { %>
You <B>won</B> the game!
<% } else { %>
You <B>lost</B> the game!
<% } %>
if (Math.random() < 0.5) {
out.write("You <B>won</B> the game!");
} else {
out.write("You <B>lost</B> the game!");
}
JSP Declarations
• A JSP declaration lets you define methods or members
that get inserted into the Servlet class (outside of all
methods)
• It has the following form:
<%! Java Code %>
• For example:
<%! private int someField = 5; %>
<%! private void someMethod(...) {...} %>
• It is usually of better design to define methods in a
separate Java class...
Declaration Example
• Print the number of times the current page has been
requested since the server booted (or the Servlet class
was changed and reloaded):
<%! private int accessCount = 0; %>
<%! private synchronized int incAccess() {
return ++accessCount;
} %>
<H1>Accesses to page since server reboot:
<%= incAccess() %> </H1>
public class serviceCount_jsp extends... implements...
throws... {
private int accessCount = 0;
private synchronized int incAccess()
{ return ++accessCount;}
public void _jspService(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
...
...
out.write("<H1>Accesses to page since server reboot: ");
out.print(incAccess());
... } ... }
jspInit and jspDestroy
• In JSP pages, like regular Servlets, sometimes want to
use init and destroy
• It is illegal to use JSP declarations to override init or
destroy, since they (usually) are already implemented
by the generated Servlet
• Instead, override the methods jspInit and jspDestroy
- The generated servlet is guaranteed to call these methods from
init and destroy respectively
- The standard versions of jspInit and jspDestroy are empty
(placeholders for you to override)
JSP Directives
• A JSP directive affects the structure of the Servlet class
that is generated from the JSP page
• It usually has the following form:
<%@ directive attribute="value" %>
• Multiple attribute settings for a single directive can be
combined:
<%@ directive attribute1="value1" ...
attributeN="valueN" %>
• Two types discussed in this section: page and include
page-Directive Attributes
• import attribute: A comma separated list of
classes/packages to import
<%@ page import="java.util.*, java.io.*" %>
• contentType attribute: Sets the MIME-Type of the
resulting document (default is text/html)
<%@ page contentType="text/plain" %>
• Note that instead of using the contentType attribute, you
can write
<% response.setContentType("text/plain"); %>
More page-Directive Attributes
• session="true|false" - use a session?
• buffer="sizekb|none"
- Specifies the content-buffer size (out)
• 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
showTableA.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");
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("Select * from a");
ResultSetMetaData md = rs.getMetaData();
int col = md.getColumnCount();
%>
<TABLE border="2">
<% while (rs.next()) { %>
<TR>
<% for (int i = 1 ; i <= col ; i++) { %>
<TD><%= rs.getString(i) %></TD>
<% } %>
</TR>
<% } %>
</TABLE>
</BODY>
</HTML>
errorPage.jsp
<HTML>
<HEAD> <TITLE>Reading From Database</TITLE></HEAD>
<BODY>
<%@ page isErrorPage="true" %>
<h1>Oops. There was an error when you accessed the
database. </h1>
<h2>Here is the stack trace: </h2>
<font color="red">
<pre>
<% exception.printStackTrace(new PrintWriter(out)); %>
</pre></font>
</BODY>
</HTML>
Table A exists!
Table A does not exist!
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...)
<HTML>
<HEAD> <TITLE>Including JSP</TITLE></HEAD>
<BODY>
Here is an interesting page.<br><br>
Bla, Bla, Bla, Bla. <br><br><br>
<%@ include file="AccessCount.jsp" %>
</BODY>
</HTML>
BlaBla.jsp
<hr>
AccessCount.jsp
Page Created for Dbi Course. Email us
<a href="mailto:[email protected]">here</a>.
<br>
<%! private int accessCount = 0; %>
Accesses to page since server reboot:
<%= ++accessCount %>
out.write("<HTML> \r\n");
out.write("<HEAD> <TITLE>Including JSP</TITLE></HEAD>\r\n");
out.write("<BODY>\r\n");
out.write("Here is an interesting page.<br><br>\r\n");
out.write("Bla, Bla, Bla, Bla. <br><br><br>\r\n");
out.write("\r\n");
out.write("<hr>\r\n");
out.write("Page Created for Dbi Course. Email us \r\n");
out.write("<a href=\"mailto:[email protected]\">here</a>.\r\n");
out.write("<br>\r\n");
out.write(" \r\n");
out.write("Accesses to page since server reboot: \r\n");
out.print( ++accessCount );
out.write("\r\n");
out.write("</BODY>\r\n");
out.write("</HTML> ");
Writing JSP in XML
(and vice versa)
• We can replace the JSP tags with XML tags that
represent
- Expressions
- Scriptlets
- Declarations
- Directives
<%= Expression %>
<jsp:expression>
Expression
</jsp:expression>
<% Code %>
<jsp:scriptlet>
Code
</jsp:scriptlet>
<%! Declaration %>
<jsp:declaration>
Declaration
</jsp:declaration>
<%@ Directive %>
<jsp:directive.type
Attribute="value"/>
<?xml version="1.0" encoding="UTF-8"?>
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page"
version="2.0">
<numbers>
<jsp:scriptlet> for(int i=1; i&lt;=10; ++i) { </jsp:scriptlet>
<number>
<jsp:expression> i </jsp:expression>
</number>
<jsp:scriptlet> } </jsp:scriptlet>
</numbers>
</jsp:root>
Variables in JSP
Implicit Objects
• As seen before, some useful variables, like
request and session are predefined
• These variables are called implicit objects
• Implicit objects are defined in the scope of the
service method
- Can these be used in JSP declarations?
• Implicit objects are part of the JSP specifications
The objects request and response
• request and response are the HttpServletRequest
and HttpServletResponse arguments of the service
method
• Using these objects, you can:
• Read request parameters
• Set response headers
• etc. (everything we learned in Servlet lectures)
The object out
• This is the Writer used to add write output into
the response body
• This object implements the interface JspWriter,
which supports auto-flush
• Recall that you can adjust the buffer size, or turn
buffering off, through use of the buffer attribute
of the page directive
The object page
• Simply a synonym for (Object)this
• page is not very useful in JSP pages
• It was created as a placeholder for the time when
the scripting language could be something other
than Java
The object pageContext
• pageContext is a new object introduced by JSP
• This object encapsulates use of server-specific
features (e.g. higher performance JspWriters)
• Access server-specific features through this class
rather than directly, so your code will conform to
JSP spec. and not be server dependent
• This object is also used to store page-scoped Java
Beans (discussed later)
The object session
• This is the HttpSession object associated with
the request
• If the session attribute in the page directive is
turned off (<%@ page session="false" %>)
then this object is not available
• Recall that a session is created by default
The object config
• This is the ServletConfig of the page, as received
in the init() method
• Remember: Contains Servlet specific
initialization parameters
• Later, we will study how initialization parameters
are passed to JSP pages in Tomcat
• You can get the ServletContext from config
The object application
• This is the ServletContext as obtained via
getServletConfig().getContext()
• Remember:
- The ServletContext is shared by all Web-application
Servlets (including ones generated from JSP)
- Getting and setting attributes is with getAttribute and
setAttribute of ServletContext
- You can use this object to get application-wide
initialization parameters
Review: Variable Scope
service() local variables
a.jsp
client1
b.jsp
client2
Review: Variable Scope
Servlet members
a.jsp
client1
b.jsp
client2
Review: Variable Scope
session
a.jsp
client1
b.jsp
client2
Review: Variable Scope
application
a.jsp
client1
b.jsp
client2
Servlet Package and Helper Classes
• The generated Servlet has a named package
• In Tomcat, this package is: org.apache.jsp
• In Java, you cannot use classes from the default
package (i.e. with no package declaration) from a
named package!
• Therefore, helper classes used by JSP pages must
have a named package
JSP Actions
Actions
• JSP actions use constructs in XML syntax to
control the behavior of the Servlet engine
• Using actions, you can
- dynamically insert a resource content
- forward the user to another page
- reuse Java Beans and custom tags - briefly
discussed later
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 %>}"
flush="true| false" >
<jsp:param name="parameterName"
value="{parameterValue | <%= expression %>}" />*
</jsp:include>
• This action is also translated to an invocation of
the RequestDispatcher
include Directive vs. Action
• When a file is included using the include directive, the
file itself is included verbatim into the JSP code, prior to
the Servlet generation
• When a resource is included using the include action,
the generated Servlet uses the dispatcher to include its
content at runtime
• Question: using which of the latter options can the
included element change the HTTP headers or status?
JSP Life Cycle
JSP Life Cycle
The following table describes the life cycle of JSP
generated Servlet in details:
JSP Life Cycle
JSP page
Request
Request
Request
Request
Request
Request
#1
#2
#3
#4
#5
#6
Yes
No
No
No
Yes
No
Yes
No
No
No
Yes
No
Yes
No
Yes
No
Yes
No
Yes
No
Yes
No
Yes
No
Yes
Yes
Yes
Yes
Yes
Yes
translated into
servlet
loaded into
server's memory
init (or
Page modified
instantiated and
Server restarted
Servlet
Page first written
Servlet compiled
equivalent) called
doGet (or
equivalent) called
Written by Marty Hall. Core Servlets & JSP book: www.coreservlets.com
JSP Translation
• When the JSP file is modified, JSP is translated into a
Servlet
- Application need not be reloaded when JSP file is modified
- In Tomcat 5.0, translation is done even if included files
(through the include directive) are modified
• Server does not generate the Servlet class after startup,
if the latter already exists
- Generated Servlet acts just like any other Servlet
init() and destroy()
• init() of the generated Servlet is called every time
the Servlet class is loaded into memory and
instantiated
• destroy() of the generated Servlet is called every
time the generated Servlet is removed
• The latter two happen even if the reason is
modification of the JSP file
Thread Synchronization
• After the Servlet is generated, one instance of it
services requests in different threads, just like
any other Servlet
• In particular, the service method (_jspService)
may be executed by several concurrent threads
• Thus, like Servlets, JSP code should deal with
concurrency
JSP in Tomcat 5.0
Tomcat 5.0 Generated Servlet
<HTML>
<HEAD>
<TITLE>Hello World</TITLE>
</HEAD>
<BODY>
<H2><I><%= new java.util.Date() %></I></H2>
<H1>Hello World</H1>
</BODY>
</HTML>
Tomcat 5.0 Generated Servlet
Generated Servlet Hierarchy
(Tomcat 5.0 Implementation)
Sun
Specifications
Servlet
GenericServlet
HttpServlet
Apache
Implementation
JspPage
HttpJspPage
HttpJspBase
mypage_jsp
different
packages
Generated
Servlet
Implementation vs. Specification
• JSP files should conform to JSP specifications
and be container independent
• For example, JSP files that assume extension of
HttpServlet will compile and run correctly under
Tomcat, but may fail to compile under other
containers
• The implicit object pageContext exists for this
reason
JSP Initial Parameters
• Like Servlets, initial parameters can be passed to
JSP files using the <servlet> element of the
application configuration file web.xml
• Use the sub-element <jsp-file> instead of the
sub-element <servlet-class>
• A <servlet-mapping> is also needed
- Use the JSP file as the <url-pattern>
<web-app>
<context-param>
<param-name>dbLogin</param-name>
<param-value>snoopy</param-value>
</context-param>
<context-param>
<param-name>dbPassword</param-name>
<param-value>snoopass</param-value>
</context-param>
<servlet>
<servlet-name>ParamPage</servlet-name>
<jsp-file>/paramPage.jsp</jsp-file>
<init-param>
<param-name>tableName</param-name>
<param-value>users</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>ParamPage</servlet-name>
<url-pattern>/initParam.jsp</url-pattern>
</servlet-mapping>
</web-app>
<HTML>
<HEAD><TITLE>JSP initial parameters</TITLE></HEAD>
<BODY>
<H1>Hello</H1>
<H2>I should use the table <I><%=
config.getInitParameter("tableName") %></I>.</H2>
<H2>To access the Database, I should use the login
<I><%=
application.getInitParameter("dbLogin") %></I> and
the password <I><%=
application.getInitParameter("dbPassword")
%></I>.</H2>
</BODY>
</HTML>
Appendix 1:
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
• Wrap your data, in a standard fashion, inside a
Java class (Java Bean)
• Use special JSP actions to access and manipulate
the bean
• Use 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
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; }
getCounter and setCounter define the property counter
public void increment() { ++counter; }
}
other methods can be used
pageA.jsp
<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>
invokes getCounter()
pageB.jsp
<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>
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;}
}
infoForm.html
<HTML>
<HEAD><TITLE>User Info</TITLE></HEAD>
<BODY><H1>Fill in your details:</H1>
<FORM ACTION="infoA.jsp">
Your First Name: <INPUT TYPE="text"
NAME="firstName"> <BR>
Your Last Name: <INPUT TYPE="text"
NAME="lastName"> <BR>
<INPUT TYPE="submit">
</FORM> </BODY>
</HTML>
infoA.jsp
Match parameters to corresponding properties
<jsp:useBean id="userInfo"
class="dbi.UserInfoBean" scope="session"/>
<jsp:setProperty name="userInfo" property="*"/>
<H1> <jsp:getProperty name="userInfo"
property="firstName"/>
<jsp:getProperty name="userInfo"
property="lastName"/>, </H1>
<H1>Have a nice session!</H1>
<A HREF="infoB.jsp">User Info B</a>
infoB.jsp
<jsp:useBean id="userInfo"
class="dbi.UserInfoBean" scope="session"/>
<jsp:setProperty name="userInfo" property="*"/>
<H1> <jsp:getProperty name="userInfo"
property="firstName"/>
<jsp:getProperty name="userInfo"
property="lastName"/>, </H1>
<H1>Have a nice session!</H1>
<A HREF="infoA.jsp">User Info A</a>
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)
Appendix 2:
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());
}
}
<?xml version="1.0" encoding="ISO-8859-1" ?>
<taglib version="2.0">
<tlib-version>1.0</tlib-version>
dbi-taglib.tld
<tag> <name>date</name>
<tagclass>dbi.DateTag</tagclass>
<body-content>empty</body-content> </tag>
</taglib>
<%@ taglib prefix="dbitag"
uri="/WEB-INF/tags/dbi-taglib.tld" %>
<html><body>
taglibuse.jsp
<h1>Hello. The time is: <dbitag:date/></h1>
</body></html>
Tag Files
• The new version of 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