JSP: JavaServer Pages

Transcription

JSP: JavaServer Pages
-- 4 -JSP: JavaServer Pages
Turning Servlets Inside Out

56
JavaServer Pages: Java code embedded in HTML  More similar to languages such as PHP
▪ out.println(”<p>The value of pi is: ” + Math.pi); // Servlet
▪ <p>The value of pi is: <%= Math.PI %>
// JSP
 Code is still executed by the server, not the client!
▪ Use the .jsp extension to indicate that it is not pure HTML
▪ The server translates the file into a servlet, executes it
 Useful when there is much more HTML than Java code
JSP source:
HTML code
with JSP code added
Output:
Compilation
Servlet code
Execution
Pure HTML
jonkv@ida
JSP 1: What is it?

57
Initial versions defined “JSP pages”
 Three different pseudo‐tags identify Java code
▪ <%= EXPRESSION %> to insert the value of an expression
▪ <% SCRIPTLET %> to insert plain Java code
▪ <%! DECLARATION %> to insert a declaration

Current versions also support ”JSP documents”
 Based on pure XML, true tags
▪ Positive: Use XML tools, validate against standard JSP DTD, …
▪ Negative: Must use well‐formed XML (longer tags, …)
▪ <jsp:expression> EXPRESSION </jsp:expression>
▪ <jsp:scriptlet> SCRIPTLET </jsp:scriptlet>
▪ <jsp:declaration>DECLARATION</jsp:declaration>
Current lab instructions use both “page” and “document”,
since you may choose to use either one!
jonkv@ida
JSP 2: Pages and Documents

58
Must declare the contents of the page
 Which scripting language is used on the server side?
 Which document langauge is generated and seen on the client?

Older JSP ”pages” (.jsp) use JSP‐specific tools
 The source file has a standard HTML doctype,
plus a JSP pseudo‐tag declaring JSP options
▪ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 //EN"
"http://www.w3.org/TR/html4/strict.dtd">
<%@ page contentType="text/html;charset=UTF-8” %>
<html>
…
</html>
 The source file lies, claiming to be HTML.
 JSP‐specific tools still know that the source file is JSP.
jonkv@ida
JSP 3: Language and Content Type

59
Newer JSP ”documents” (.jspx) use the XML standard
 Suppose the doc source file started with an HTML doctype
▪ Standard XML tools apply this to the entire document – wrong!
 But the client should still see an HTML DOCTYPE at the top!
▪ Solution: Use code that ”prints” the doctype!
▪ <jsp:output doctype-root-element="html”
doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN"
doctype-system=”http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd”
omit-xml-declaration=”false” />
▪ (By default, jsp:output will declare your document to be XML,
which is only true for XHTML.
Use omit‐xml‐declaration=”true” for ordinary HTML.)
 Then, the page directive must be different
▪ <%@ page …> is not well‐formed XML, can’t be used here
▪ <jsp:directive.page contentType="text/html;charset=UTF-8" />
<html>…</html>
jonkv@ida
JSP 4: Language and Content Type

Inserting the value of an expression:
 In JSP pages, use <%= … %>
▪ …DOCTYPE…
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>A Simple JSP Page</title></head>
<body>
<p>Today is <%= new java.util.Date() %>
<p>The value of pi is: <%= Math.PI %>
</body>
</html> <jsp:expression> new java.util.Date()</jsp:expression>
 Automatically converted into a servlet:
