Using JSPs

The container looks at your JSP, translates it into Java source code, and compiles it into a fully-fledged Java servlet class, this servlet is alot like any other servlet, except that the servlet class is written for you by the container.

With JSP you can put regular Java code in a JSP using a scriptlet which means Java code within a <% ... %> tag. The one thing to note is that if your Java code needs to use any other class that it is in the classpath just like a normal Java program. You have two options to use other classes within your JSP

JSP Expressions, Variables and Declarations

A directive is away for you to give special instructions to the Container at page translation time, they come in three flavors

page directive example <%@ page import="foo.*" >
<%@ page import="foo.*,java.util.*" %>
<%@ page import="foo.*" session="false" %>

Note: the <%@ sign means that its a directive
include <%@ include file="datadiskHeader.html" %>
taglib <%@ taglib tagdir="/WEB-INF/tags/cool" prefix="cool" %>
13 Page Directive attributes
import Defines the Java import statements that'll be added to the generated servlet class
isThreadSafe Defines whether the generated servlet needs to implement the Single ThreadModel which as you know know is a bad thing
contentType Defines the MIME type for the JSP response (default is "text/html")
isELIgnored Defines whether EL expressions are ignored when this page is translated
isErrorPage Defines whether the current page represents another JSPs error page
errorPage Defines a URL to the resource to which uncaught Throwables should be sent
language Defines the scripting language used in the scriptlets, expressions and declarations, only java is available at the moment
extends Defines the superclass of the class this JSP will become
session Defines whether the page will have an implicit session object
buffer Defines how buffering is handled by the implicit out object (reference to the jspWriter)
autoFlush Defines whether the buffered output is flushed automatically
info Defines a String that gets put into the translated page, just so that you can get it using the generated servlets inherited getServletInfo() method
pageEncoding Defines the character encoding for the JSP

One of the points in using JSP is that you don't need to use the println() statement, the expression element automatically prints out whatever you put between the tags

expression element

<% out.println(Counter.getCount()); %>

<%= Counter.getCount() %>

The two above statements are the same, but did you notice the equals sign in the second statement, this is what turns the code into a expression statement, also the Container automatically adds the out.println( ... ); to your statement so there is no need to put a semi-colon on the end of your statement, so never end an expression with a semi-colon.

Scriptlet <%  %>
Directive <%@  %>
Expression <%=  %>
Instance Declaration <%! %>

Note: talk about this next

JSP-Generated Servlet

So what happens when to create a simple JSP, here is an example

JSP
JSP Becomes a Servlet
<html><body>
  <% int count=0; %>
  The page count is now:
  <%= ++count %>
</body></html>
public class basicCounter_jsp extends SomeSpecialHttpServlet {

  public void _jspService(HttpServletRequest request, HttpServletResponse response )
                                     throws java.io.IOException, ServletException {

    PrintWriter out = response.getWriter();
    response.setContentType("text/html");
    out.write("<html><body>");
    int count=0;
    out.write("The page count is now:");
    out.print( ++count );
    out.write("</body></html>");
  }
}

The problem with the above example is the count will be a local variable, which means that it will get reset every time the servlet is run. JSP declarations are for declaring members of the generated servlet class. That means both variables and methods which means you can declare static variables and methods.

JSP
JSP Becomes a Servlet
<html><body>
  <%! int count=0; %>
  The page count is now:
  <= ++count %>
</body></html>

Note: the ! (bang) character

public class basicCounter_jsp extends SomeSpecialHttpServlet {

  int count=0;

  public void _jspService(HttpServletRequest request, HttpServletResponse response )
                                     throws java.io.IOException, ServletException {

    PrintWriter out = response.getWriter();
    response.setContentType("text/html");
    out.write("<html><body>");
    out.write("The page count is now:");
    out.print( ++count );
    out.write("</body></html>");
  }
}

Note: count is now an instance variable

What if you use the same name as a local and a instance variable

use local and instance variables

<html><body>
  Test local and instance variable
  <%! int x=100; %>
  <% int x=1000; %>
  Local x is:
  <%= x %>
  Instance x is:
  <%= this.x %>
</body></html>

Note: this is pretty much the same as Java

You can write an JSP knowing that your code is going to be part of a servlet, this means you can take advantage of your servletness, even though you're not directly writing the servlet class yourself., there are a few reasons your JSP might need to use some of what's available to a servlet. All of the implicit objects map to something from the Servlet/JSP API.

API
Implicit Object
JspWriter
out
HttpServletRequest
request
HttpServletResponse
response
HttpSession
session
ServletContext
application
ServletConfig
config
Throwable
exception
PageContext
pageContext
Object
page

JSP Comments

With any programming you should write comments throughout your code, this helps in maintaining it

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

API for the Generated Servlet

The container generates a class from your JSP that implements the HttpJspPage interface, there are three key methods that you need to know about

jspInit() This method is called from the init() method and it can be overridden

see a override example of this below
jspDestroy() This method is called from the servlets destroy() method and it too can be overridden
_jspService() This method is called from the servlets service() method which means its runs in a separate thread for each request, the container passes the request and response object to this method. You cannot override this method.

