JSP

<!--HTML Comment-->
<%--JSP Comment--%>

security - filters - making a custom tag

Tags

Embed JSP codes in HTML files in tags (there shouldn't be any space between tag punctuations):
  • <%     %>Direct Java code (executed in the jsp service method specified) - Scriptlet <%    %>
  • <%=   %>Display strings - Expressions:   <%=myObject.toString() %>
  • <%@  %> Directives
    • Include other content, access built-in variables
      •  <%@ include file="banner.jsp" %> 
        • include at translation time.
      • <jsp:include page="page.jsp" />
        • include at execution time (<%@  %> is faster)
          • <%@ include file="banner.jsp" %> ===>  out.println(content of banner.jsp copied here)
          • <jsp:include page="banner.jsp">  ===>  org.apache.jasper.runtime.JSPRuntimeLibrary.include(request, response, "banner.jsp", out, false);
<jsp:include page="page.jsp">
<jsp:param name="subtitle" value="Subtitle of the page based on parent assignment ."/>
</jsp:include>

refering to parameter in the included jsp page:
${param.subtitle}
        • Use include directive if the file changes rarely
          • It is faster than jsp:include
        • Use jsp:include for content that changes often
        • Use jsp:include if which page to include cannot be decided until the main page is requested
    • <%@ page %> page Directive
      • <%@ page import = "java.util.HashTable" content_type="text/plain(or other MIMEs)" extends = "CustomHttpServletSuperClass" implements = "Serializable, IFramework" method = "doPost" %>
      • <%@ page errorPage="errorpage.jsp" %>
      • <%@ page isErrorPage="true" %>         ${pageScope.exception}
      • .... and other attributes
  • <%!    %>Declarations - To define variables and methods <%!  private void method(){} %>
Override init or destroy methods
<%!
 private BookDBAO bookDBAO;
 public void jspInit() {
   ...
 }
 public void jspDestroy() {
   ...
 }
%>
  • Forward        <jsp:forward page="/main.jsp/"> <jsp:param name="param1" value="value1"/> </jsp:forward>
Content of the tags will be placed exactly as they are to a translated servlet, plain texts will be replaced by out.print(text) in the resulting servlet file. each of these is done line by line.

Implicit Objects:

request: HttpServletRequest
response: HttpServletResponse
out: PrintWriter
in: BufferedReader
4 Scope Variables
pageContext: page (just in one jsp page)  HAS ACCESS TO ALL SCOPES
getAttribute(String name);
getAttribute(String name, int scope);
getAttributeNamesInScope(int scope);
APPLICATION_SCOPE
SESSION_SCOPE
REQUEST_SCOPE
PAGE_SCOPE
findAttribute(String name); //starts from the most narrow scope to the widest one, The first match wins

request: HttpServletRequest (shared among forwarding pages for one request)
session: HttpSession (available as long as a valid session)
application: ServletContext (for the application server) === getServletContext().
config: ServletConfig
exception (only available to designated error pages)
...

<html>
<head>
</head>
<body>
<%
    out.println("Hello!");
    if (request.getParameter("name") != null) {
        out.println("I found you! " + request.getParameter("name"));
    } else {
        out.println("You?");
    }
%>
</body>
</html>

The first time a JSP file is called server it will generate an equivalent Servlet for the page, complie and load and then execute it, This would take a short while, subsequent calls to that JSP page will be as quick as a Servlet's.

JSP & Beans

 <%
 ShoppingCart cart = (ShoppingCart)session.getAttribute("cart");
 if (cart == null) {
     cart = new ShoppingCart();
     session.setAttribute("cart", cart);
 }
%>

 <jsp:useBean id="cart" class="cart.ShoppingCart" scope="session"/>

Create an instance of “ShoppingCart” if none exists, stores it as an attribute of the session scope object, and makes the bean available throughout the session by the identifier “cart”.

Create Bean

  • As table above - reads it, creates if not available - default scope is page
    • Type is reference type and class is object type itself
<jsp:useBean id="person" type="foo.Person" class="foo.Employee" scope="page"/> //object of type employee stored in object of type Person.  -- using type without class will work if the bean already in scope, and will not work if its not in scope

Set Bean Property

  • <% beanName.setPropName(value); %>
  • <jsp:setProperty name="beanName" property="propName" value="string constant"/>
  • from request parameters <jsp:setProperty name="beanName" property="propName" param="paramName"/>
  • <jsp:setProperty name="beanName" property="paramName"/>   === <% String bookId = request.getParameter("bookId");
      bookDB.setBookId(bookId); %>
  • <jsp:setProperty name="beanName" property="*"/>  ===  iterates through parameters and sets those attributes that match the bean fields.
  • Expression: <jsp:setProperty name="currency" property="amount" value="<%=cart.getTotal()%>"/>
  • Conditional //body will be executed when the bean is being created and is not available in the scope
<jsp:useBean id="person" class="foo.Person" scope="page">
<jsp:setProperty name="person" property="email" value="abc@d.com"/>
</jsp:useBean>

Get Bean Property

  • <%= beanName.getPropName() %>
  • <jsp:getProperty name="beanName" property="propName"/>

Why Java Beans

  • No need to learn Java programming language for page designers
  • Stronger separation between content and presentation
  • Higher reusability of code Simpler object sharing through built-in sharing mechanism
  • Convenient matching between request parameters and object properties

Why JSP

Content and display logic are separated
Supports software reuse through the use. of components (JavaBeans, Custom   tags)
Recompile automatically when changes are made to JSP pages
Model-View(JSP)-Controller(Servlet)
Automatic translate, recompile and use at run time, after change

Variable Scopes

page (just in one jsp page)
request(shared among forwarding pages for one request)
session (available as long as a valid session)
application (for the application server)

Error Page

<%@ page errorPage="errorpage.jsp" %>
<%@ page isErrorPage="true" %>
<%= exception.toString() %>

web.xml InitParameters

<web-app ...>
<servlet>
<servlet-name>myInit JSP</servlet-name>
<jsp-file>/TestInit.jsp</jsp-file>
<init-param>
<param-name>email</param-name>
<param-value>morteza@abcd.com</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>myInit JSP</servlet-name>
<url-patter>/TestInit.jsp</url-patter>
</servlet-mapping>
</web-app>

<%! jspInit(){
ServletConfig config = request.getServletConfig();
String emailAddr = config.getInitParameter("email");

ServletContext context = getServletContext();
context.setAttribute("mail", emailAddr);
} %>


All we learned so far was rubbish! We have to avoid using scriptlets, declaratives in a JSP file, for the sake of non-java aware web designers we have to learn another scripting language!

web.xml
<web-app>
<jsp-config>
<jsp-property-group>
<url-pattern>*.jsp</url-pattern>
<scripting-invalid>true</scripting-invalid>
</jsp-property-group>
</jsp-config>
</web-app>

EL: Expression Language

<html><body>
Dog's name is ${person.dog.name}
</body></html>
== is equal to
<%  ((foo.Person)request.getParameter(person)).getDog().getName()  %>

The first literal is either an EL implicit object or
  • Attribute
    • in Page Scope
    • in Request Scope
    • in Session Scope
    • in Application Scope
  • Implicit Object
    • pageScope
    • requestScope
    • sessionScope
    • applicationScope
    • --
    • param   // map of request parameters
    • paramValues   /used when the parameter has more than one value
    • --
    • header   // map of request headers
    • headerValues
    • --
    • cookie 
    • --
    • initParam   // map of context init parameters not servlet init parameters
    • --
    • pageContext: among all these implicit objects, only pageContext is not a map (key/value pair). It is an actual reference to the pageContext object. (and the pageContext is a java bean). all of the above are different than their jsp equivalents except just pageContext
Use dot (.) to access properties and map values.
The left-hand-side of a dot must be a bean or a map (an attribute)
The right-hand-side of a dot must be a property name or a key in the map

Use [] to access properties and map values.
The left-hand-side of a dot can be a bean, a map (an attribute), a List, or an array
The right-hand-side of a dot must be a property name or a key in the map or an index
${musicList["something"]} something can be property name or a key in the map or an int (an index)
${musicList[something]} since something is not an string literal it will be tried to be evaluated as an attribute.
if the property name or key can not be evaluated it will return the same text
Can be nested
${musicMap[musicType[0]]}

<input type="text" name="food">
<input type="text" name="food">


// ${paramValues.food[0]}     ${paramValues.food[1]}     ????    ${paramValues["food"]["1"]}   ????

${header.host} == ${header["host"]}
Use requestScope for request attributes not its properties
${pageContext.request.method}   you can't use ${requestScope.method}

If the request scope was not a legal java variable name, we can use implicit scope variables to access them
e.g. if we set the name of an attribute as "foo.bar" we can't obtain its value with ${foo.bar}, it will be thought of as another mapping. we should use ${requestScope["foo.bar"]}

${cookie.username.value}   == will give the value of the username cookie

${initParam.adminEmail}

EL expression can be in jsp tags in value assignments to tag attributes <jsp:setProperty name="person" property="email" value="${list[0]}"/>

EL Function Call - public static

Using *.TLD files (Tag Library Descriptor) placed in the WEB-INF
<?xml version="1.0"?>

<taglib xmlns= ...  >
<taglib-version>1.2</taglib-version>
<uri>WEB-INF/myFunctionURI</uri>
<function>
<name>functionPreferredName</name> <!-- doesn't have function at the tag name-->
<function-class>foo.bar.MyClass<function-class>
<function-signature>
int getElement(java.util.Map)
</function-signature>
</function>
</taglib>

Actual class
package foo.bar;
import java.util.Map;
public class MyClass{
public static int getElement(Map map){
...
}
}

Refering JSP file
<%@ taglib   prefix="myPrefix"  uri="WEB-INF/myFunctionURI"%>
<html><body>
${myPrefix:functionPreferredName}
</body></html>

EL Operators

+ - * (/  div [devision by zero is not an exception and returns infinity])  (% mod [number mod zero is exception]) (&& and) (||  or) (! not) (== eq) (!= ne) (< le) (> gt) (<= le) (>= ge) true false null[in arithmetics is zero, in logic is false, and empty string as string] empty[something is null or empty e.g. ${empty A} returns true if A is empty or null]


Some JSP Tags

<jsp:forward page="a.jsp"/>
If at any portion of a JSP page, forward occurs, all the things written to the output will be cleared from the output buffer before forwarding occures. Can include <jsp:param>

JSTL (JSP Standard Tag Library)

We will need jstl.jar and standard.jar which can be found at $CATALINA_HOME/webapps/examples/WEB-INF/lib  Put the jar files in the WEB-INF/lib directory of your project.

  • To convert HTML special characters to their etity form, so that they are viewable than processable. Escaping is on be default. To avoid escaping special characters turn it off or print it raw (without c:out).
< &lt;     > &gt;    & &amp;    ' &#039;   " &#034;
<body>  <c:out value="${pageContent.myText}" escapeXML="true" default="default if null"/>  </body>
To default, also: <c:out value="value">default value</c:out>

  • Iterate: varStatus will be an instance of javax.servlet.jsp.jstl.core.LoopTagStatus which has a count field.
It can have optional attributes, begin, end, and step
<table>
<c:forEach var="movie" items="$movieList" varStatus="index">
<tr>
index is ${index.count} and element  is ${movie}
</tr>
</c:forEach>
</table>

nested loop works by just passing the temporary variable ofthe bigger loop as the items of the smaller one

  • if
<c:if test="${useType eq 'member'}">

</c:if>
  • if/else (choose)
<c:choose>
<c:when test="${userPreference eq 'speed'}">

</c:when>
<c:when test="${userPreference eq 'quality'}">

</c:when>
<c:otherwise>

</c:otherwise>
</c:choose>

  • set - if the variable is not found it will be created
    • set a variable - if the value is null hte variable will be removed
<c:set var="varName" scope="session" value="${person.dog}"/>
OR put the value in the tag
<c:set variable="varName">
${person.dog}
</c:set>
set a bean property or key in a map - target must evaluate to the object itself; it shouldn't be the object's id string literal or etc. It should either be an EL ${} or script expression <%= %>
      • if scope is not set just the page scope will be searched not all
<c:set target="$petMap" property="MapKeyOrPropertyName" value="value"/>

  • remove
<c:remove var="VarName" scope="request">
  • include - url of a resource out of the container is possible - it should be an html fragment (e.g. an image) not a complete page (shouldn't have body, html, ...)
<c:import url="http://www.pix.com/pic1.html">
<c:param name=paramName" value="value of parameter"/>
</c:import>
  • url rewriting - to keep session tracking - var will store the url as a variable for future use
<a href="<c:url value='/checkout.jsp'/>" var="varName"> Click to Check out </a>

<c:url value="/checkout.jsp">  <!-- To ensure proper URL encoding -->
<c:param name="paramName1" value="${first}"/>
<c:param name="paramName2" value="ex2"/>
</c:url>
  • catch exception
<c:catch var="caughtException">
<%= 0/0 %>
</c:catch>
${caughtException.message}
















Comments