▪ public void doGet(HttpServletRequest req, HttpServletResponse res) {
… res.setContentType("text/html;charset=UTF-8"); …
out.print("<html>\n<head><title>…Today is ");
out.print(new java.util.Date());
out.print("\n\n<p>The value…");
60
jonkv@ida
JSP 5: Inserting Expressions

61
Use scriptlets to insert complete Java code fragments
 Use <% … %> or <jsp:scriptlet> … </jsp:scriptlet>
▪ <p>Will you win the lottery?
<%
double rand = Math.random();
if (rand < 0.1) {
out.println("You win!");
} else {
out.println(“Reload the page to try again!");
}
What’s inside <% … %> is inserted as-is in the resulting servlet!
%>
What’s inside <%= … %> was inserted inside out.print(…).
<p>Random: <%= double r = Math.random(); out.println(r); %>
 out.println(”<p> Random: ” + double r = Math.random(); out.println(r););
<p>Pi is equal to <% Math.PI %>
 out.println(”<p>Pi is equal to ”); Math.Pi
jonkv@ida
JSP 6: Inserting Code Fragments

Declare methods and fields
 Use <%! … %> or <jsp:declaration>DECLARATION</jsp:declaration>
▪ <%!
private int visitsSinceServerStarted = 0;
%>
▪ <%! private Connection getDatabaseConnection() {
…
}
%>
 Ends up outside the doGet() method
▪ At the top level of the resulting servlet class
62
jonkv@ida
JSP 7: Declaring Methods and Fields

Using JSP to display a database table:
▪ <%
Connection conn = …;
Statement statement = conn.createStatement();
ResultSet result = statement.executeQuery(…); %>
<TABLE …>
<% while (result.next()) { %>
<tr>
<td><%= result.getString("name") %></td>
<td><%= result.getString("phone") %></td>
</tr>
<% } %>
 HTML within a Java loop! Works due to the translation:
▪ while (result.next()) {
out.print("<tr>\n");
out.print(" <td>"); out.print(result.getString("name")); out.print("</td>");
…
}
63
jonkv@ida
JSP 8: Database Example

A number of variables are set up for your use:
 request
 response
 pageContext
 session
‐ an HTTPServletRequest
‐ an HTTPServletResponse
‐ a javax.servlet.jsp.PageContext
‐ a javax.servlet.http.HttpSession
‐ a javax.servlet.ServletContext
 application
▪ Example: Retrieve a <context‐param> from web.xml using
<%= application.getInitParameter("Webmaster") %>
 out
 config
‐ a javax.servlet.jsp.JspWriter
‐ a javax.servlet.ServletConfig
64
jonkv@ida
JSP 9: Implicit Variables

65
Processing Forms using JSP
 First, the form:
▪ <html>
<body>
<form method="POST" action="form.jsp">
<input type="checkbox" name="city" value="LA">LA<br>
<input type="checkbox" name="city" value="Boston">Boston<br>
<input type="checkbox" name="city" value="Calgary">Calgary<br>
<br>
<input type="radio" name="month" value="January">January<br>
<input type="radio" name="month" value="June">June<br>
<input type="radio" name="month" value="August">August<br>
<br>
<input type="submit" value="Submit">
</form>
</body>
</html>
jonkv@ida
JSP 10: Form example (HTML form)

66
Processing Forms using JSP
 Then, the JSP page, using request (the HTTPServletRequest):
▪ <p>The cities selected are:</p>
<%
final String[] cities = request.getParameterValues("city");
final String month = request.getParameter("month");
if (cities != null) { %>
<ul>
<% for (int i=0; i &lt; cities.length; i++) { %>
<li><%= cities[i] %>
<% } %>
Some of this code might be
</ul>
extracted into "real" classes!
<% } else { %>
<p>None selected.</p>
<% } %>
…
jonkv@ida
JSP 11: Form example (JSP)

67
Page directives (at the top of the file) are used to:
 Import necessary Java classes
▪ <%@ page import=“{package.class | package.* }” %>
▪ <jsp:directive import=“{package.class | package.* }” />
 Turn on or off session handling (discussed later)
▪ … session = ”true | false” (default is true)
 Change buffer sizes
▪ … buffer = ”none | 8kb | sizekb” (default is 8kb)
 Declare whether your page is threadsafe
▪ … isThreadSafe = ”true | false”
▪ Default is true: The page may be called multiple times concurrently!
jonkv@ida
JSP 12: Page Directives

68
Init parameters for JSP pages
 Also specified within servlet tag – JSP compiled into servlet!
▪ <servlet>
<servlet‐name>newuser</servlet‐name>
<jsp‐file>directory/newuser.jsp</jsp‐file>
…
<init‐param>
<param‐name>emailConfirmationRequired</param‐name>
<param‐value>true</param‐value>
</init‐param>
<init‐param>…</init‐param>
</servlet>
▪ JSP: <%= config.getInitParameter("emailConfirmationRequired") %>
jonkv@ida
JSP 13: Configuration
-- 5 -JSP Standard Tag Library (JSTL)
JavaServer Pages Standard Tag Library
Custom Tag Libraries

Java code and HTML don't mix very well
 Harder to read mixed languages with mixed indentation…
▪ <% for (int i=0; i < cities.length; i++) { %>
<li><%= cities[i] %>
<% } %>
 Also, Java is strongly typed, exceptions must be handled, …
▪ A nuisance if you prefer the ”script language” style
 Solution: Use tag libraries
▪ Well‐defined interface to define your own ”server‐side tags”
 JSTL: JavaServer Pages Standard Tag Library
▪ Standard tags, relevant for most applications
▪ Written in Java, but used as tags
 JSTL EL: Expression Language
▪ Calculate simple expressions within JSP, without Java code
70
jonkv@ida
JSTL 1: Why?

Consider a simple example…
 Square numbers using println to generate HTML
▪ <%
for (int i = 0; i < 10; i++) {
out.println(”<p>Here's a number: ” + i + ”</p>”);
out.println(”<p>Its square is ” + (i*i) + ”</p>”);
}
%>
 Square numbers using mixed HTML and Java
▪ <% for (int i = 0; i < 10; i++) { %>
<p>Here's a number: <%= i %></p>
<p>Its square is <%= i*i %></p>
<% } %>
jonkv@ida
JSTL 2: Square Example and <c:forEach> 71

A JSTL version:
 Declare the use of the "core" tag library, give it the prefix ”c”
▪ <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
▪ JSPX: <html xmlns:c="http://java.sun.com/jsp/jstl/core" …>
▪ The tag library itself consists of Java code
(class library must be included with the final application)
 Use tags from JSTL Core, prefixed by ”c:”
▪ <c:forEach var="i" begin="0" end="9">
<p>Here's a number: ${i}</p>
<p>Its square is ${i*i}</p>
</c:forEach>
 <c:forEach> creates a scoped variable
▪ Not the same as ”ordinary” Java variables
▪ Its value can be used in the Expression Language (EL), inside ${…}
▪ The Expression Language is not plain Java either!
jonkv@ida
JSTL 3: Square Example and <c:forEach> 72

73
Conditionals are available…
▪ <c:forEach var="i" begin="0" end="9">
<p>Here's a number: ${i}.</p>
<c:if test="${i mod 2 eq 0}">
<c:if> contains a test written in the
<p>The number is even.</p>
Expression Language. (Not Java –
</c:if>
notice the operators "mod" and "eq",
<p>Its square is ${i*i}.</p>
though "%" and "==" are also available
here.)
</c:forEach>
jonkv@ida
JSTL 4: Conditionals, <c:if>

74
There is no "else”!
 But there is a choose/when/otherwise:
▪ <c:forEach var="i" begin="0" end="9">
<p>Here's a number: ${i}</p>
<c:choose>
<c:when test="${i mod 2 eq 0}">
<p>The number is even.</p>
This is similar to switch/case in Java, in
</c:when>
that you can have multiple "when" tags
<c:otherwise>
<p>The number is odd.</p> in a "choose" tag.
</c:otherwise>
</c:choose>
<p>Its square is ${i*i}</p>
</c:forEach>
jonkv@ida
JSTL 5: Conditionals, <c:choose>

Then, the JSP page, using JSTL tags
 The EL variable ”param” contains all parameter values
▪ Implicitly declared, always available
▪ Parameters are provided by forms (PUT or POST),
or by URLs of the form ”something.jsp?yourname=Jonas&par1=val1&par2=val2&…”
▪ <p>Your name is: <c:out value="${param.yourname}” /></p>
 The ”empty” operator tests for null, empty strings, empty arrays, …
▪ <c:if test="${empty param.yourname}">
<p>You forgot to specify a name.</p>
</c:if>
75
jonkv@ida
JSTL 6: Forms, Revisited (JSP+JSTL)
76
 Use ”paramValues” for parameters with multiple values
▪ Many checkboxes may be selected
 Use <c:forEach> to iterate over arrays, collections, …
▪ <c:choose>
<c:when test="${empty paramValues.city}">
<p>None selected.</p>
</c:when>
paramValues.city is a list of cities
<c:otherwise>
selected in the form (in Java code:
<p>The cities selected are:</p>
request.getParameterValues(”city”
<ul>
)
<c:forEach var="city" items="${paramValues.city}">
<li><c:out value="${city}"/></li>
</c:forEach>
”city” is a new scoped variable in the
</ul>
Expression Language
</c:otherwise>
</c:choose>
jonkv@ida
JSTL 7: Forms, Revisited (JSP+JSTL)

77
JSTL has special tags for SQL access
 Specify use of the SQL tag library in each JSP page/doc
▪ <%@ taglib uri="http://java.sun.com/jsp/jstl/sql" prefix="sql"%>
 Specify a default DataSource used by these tags
▪ A DataSource was already configured and named in Tomcat’s config
▪ Tell JSTL you want to use this DataSource using web.xml:
<context-param>
<param-name>javax.servlet.jsp.jstl.sql.dataSource</param-name>
<param-value>jdbc/mydb</param-value>
</context-param>
▪ …where jdbc/mydb is replaced with the name you chose before!
jonkv@ida
JSTL/SQL 1: Databases – setup

78
Display a database table using JSTL:
 Use <sql:query> ‐‐ opens and closes connections as needed
 Returns a Result, whose ”rows” field can be iterated over
▪ <sql:query var="result">SELECT * FROM myTable; </sql:query>
<TABLE …>
<tbody>
<c:forEach var="row" items="${result.rows}">
<tr>
<td><c:out value="${row.name}"/></td>
<td><c:out value="${row.phone}"/></td> </tr>
</c:forEach>
</tbody>
</TABLE>
 Use <c:out /> tag to convert ”<” into ”&lt;” etc.
▪ If the user enters name = ”<b>hello”, you will see ”<b>hello”
▪ With just plain ”<td>${row.name}</td>”, the rest of the web page would be bold…
jonkv@ida
JSTL/SQL 2: Queries – <sql:query>

79
Queries are always PreparedStatements
 Use ? as placeholder for a parameter
▪ Can be used in most places, but not (for example) in LIMIT clauses
▪ <sql:param> for most parameter values
▪ <sql:dateparam> for dates
▪ <sql:query var="result">
SELECT * FROM myTable WHERE name LIKE ’?’
<sql:param value="${param.namepattern}"/>
</sql:query>
jonkv@ida
JSTL/SQL 3: Query Parameters

80
You may want to limit the number of result rows
 If you have a thousand topics, you don’t display all on one page
 JSTL always reads all rows resulting from a query…

Solution:
 <sql:query var="result" startRow=”0" maxRows=”50”>
…
</sql:query>
<c:if test=”${result.limitedByMaxRows}”>
There are additional results that have not been returned.
</c:if>
jonkv@ida
JSTL/SQL 4: Limiting Results

81
Database updates using JSTL
 A form to enter information for a new user
▪ <form method="post" action="addUser.jsp">
<input type="text" name="subject"></input> …
</form>
 A JSP+JSTL page to which this information is sent
▪ <!‐‐ First ensure that parameters are correctly provided! ‐‐>
<sql:update var="updateResult"> <!‐‐ Result: # rows changed ‐‐>
INSERT INTO messages VALUES(NULL,?,?,NULL,?,?)
<sql:param value="${param.topicid}"/>
<sql:param value="${param.user}"/>
<sql:param value="${user.messagesWritten + 1}"/>
<sql:param value="${param.message}"/>
</sql:update>
jonkv@ida
JSTL/SQL 5: Updates – <sql:update>

Database transactions using JSTL
 Enclose in <sql:transaction>
▪ <sql:transaction>
<sql:query> … </sql:query>
<!– do something based on the query ‐‐>
<sql:update> … </sql:update>
<sql:update> … </sql:update>
<sql:update> … </sql:update>
</sql:transaction>
 Java (and JSP / JSTL) signal errors using exceptions
▪ If an exception occurs ”inside” <sql:transaction>,
the transaction is automatically rolled back
82
jonkv@ida
JSTL/SQL 6: <sql:transaction>

83
Processing and rewriting relative URLs
 May be necessary to add session ID for session tracking
 <c:url> generates a variable containing a rewritten URL

Message forum example:
 Suppose this webapp is mapped at "/forum"
 <c:url var="myURL" value="/adduser" >
<c:param name=“user" value="${param.name}" />
</c:url>
 Result: "myURL" variable may become either…
▪ "http://www.host.com/forum/adduser?user=Jonas+Kvarnstr%F6m" or
▪ "http://www.host.com/forum/adduser;jsession=ede1ac355149582fb3
4ba9e6d5a347bc?user=Jonas+Kvarnstr%F6m"
 Used later in the page
▪ <p><a href="${myURL}">Add user!</a>
jonkv@ida
JSTL: Building URLs – <c:url>

84
JSTL is just the standard tag library – many others exist
 You can write your own tags!
▪ http://java.sun.com/developer/technicalArticles/xml/WebAppDev3/
▪ public class Subtract extends TagSupport {
private int num1, num2;
public void setNum1(int num1) { this.num1 = num1; }
public void setNum2(int num2) { this.num2 = num2; }
public int doStartTag() throws JspException {
try {
pageContext.getOut().print("Welcome to First Grade Math! ");
pageContext.getOut().print("If you subtract" + num2 + " from " + num1 + ", you get: "+ (num1 ‐ num2));
} catch (IOException ioe) { … }
return SKIP_BODY;
}
}
▪ … plus XML config  JSP tag <math:sub num1="12" num2="3" />
jonkv@ida
Custom Tag Libraries
-- 6 -The JSTL Expression Language

Expression language used within ${…} is NOT JAVA!
 JSP‐specific expressions where some operators are similar
 Translated into Java by servlet container

Operators:
 == (or eq), != (or ne), < (or lt), > (or gt), <= (or le), >= (or ge)
▪ Operator names without <> can be used more easily in XML!
 Addition (+), subtraction (‐), multiplication (*),
division (/ or div), remainder/modulo (% or mod)
 && (or and), || (or or), and ! (or not).
 "empty" is used to determine if a value is null or empty
▪ <c:if test=”${empty param.name}”>
<p>Please specify your name.</p>
</c:if>
86
jonkv@ida
EL 1: Not Java; operator overview

87
Implicit variables are set up automatically to access:
 HTTP request parameters (such as form input)
▪ param.name or param["name"]: Single‐valued parameter "name"
▪ paramValues.name: When multiple values are possible (returns array)
 HTTP request headers (user‐agent, accept‐language, …)
▪ Via header and headerValues
 Servlet/JSP initialization parameters
▪ initParam (specified in web.xml for configuration; discussed later)
 Cookies
▪ cookie (cookies received in request; discussed later)
 The PageContext
▪ pageContext gives access to a JSP PageContext object
▪ Gives access to HttpServletRequest, ServletContext, and HttpSession
▪ ServletContext: Global configuration for the entire webapp
jonkv@ida
EL: Some implicit variables

Variables available in EL are not Java variables
 <c:out value="${param}" /> ‐‐ OK
 <% System.out.println(param) %> ‐‐ "param" unknown!

Reason: You can choose their scope
 Choose how they are shared and how long they live
 Page: Local to this page (the most restricted)
 Request: A single call from the browser to the server
▪ May consist of multiple pages, using e.g. <jsp:include>
 Session: Persists during multiple calls from the same user
▪ Will discuss sessions in detail later
 Application: Globally available in the web application
▪ Many sessions for this and other users)
88
jonkv@ida
EL: Variables are not Java Variables

Supporting scopes requires special care
 Use JSTL maps containing variable names and values
▪ One applicationScope map
▪ One sessionScope map per session
▪ One requestScope map per request
▪ One pageScope map per page
▪ <c:set value=”val" var=”myVar” scope=”session” />
▪ Actually results in sessionScope.put(”myVar”, ”val”);
▪ ${sessionScope.myVar} …
▪ <c:remove var="variableName" [scope=…] />
(important for long‐lived scopes such as session/application!)
 Or use corresponding JSP/Java objects and methods
▪ pageContext.getAttribute(”…”)
▪ …
89
jonkv@ida
EL: Variables are not Java Variables

90
Implicit scope references
 If you don’t specify a scope, all scopes are searched
▪ Smallest scope first
▪ <c:set value=”val" var=”myVar” scope=”session” />
▪ ${sessionScope.myVar}
▪ Guaranteed to refer to the variable above
▪ ${myVar}
▪ Checks the page scope for myVar
▪ If not found, checks request scope
▪ If not found, checks sessionScope and returns the same myVar used above
jonkv@ida
EL: Variables are not Java Variables

91
Variables may be composite (objects, arrays, maps)
 Access using "." or [] ▪ ".foo" for identifier syntax
▪ "[foo]" when an expression (foo) identifies the ”index”
 Example: param is a map from parameter names to values
▪ In form.html:
<FORM action="http://somesite.com/add.jsp" method="get">
<table class="mytable">
<tr><td>Name:<td><INPUT type="text" name="name">
<tr><td><INPUT type="submit" value="Send">
</table>
</FORM>
▪ Fill in "Bob Jones" and press Send
▪ In add.jsp: ${param.name} is "Bob Jones"
▪ In add.jsp: ${param["name"]} is also "Bob Jones"
▪ In add.jsp: ${param["na" + "me"]} is also "Bob Jones"
jonkv@ida
EL: Composite variables

JSTL variables have default values
 No null pointer exceptions (but less exact error checking)
▪ Java: If user.address is null, user.address.city  NPException
▪ JSTL/EL: If user.address is null or not defined,
user.address.city is null
 Integers default to 0
▪ <c:forEach items=”${products}” begin=”${param.start + 10}”>
...
</c:forEach>
▪ If param.start undefined (no "start=…" provided to the script), param.start is considered to be 0
 Provide your own defaults in <c:out>!
▪ <c:out value="${user.address.city}" default="N/A" />
92
jonkv@ida
EL: Default Values

93
Standard EL functions available in functions tag library
 JSP: <%@ taglib
uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
 JSPX: <html
xmlns:c="http://java.sun.com/jsp/jstl/core"
xmlns:fn="http://java.sun.com/jsp/jstl/functions" … >
▪
▪
▪
▪
▪
▪
▪
▪
length (of array, Collection, String, …)
toUpperCase, toLowerCase
substring, substringAfter, substringBefore
trim replace indexOf, startsWith, endsWith, contains, containsIgnoreCase
split, join escapeXml
jonkv@ida
EL: Standard Functions
94
 A JSP page, test.jsp, contains the following:
▪ ${param.a} &gt; ${param.b}: ${param.a > param.b}
${param.a} &gt; 13: ${param.a > 13}
 We call it: test.jsp?a=2&b=13
▪ 2 > 13: true
2 > 13: false
 Why?
 All query parameters are stored as strings!
▪ Converted to numbers when required
▪ The string “2” is greater than the string “13”
The string “2” is converted to the number 2 which is not greater than 13
jonkv@ida
EL: Variable Types…