comp 321 week 10. overview using beans in jsp expression language jstl lab 10-1 introduction exam...
TRANSCRIPT
COMP 321
Week 10
Overview
Using Beans in JSP
Expression Language
JSTL
Lab 10-1 Introduction
Exam Review
Accessing Attributesprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String name = request.getParameter("userName"); request.setAttribute("name", name);
RequestDispatcher view = request.getRequestDispatcher("/result.jsp"); view.forward(request, response);}
<html><body>Hello<%= request.getAttribute("name") %></body></html>
Accessing Attributes// What if the attribute is an object?foo.Person p = new foo.Person();p.setName("Evan");request.setAttribute("person", p);
RequestDispatcher view = request.getRequestDispatcher("/result.jsp");view.forward(request, response);
<body><% foo.Person p = (foo.Person) request.getAttribute("person"); %>Person is: <%= p.getName() %>
Person is:<%= ((foo.Person) request.getAttribute("person")).getName() %></body>
Accessing Attributes// What if the attribute is an object?foo.Person p = new foo.Person();p.setName("Evan");request.setAttribute("person", p);
RequestDispatcher view = request.getRequestDispatcher("/result.jsp");view.forward(request, response);
<body><% foo.Person p = (foo.Person) request.getAttribute("person"); %>Person is: <%= p.getName() %>
Person is:<%= ((foo.Person) request.getAttribute("person")).getName() %></body>
Accessing Attributes<!-- Using scripting--><body><% foo.Person p = (foo.Person) request.getAttribute("person"); %>Person is: <%= p.getName() %></body>
<!-- Using standard actions --><body><jsp:useBean id="person" class="foo.Person" scope="request" />Person is: <jsp:getProperty name="person" property="name" /></body>
<!-- jsp:useBean will create a new bean if it's not found --><!-- Use jsp:setProperty to initialize this default bean --><jsp:useBean id="person" class="foo.Person" scope="page"> <jsp:setProperty name="person" property="name" value="Fred" /></jsp:useBean>
Accessing Attributes// What if we want to use polymorphism?public abstract class Person { public void setName(String name) { ... } public String getName() { ... }}
public class Employee extends Person { public void setEmpID(int id) { ... } public int getEmpID() { ... }}
<!-- This won't work. Why not? --><jsp:useBean id="person" class="foo.Person" scope="page"> <jsp:setProperty name="person" property="name" value="Fred" /></jsp:useBean>
Accessing Attributes// What if we want to use polymorphism?public abstract class Person { ... }public class Employee extends Person { ... }
<jsp:useBean id="person" type="foo.Person" class="foo.Employee" scope="page">
<jsp:setProperty name="person" property="name" value="Fred" /></jsp:useBean>
// Generated codefoo.Person person = null;// Code to get person attributeif (person == null) { person = new foo.Employee(); ...}
<!– We can use type without class, as long as the bean already exists --><jsp:useBean id="person" type="foo.Person" scope="page" />
HTML -> JSP<!-- The form can send the request directly to the JSP --><form action="TestBean.jsp"> name: <input type="text" name="userName"> ID#: <input type="text" name="userID"> <input type="submit"></form>
<!-- We can get to the parameter using scripting... --><jsp:useBean id="person" type="foo.Person" class="foo.Employee" /><% person.setName(request.getParameter("userName")); %>
<!-- ...or we can use param --><jsp:useBean id="person" type="foo.Person" class="foo.Employee" /> <jsp:setProperty name="person" property="name" param="userName" /></jsp:useBean>
HTML -> JSP<!-- We can do better if the form field name matches the bean attribute --><form action="TestBean.jsp"> name: <input type="text" name="name"> ID#: <input type="text" name="empID"> <input type="submit"></form>
<!-- Now we don't specify any value --><jsp:useBean id="person" type="foo.Person" class="foo.Employee" /> <jsp:setProperty name="person" property="name" /></jsp:useBean>
<!-- If all of the fields match, we can set them all at once, and type --><!-- conversions happen automatically. Notice that type is now Employee,
--><!-- so that EmpID can be found. --><jsp:useBean id="person" type="foo.Employee" class="foo.Employee" /> <jsp:setProperty name="person" property="*" /></jsp:useBean>
EL Expressions
Follow the format ${First.Second} or ${First[Second]}
First is either an implicit object or an attribute
Second is a key, member, index, or expression
EL Expressions - Implicit Objects
Maps pageScope, requestScope, sessionScope,
applicationScope param, paramValues header, headerValues cookie initParam
pageContext – the page context object
EL Expressions<!-- The dot operator is used to access properties or map values --><!-- Get the name property from the person attribute in some scope -->${person.name}
<!-- The [] operator is used to access properties, map values, or --><!-- List/array elements -->${person["name"]}
String [] myMusic = { "Zero 7", "Tahiti 80", "BT" };request.setAttribute("musicList", myMusic);
<!-- prints "Zero 7" -->${musicList[0]}
<!-- "1" is coerced to an int, so this prints "Tahiti 80" -->${musicList["1"]}
EL Expressions<!-- For beans and maps, either operator works -->Map musicMap = new HashMap();musicMap.put("Ambient", "Zero 7");request.setAttribute("musicMap", musicMap);
<!-- Both of these evaluate to "Zero 7" -->${musicMap.Ambient}${musicMap["Ambient"]}
<!-- If the argument isn't a string literal, it's evaluated --><!-- This doesn't work -->${musicMap[Ambient]}
request.setAttribute("Genre", "Ambient"); <!-- Now this evaluates to ${musicList["Ambient"]}, which --><!-- evaluates to "Zero 7" -->${musicList[Genre]}
EL Expressions<!-- Accessing request parameters -->${param.userName}
<!-- Accessing multi-valued request parameters -->${paramValues.food[0]}${paramValues.food[1]}
<!-- Accessing request headers -->${header.host}
<!-- Accessing request object properties -->${pageContext.request.method}
EL Expressions<!-- Specifying scope -->${requestScope.person.name}
<!-- Accessing attribute without legal Java name -->${requestScope["foo.person"].name}
<!-- Accessing cookies -->${cookie.userName.value}
<!-- Accessing context init parameters -->${initParam.mainEmail}
EL Functions
Can be used to call static methods in Java classes:1. Write a Java class with a static method
2. Create a Tag Library Descriptor (TLD) file
3. Add a taglib directive to your JSP
4. Use EL to call the function
EL Functionsclass DiceRoller { public static int rollDice() { return (int)((Math.random() * 6) + 1); }}
<!-- In TLD file--><uri>DiceFunctions</uri><function> <name>rollIt</name> <function-class>foo.DiceRoller</function-class> <function-signature>int rollDice()</function-signature></function>
<!-- In JSP --><%@ taglib prefix="mine" uri="DiceFunctions" %><html><body>${mine:rollit()}
JSP Include Directive<!-- Header.jsp --><img src="images/Web-Services.jpg"/><br><em><string>We know how to make SOAP suck less.</strong></em><br>
<!-- Contact.jsp --><html><body><%@ include file="Header.jsp" %><br><em>We can help.</em><br><br>Contact us at: ${initParam.mainEmail}</body></html>
Equivalent to pasting the header into Contact.jsp Position-dependent Takes place once at translation time
JSP Include Action<!-- Header.jsp --><img src="images/Web-Services.jpg"/><br><em><string>${param.subTitle}</strong></em><br>
<!-- Contact.jsp --><html><body><jsp:include page="Header.jsp" <jsp:param name="subTitle" value="We know how to make SOAP suck less." /></jsp:include><em>We can help.</em><br><br>Contact us at: ${initParam.mainEmail}</body></html>
Request and response are forwarded to included JSP Takes place at execution time Happens once per request jsp:param can be used to pass parameters
Code Magnetspublic class Toy { private String name; // Getters/setters}
public class Person { private Dog dog; private String name; // Getters/setters}
public class Dog { private String name; private Toy[] toys; // Getters/setters}
Code MagnetsPerson p = new Person("Leelu");Dog d = new Dog("Clyde");Toy t1 = new Toy("stick");Toy t2 = new Toy("neighbor's cat");Toy t3 = new Toy("Barbie doll head");d.setToys(new Toy[]{t1, t2, t3});p.setDog(d);request.setAttribute("person", p);
Desired output:Leelu's dog Clyde's toys are: stick, neighbor's cat, and a Barbie doll head
Code MagnetsPerson p = new Person("Leelu");Dog d = new Dog("Clyde");Toy t1 = new Toy("stick");Toy t2 = new Toy("neighbor's cat");Toy t3 = new Toy("Barbie doll head");d.setToys(new Toy[]{t1, t2, t3});p.setDog(d);request.setAttribute("person", p);
Desired output:Leelu's dog Clyde's toys are: stick, neighbor's cat, and a Barbie doll head
EL:${person.name}'s dog ${person.dog.name}'s toys are: $
{person.dog.toys[0].name},${person.dog.toys[1].name}, and a ${person.dog.toys[2].name}
Sharpen Your Pencilrequest.setAttribute("num", "2");request.setAttribute("integer", new Integer(3));ArrayList list = new ArrayList();list.add("true"); list.add("false");list.add("2"); list.add("10");request.setAttribute("list", list);
What prints for each of these?${num > 3}${integer le 12}${requestScope["integer"] ne 4 and 6 le num || false}${list[0] || list["1"] and true}${num > integer}${num == integer - 1}${42 div 0}
Sharpen Your Pencilrequest.setAttribute("num", "2");request.setAttribute("integer", new Integer(3));ArrayList list = new ArrayList();list.add("true"); list.add("false");list.add("2"); list.add("10");request.setAttribute("list", list);
What prints for each of these?${num > 3} false${integer le 12} true${requestScope["integer"] ne 4 and 6 le num || false} false${list[0] || list["1"] and true} true${num > integer} false${num == integer - 1} true${42 div 0} Infinity
JSTL<div class="tipBox"> <b>Tip of the day:</b><br/><br/> ${pageContent.currentTip}</div>
<!-- If currentTip="<b></b> tags make things bold", we have a problem --><div class="tipBox"> <b>Tip of the day:</b><br/><br/> <b></b> tags make things bold</div>
<!-- We actually wanted this... --><div class="tipBox"> <b>Tip of the day:</b><br/><br/> <b></b> tags make things bold</div>
JSTL<!-- We can use c:out to escape the XML special characters --><div class="tipBox"> <b>Tip of the day:</b><br/><br/> <c:out value="${pageContent.currentTip}" /></div>
<!-- The c:out prints what we wanted originally --><b></b> tags make things bold
<!-- We can also use c:out to provide default values -->Hello, <c:out value="${user}" default="guest"/>Hello, <c:out value="${user}">guest</c:out>
JSTL Looping<!-- Using scripting --><table><% String [] items = (String[])request.getAttribute("movieList"); String var = null; for (int i = 0; i < items.length; i++) { var = items[i];%> <tr><td><%= var %></td></tr><% } %></table>
<!-- Using JSTL --><table> <c:forEach var="movie" items="${movieList}" > <tr><td>${movie}</td></tr> </c:forEach></table>
JSTL Conditionals<c:if test="${userType eq 'member' }" > <jsp:include page="inputComments.jsp"/></c:if>
<c:choose> <c:when test="${userPref == 'performance' }"> Now you can stop even if you drive insanely fast. </c:when> <c:when test="${userPref == 'safety' }"> Our brakes won't lock up, no matter how badly you drive. </c:when> <c:otherwise> Our brakes are the best. </c:otherwise></c:choose>
JSTL<!-- c:set var sets attribute variables --><c:set var="userLevel" scope="session" value="Cowboy"/><c:set var="Fido" value="${person.dog }"/><c:set var="userLevel" scope="session">Sheriff, Bartender, Cowgirl</c:set>
<!-- c:set target sets bean properties, or Map values --><!-- The target expression must evaluate to the actual object --><c:set target="${PetMap}" property="dogName" value="Clover"/>
<c:set target="${person}" property="name"> ${foo.name}</c:set>
<!-- c:set will remove attributes if the value is null, but it's better--><!-- to use c:remove --><c:remove var="userStatus" scope="request"/>
JSTL<!-- c:import - another way to include content from another source --><!-- c:import can include resources that live outside the web app --><c:import url="http://wickedlysmart.com/skyler/horse.html" />
<!-- c:import can pass values to the included resource --><c:import url="Header.jsp"> <c:param name="subTitle" value="We take the sting out of SOAP." /></c:import>
<!-- The included file --><em><strong>${param.subTitle}</strong></em>
JSTL<!-- c:url - handles URL rewriting from a JSP --><a href="<c:url value='/inputComments.jsp' />">Click here</a>
<!-- We can use var to remember the URL for later--><c:set var="last" value="Hidden Cursor" /><c:set var="first" value="Crouching Pixels" />
<c:url value="/inputComments.jsp?first=${first}&last=${last}" var="inputURL" />
The URL using params is: ${inputURL} <br>
JSTL<!-- c:url - handles URL rewriting from a JSP --><a href="<c:url value='/inputComments.jsp' />">Click here</a>
<!-- We can use var to remember the URL for later--><c:set var="last" value="Hidden Cursor" /><c:set var="first" value="Crouching Pixels" />
<c:url value="/inputComments.jsp?first=${first}&last=${last}" var="inputURL" />
The URL using params is: ${inputURL} <br>
What's wrong with the URL above?
JSTL<!-- c:url - handles URL rewriting from a JSP --><a href="<c:url value='/inputComments.jsp' />">Click here</a>
<!-- We can use var to remember the URL for later--><c:set var="last" value="Hidden Cursor" /><c:set var="first" value="Crouching Pixels" />
<c:url value="/inputComments.jsp?first=${first}&last=${last}" var="inputURL" />
The URL using params is: ${inputURL} <br>
What's wrong with the URL above? We should be encoding the parameters!
JSTL<!-- c:url - handles URL rewriting from a JSP --><a href="<c:url value='/inputComments.jsp' />">Click here</a>
<!-- We can use var to remember the URL for later--><c:set var="last" value="Hidden Cursor" /><c:set var="first" value="Crouching Pixels" />
<c:url value="/inputComments.jsp" var="inputURL" /> <c:param name="firstName" value="${first}" /> <c:param name="lastName" value="${last}" /></c:url />The URL using params is: ${inputURL} <br>
Error Pages<!-- The error page - displayed when an exception occurs --><%@ page isErrorPage="true" %><html><body><strong>Bummer.</strong><br>You caused a ${pageContext.exception} on the server.<br><img src="images/bummerGuy.jpg"/></body></html>
<!-- The page that has an error --><%@ page errorPage="errorPage.jsp" %><html><body>About to be bad...<% int x = 10/0; %></body></html>
Error Pages and the DD<!-- Declaring a catch-all error page --><error-page> <exception-type>java.lang.Throwable</exception-type> <location>/errorPage.jsp</location></error-page>
<!-- Declaring an exception-specific error page --><error-page> <exception-type>java.lang.ArithmeticException</exception-type> <location>/arithmeticError.jsp</location></error-page>
<!-- Declaring an error page based on an HTTP status code --><error-page> <error-code>404</error-code> <location>/notFoundError.jsp</location></error-page>
Handling Exceptions in a JSP<!-- c:catch can be used to catch an exception within the page --><html><body>
About to do a risky thing... <br>
<c:catch> <% int x = 10 / 0; %></c:catch>
If you see this, we survived.
</body></html>
Handling Exceptions in a JSP<!-- The var attribute can be used to get the exception object --><html><body>
About to do a risky thing... <br>
<c:catch var="myException"> <% int x = 10 / 0; %></c:catch>
<c:if test="${myException != null}"> There was an exception: ${myException.message} <br></c:if>
If you see this, we survived.
</body></html>
Deciphering the TLD<?xml version="1.0" encoding="ISO-8859-1" ?> <taglib xmlns=…><tlibversion>1.2</tlibversion><shortname>RandomTags</shortname> <!-- Used by tools-->
<uri>randomThings</uri> <!-- used in the taglib directive --><tag> <description>random advice</description> <name>advice</name> <!-- used in the JSP - <my:advice> --> <tag-class>foo.AdvisorTagHandler</tag-class> <body-content>empty</body-content> <attribute> <name>user</name> <required>true</required> <rtexprvalue>true</rtexprvalue> <!-- Can be a runtime expression --> </attribute></tag>
Using a Custom Tag<%@ taglib prefix="mine" uri="randomThings" %>Advisor Page<br><mine:advice user="${userName}" />
public class AdvisorTagHandler extends SimpleTagSupport { private String user; public void setUser(String user) { this.user = user; }
public void doTag() throws JspException, IOException { getJspContext().getOut().write("Hello " + user + " <br>"); getJspContext().getOut().write("Your advice is: " + getAdvice()); }
private String getAdvice() { // Code to give advice here }}
Finding the TLD
Since JSP 2.0, the container finds TLDs for you in: WEB-INF and its subdirectories Inside JAR files in the lib directory - in the META-INF
directory and its subdirectories<!-- The old (pre-JSP 2.0) way is to use the DD --><web-app>... <jsp-config> <taglib> <taglib-uri>randomThings</taglib-uri> <taglib-location>/WEB-INF/myFunctions.tld</taglib-
location> </taglib> </jsp-config></web-app>
Lab 10-1 Introduction
Exam Review
Learning Activity – Music Search
Implement MusicSearch servlet using model class
Implement SearchResults.jsp using scripting
Implement SearchResults2.jsp without scripting
Progress Check
Due this week: Lab 8-1 Servlets
Due next week: Exam 2