When you deploy a web application with a JSP, the whole translation and compilation of the JSP happens only once in the JSP's life, the first time it is called. Although this is a big hit for the first user who accesses the JSP, some vendors Containers can perform this translation and compilation in advanced, thus it is ready for the first user

Initializing your JSP

You can do servlet initialization in your JSP, but its slightly different from what you do in a regular servlet.

initialize servlet via JSP # add to the applications web.xml file

<web-app ...>
  <servlet>
    <servlet-name>myTestJSPInit</servlet-name>
    <jsp-file>/TestInit.jsp</jsp-file>

    <init-param>
      <param-name>email</param-name>
      <param-value>sales@datadisk.co.uk</param-value>
    </init-param>
  </servlet>

  <servlet-mapping>
    <servlet-name>myTestJSPInit</servlet-name>
    <url-pattern>/TestInit.jsp</url-pattern>

  </servlet-mapping>

</web-app>
using the parameter and overriding jspInit()

# create the file TestInit.jsp

<html>
<head></head>
<body>

<h1>Testing getting a parameter from web.xml</h1>
<br>

<!-- Below are a number of ways to get the web.xml init parameter -->

<%-- override the jspInit() method %>
<%!
  public void jspInit() {
  
    ServletConfig sConfig = getServletConfig();
    String emailAddr = sConfig.getInitParameter("email");
    ServletContext ctx = getServletContext();
    ctx.setAttribute("mail", emailAddr);
  }
%>

<%-- you can use either of the below, both are explained below %>
<%= "Mail Attribute is: " + application.getAttribute("mail") %>
<br>
<%= "Mail Attribute is: " + pageContext.findAttribute("mail") %>

<%
   ServletConfig sConfig = getServletConfig();
   String emailAddr = sConfig.getInitParameter("email");
   out.println("<br><br>Another way to get web.xml attributes: " + emailAddr );
%>

<%
   out.println("<br><br>Yet another way to get web.xml attributes: " + getServletConfig().getInitParameter("email") );
%>

</body>
</html>

Note: remember that if you change the web.xml it will automatically be picked up

There are four implicit objects to get and set attributes corresponding to the four attribute scopes available

 
In a Servlet
In a JSP
Application getServletContext().setAttribute("foo",barObj); application.setAttribute("foo",barObj);
Request request.setAttribute("foo",barObj); request.setAttribute("foo",barObj);
Session request.getSession().setAttribute("foo",barObj); session.setAttribute("foo",barObj);
Page does not apply pageContext.setAttribute("foo",barObj);

You can use a PageContext reference to get attributes from any scope, including the page scope for attributes bound to the PageContext

Setting a paged-scoped attribute <% Float one = new Float(42.5); %>
<% pageContext.setAttribute("foo", one); %>
Getting a page-scoped attribute <%= pageContext.getAttribute("foo") %>
Using the pageContext to set a session-scoped attribute <% Float two = new Float(42.5); %>
<% pageContext.setAttribute("foo", two, PageContext.SESSION_SCOPE); %>
Using the pageContext to get a session-scoped attribute <%= pageContext.getAttribute("foo", PageContext.SESSION_SCOPE ) %>
Using the pageContext to get an application-scoped attribute <%= pageContext.getAttribute("mail", PageContext.APPLICATION_SCOPE) %>
Using the pageContext to find an attribute when you don't know the scope

<%= pageContext.findAttribute("mail") %>

Note: find looks from the most restricted to the least restrictive page then request then session and finally application scope. The first one it finds with that name wins.

Expression Language Introduction

Putting Java code into an JSP is very bad and you should'nt do it, the reason for the above tutorial is that years ago this was the only way to get Java code within your web pages and there are still lots of web pages out there with Java code imbedded that needs to be maintained (hence the tutorial above).

So how do we use Java code with out exposing the code itself within the JSP, the answer is EL (Expression Language), it is now part of the JSP 2.0 spec. EL offers a simpler way to invoke Java code but he code itself belongs somewhere else. That means in a regular old Java class that's either a JavaBean, a class with static methods or something called a Tag Handler.

EL example # Java Expression (old way don't do now)
Please contact: <%= application.getAttribute("mail") %>

# EL way
please contact: ${applicationScope.mail}

You can stop all JSP pages from using any scripting elements by using a <scripting-invalid> DD tag, you can even disable EL if you want to

stop JSP from using scripting elements <web-app ...>
...
  <jsp-config>
    <jsp-property-group>
    <url-pattern>*.jsp</url-pattern>
    <scripting-invalid>true</scripting-invalid>
    <el-ignored>true</el-ignored>
    </jsp-property-group>
  </jsp-config>
...
</web-app>
stop using EL <%@ page isELIgnored="true" %>

Note: this takes priority over the DD tag above

I have a complete topic on Expression Language so pop over and pickup from here.

Actions

There is another type of element you can use in a JSP called actions which I discuss in another topic, but here is an example

standard action <jsp:include page="datadiskFooter.jsp" />
not a standard action <c:set var="rate" value="32" /?

Quick Recap

I have covered six JSP element types, examples are below

Element Type Example
directive <%@ page import="java.util.*" %>
declaration <%! int y = 3; %>
EL Expression email: ${applicationScope.mail}
scriptlet <% Float one = new Float(42.5); %>
expression <%= pageContext.getAttribute(foo") %>
action <jsp:include page="foo.html" />